]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/AST/DeclTemplate.cpp
Vendor import of stripped clang trunk r375505, the last commit before
[FreeBSD/FreeBSD.git] / lib / AST / DeclTemplate.cpp
1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the C++ related Decl classes for templates.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/AST/DeclTemplate.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/ASTMutationListener.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclarationName.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/ExternalASTSource.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/AST/TemplateName.h"
22 #include "clang/AST/Type.h"
23 #include "clang/AST/TypeLoc.h"
24 #include "clang/Basic/Builtins.h"
25 #include "clang/Basic/LLVM.h"
26 #include "clang/Basic/SourceLocation.h"
27 #include "llvm/ADT/ArrayRef.h"
28 #include "llvm/ADT/FoldingSet.h"
29 #include "llvm/ADT/None.h"
30 #include "llvm/ADT/PointerUnion.h"
31 #include "llvm/ADT/SmallVector.h"
32 #include "llvm/Support/Casting.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstdint>
37 #include <memory>
38 #include <utility>
39
40 using namespace clang;
41
42 //===----------------------------------------------------------------------===//
43 // TemplateParameterList Implementation
44 //===----------------------------------------------------------------------===//
45
46 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
47                                              SourceLocation LAngleLoc,
48                                              ArrayRef<NamedDecl *> Params,
49                                              SourceLocation RAngleLoc,
50                                              Expr *RequiresClause)
51     : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
52       NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
53       HasRequiresClause(static_cast<bool>(RequiresClause)) {
54   for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
55     NamedDecl *P = Params[Idx];
56     begin()[Idx] = P;
57
58     if (!P->isTemplateParameterPack()) {
59       if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
60         if (NTTP->getType()->containsUnexpandedParameterPack())
61           ContainsUnexpandedParameterPack = true;
62
63       if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
64         if (TTP->getTemplateParameters()->containsUnexpandedParameterPack())
65           ContainsUnexpandedParameterPack = true;
66
67       // FIXME: If a default argument contains an unexpanded parameter pack, the
68       // template parameter list does too.
69     }
70   }
71   if (RequiresClause) {
72     *getTrailingObjects<Expr *>() = RequiresClause;
73     if (RequiresClause->containsUnexpandedParameterPack())
74       ContainsUnexpandedParameterPack = true;
75   }
76 }
77
78 TemplateParameterList *
79 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
80                               SourceLocation LAngleLoc,
81                               ArrayRef<NamedDecl *> Params,
82                               SourceLocation RAngleLoc, Expr *RequiresClause) {
83   void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>(
84                              Params.size(), RequiresClause ? 1u : 0u),
85                          alignof(TemplateParameterList));
86   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
87                                          RAngleLoc, RequiresClause);
88 }
89
90 unsigned TemplateParameterList::getMinRequiredArguments() const {
91   unsigned NumRequiredArgs = 0;
92   for (const NamedDecl *P : asArray()) {
93     if (P->isTemplateParameterPack()) {
94       if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P))
95         if (NTTP->isExpandedParameterPack()) {
96           NumRequiredArgs += NTTP->getNumExpansionTypes();
97           continue;
98         }
99
100       break;
101     }
102
103     if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) {
104       if (TTP->hasDefaultArgument())
105         break;
106     } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
107       if (NTTP->hasDefaultArgument())
108         break;
109     } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument())
110       break;
111
112     ++NumRequiredArgs;
113   }
114
115   return NumRequiredArgs;
116 }
117
118 unsigned TemplateParameterList::getDepth() const {
119   if (size() == 0)
120     return 0;
121
122   const NamedDecl *FirstParm = getParam(0);
123   if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm))
124     return TTP->getDepth();
125   else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
126     return NTTP->getDepth();
127   else
128     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
129 }
130
131 static void AdoptTemplateParameterList(TemplateParameterList *Params,
132                                        DeclContext *Owner) {
133   for (NamedDecl *P : *Params) {
134     P->setDeclContext(Owner);
135
136     if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P))
137       AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
138   }
139 }
140
141 void TemplateParameterList::
142 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
143   // TODO: Concepts: Collect immediately-introduced constraints.
144   if (HasRequiresClause)
145     AC.push_back(getRequiresClause());
146 }
147
148 bool TemplateParameterList::hasAssociatedConstraints() const {
149   // TODO: Concepts: Regard immediately-introduced constraints.
150   return HasRequiresClause;
151 }
152
153 namespace clang {
154
155 void *allocateDefaultArgStorageChain(const ASTContext &C) {
156   return new (C) char[sizeof(void*) * 2];
157 }
158
159 } // namespace clang
160
161 //===----------------------------------------------------------------------===//
162 // TemplateDecl Implementation
163 //===----------------------------------------------------------------------===//
164
165 TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
166                            DeclarationName Name, TemplateParameterList *Params,
167                            NamedDecl *Decl)
168     : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {}
169
170 void TemplateDecl::anchor() {}
171
172 void TemplateDecl::
173 getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
174   // TODO: Concepts: Append function trailing requires clause.
175   TemplateParams->getAssociatedConstraints(AC);
176 }
177
178 bool TemplateDecl::hasAssociatedConstraints() const {
179   // TODO: Concepts: Regard function trailing requires clause.
180   return TemplateParams->hasAssociatedConstraints();
181 }
182
183 //===----------------------------------------------------------------------===//
184 // RedeclarableTemplateDecl Implementation
185 //===----------------------------------------------------------------------===//
186
187 void RedeclarableTemplateDecl::anchor() {}
188
189 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const {
190   if (Common)
191     return Common;
192
193   // Walk the previous-declaration chain until we either find a declaration
194   // with a common pointer or we run out of previous declarations.
195   SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls;
196   for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev;
197        Prev = Prev->getPreviousDecl()) {
198     if (Prev->Common) {
199       Common = Prev->Common;
200       break;
201     }
202
203     PrevDecls.push_back(Prev);
204   }
205
206   // If we never found a common pointer, allocate one now.
207   if (!Common) {
208     // FIXME: If any of the declarations is from an AST file, we probably
209     // need an update record to add the common data.
210
211     Common = newCommon(getASTContext());
212   }
213
214   // Update any previous declarations we saw with the common pointer.
215   for (const RedeclarableTemplateDecl *Prev : PrevDecls)
216     Prev->Common = Common;
217
218   return Common;
219 }
220
221 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
222   // Grab the most recent declaration to ensure we've loaded any lazy
223   // redeclarations of this template.
224   CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
225   if (CommonBasePtr->LazySpecializations) {
226     ASTContext &Context = getASTContext();
227     uint32_t *Specs = CommonBasePtr->LazySpecializations;
228     CommonBasePtr->LazySpecializations = nullptr;
229     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
230       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
231   }
232 }
233
234 template<class EntryType>
235 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
236 RedeclarableTemplateDecl::findSpecializationImpl(
237     llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
238     void *&InsertPos) {
239   using SETraits = SpecEntryTraits<EntryType>;
240
241   llvm::FoldingSetNodeID ID;
242   EntryType::Profile(ID, Args, getASTContext());
243   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
244   return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
245 }
246
247 template<class Derived, class EntryType>
248 void RedeclarableTemplateDecl::addSpecializationImpl(
249     llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
250     void *InsertPos) {
251   using SETraits = SpecEntryTraits<EntryType>;
252
253   if (InsertPos) {
254 #ifndef NDEBUG
255     void *CorrectInsertPos;
256     assert(!findSpecializationImpl(Specializations,
257                                    SETraits::getTemplateArgs(Entry),
258                                    CorrectInsertPos) &&
259            InsertPos == CorrectInsertPos &&
260            "given incorrect InsertPos for specialization");
261 #endif
262     Specializations.InsertNode(Entry, InsertPos);
263   } else {
264     EntryType *Existing = Specializations.GetOrInsertNode(Entry);
265     (void)Existing;
266     assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
267            "non-canonical specialization?");
268   }
269
270   if (ASTMutationListener *L = getASTMutationListener())
271     L->AddedCXXTemplateSpecialization(cast<Derived>(this),
272                                       SETraits::getDecl(Entry));
273 }
274
275 //===----------------------------------------------------------------------===//
276 // FunctionTemplateDecl Implementation
277 //===----------------------------------------------------------------------===//
278
279 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
280                                                    DeclContext *DC,
281                                                    SourceLocation L,
282                                                    DeclarationName Name,
283                                                TemplateParameterList *Params,
284                                                    NamedDecl *Decl) {
285   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
286   return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
287 }
288
289 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
290                                                                unsigned ID) {
291   return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
292                                           DeclarationName(), nullptr, nullptr);
293 }
294
295 RedeclarableTemplateDecl::CommonBase *
296 FunctionTemplateDecl::newCommon(ASTContext &C) const {
297   auto *CommonPtr = new (C) Common;
298   C.addDestruction(CommonPtr);
299   return CommonPtr;
300 }
301
302 void FunctionTemplateDecl::LoadLazySpecializations() const {
303   loadLazySpecializationsImpl();
304 }
305
306 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
307 FunctionTemplateDecl::getSpecializations() const {
308   LoadLazySpecializations();
309   return getCommonPtr()->Specializations;
310 }
311
312 FunctionDecl *
313 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
314                                          void *&InsertPos) {
315   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
316 }
317
318 void FunctionTemplateDecl::addSpecialization(
319       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
320   addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
321                                               InsertPos);
322 }
323
324 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
325   TemplateParameterList *Params = getTemplateParameters();
326   Common *CommonPtr = getCommonPtr();
327   if (!CommonPtr->InjectedArgs) {
328     auto &Context = getASTContext();
329     SmallVector<TemplateArgument, 16> TemplateArgs;
330     Context.getInjectedTemplateArgs(Params, TemplateArgs);
331     CommonPtr->InjectedArgs =
332         new (Context) TemplateArgument[TemplateArgs.size()];
333     std::copy(TemplateArgs.begin(), TemplateArgs.end(),
334               CommonPtr->InjectedArgs);
335   }
336
337   return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
338 }
339
340 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) {
341   using Base = RedeclarableTemplateDecl;
342
343   // If we haven't created a common pointer yet, then it can just be created
344   // with the usual method.
345   if (!Base::Common)
346     return;
347
348   Common *ThisCommon = static_cast<Common *>(Base::Common);
349   Common *PrevCommon = nullptr;
350   SmallVector<FunctionTemplateDecl *, 8> PreviousDecls;
351   for (; Prev; Prev = Prev->getPreviousDecl()) {
352     if (Prev->Base::Common) {
353       PrevCommon = static_cast<Common *>(Prev->Base::Common);
354       break;
355     }
356     PreviousDecls.push_back(Prev);
357   }
358
359   // If the previous redecl chain hasn't created a common pointer yet, then just
360   // use this common pointer.
361   if (!PrevCommon) {
362     for (auto *D : PreviousDecls)
363       D->Base::Common = ThisCommon;
364     return;
365   }
366
367   // Ensure we don't leak any important state.
368   assert(ThisCommon->Specializations.size() == 0 &&
369          "Can't merge incompatible declarations!");
370
371   Base::Common = PrevCommon;
372 }
373
374 //===----------------------------------------------------------------------===//
375 // ClassTemplateDecl Implementation
376 //===----------------------------------------------------------------------===//
377
378 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
379                                              DeclContext *DC,
380                                              SourceLocation L,
381                                              DeclarationName Name,
382                                              TemplateParameterList *Params,
383                                              NamedDecl *Decl) {
384   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
385
386   return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl);
387 }
388
389 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
390                                                          unsigned ID) {
391   return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
392                                        DeclarationName(), nullptr, nullptr);
393 }
394
395 void ClassTemplateDecl::LoadLazySpecializations() const {
396   loadLazySpecializationsImpl();
397 }
398
399 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
400 ClassTemplateDecl::getSpecializations() const {
401   LoadLazySpecializations();
402   return getCommonPtr()->Specializations;
403 }
404
405 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
406 ClassTemplateDecl::getPartialSpecializations() {
407   LoadLazySpecializations();
408   return getCommonPtr()->PartialSpecializations;
409 }
410
411 RedeclarableTemplateDecl::CommonBase *
412 ClassTemplateDecl::newCommon(ASTContext &C) const {
413   auto *CommonPtr = new (C) Common;
414   C.addDestruction(CommonPtr);
415   return CommonPtr;
416 }
417
418 ClassTemplateSpecializationDecl *
419 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
420                                       void *&InsertPos) {
421   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
422 }
423
424 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
425                                           void *InsertPos) {
426   addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
427 }
428
429 ClassTemplatePartialSpecializationDecl *
430 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
431                                              void *&InsertPos) {
432   return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
433 }
434
435 void ClassTemplateDecl::AddPartialSpecialization(
436                                       ClassTemplatePartialSpecializationDecl *D,
437                                       void *InsertPos) {
438   if (InsertPos)
439     getPartialSpecializations().InsertNode(D, InsertPos);
440   else {
441     ClassTemplatePartialSpecializationDecl *Existing
442       = getPartialSpecializations().GetOrInsertNode(D);
443     (void)Existing;
444     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
445   }
446
447   if (ASTMutationListener *L = getASTMutationListener())
448     L->AddedCXXTemplateSpecialization(this, D);
449 }
450
451 void ClassTemplateDecl::getPartialSpecializations(
452           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
453   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
454     = getPartialSpecializations();
455   PS.clear();
456   PS.reserve(PartialSpecs.size());
457   for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs)
458     PS.push_back(P.getMostRecentDecl());
459 }
460
461 ClassTemplatePartialSpecializationDecl *
462 ClassTemplateDecl::findPartialSpecialization(QualType T) {
463   ASTContext &Context = getASTContext();
464   for (ClassTemplatePartialSpecializationDecl &P :
465        getPartialSpecializations()) {
466     if (Context.hasSameType(P.getInjectedSpecializationType(), T))
467       return P.getMostRecentDecl();
468   }
469
470   return nullptr;
471 }
472
473 ClassTemplatePartialSpecializationDecl *
474 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
475                                     ClassTemplatePartialSpecializationDecl *D) {
476   Decl *DCanon = D->getCanonicalDecl();
477   for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
478     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
479       return P.getMostRecentDecl();
480   }
481
482   return nullptr;
483 }
484
485 QualType
486 ClassTemplateDecl::getInjectedClassNameSpecialization() {
487   Common *CommonPtr = getCommonPtr();
488   if (!CommonPtr->InjectedClassNameType.isNull())
489     return CommonPtr->InjectedClassNameType;
490
491   // C++0x [temp.dep.type]p2:
492   //  The template argument list of a primary template is a template argument
493   //  list in which the nth template argument has the value of the nth template
494   //  parameter of the class template. If the nth template parameter is a
495   //  template parameter pack (14.5.3), the nth template argument is a pack
496   //  expansion (14.5.3) whose pattern is the name of the template parameter
497   //  pack.
498   ASTContext &Context = getASTContext();
499   TemplateParameterList *Params = getTemplateParameters();
500   SmallVector<TemplateArgument, 16> TemplateArgs;
501   Context.getInjectedTemplateArgs(Params, TemplateArgs);
502   CommonPtr->InjectedClassNameType
503     = Context.getTemplateSpecializationType(TemplateName(this),
504                                             TemplateArgs);
505   return CommonPtr->InjectedClassNameType;
506 }
507
508 //===----------------------------------------------------------------------===//
509 // TemplateTypeParm Allocation/Deallocation Method Implementations
510 //===----------------------------------------------------------------------===//
511
512 TemplateTypeParmDecl *
513 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
514                              SourceLocation KeyLoc, SourceLocation NameLoc,
515                              unsigned D, unsigned P, IdentifierInfo *Id,
516                              bool Typename, bool ParameterPack) {
517   auto *TTPDecl =
518       new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
519   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
520   TTPDecl->setTypeForDecl(TTPType.getTypePtr());
521   return TTPDecl;
522 }
523
524 TemplateTypeParmDecl *
525 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
526   return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
527                                           SourceLocation(), nullptr, false);
528 }
529
530 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
531   return hasDefaultArgument()
532              ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc()
533              : SourceLocation();
534 }
535
536 SourceRange TemplateTypeParmDecl::getSourceRange() const {
537   if (hasDefaultArgument() && !defaultArgumentWasInherited())
538     return SourceRange(getBeginLoc(),
539                        getDefaultArgumentInfo()->getTypeLoc().getEndLoc());
540   // TypeDecl::getSourceRange returns a range containing name location, which is
541   // wrong for unnamed template parameters. e.g:
542   // it will return <[[typename>]] instead of <[[typename]]>
543   else if (getDeclName().isEmpty())
544     return SourceRange(getBeginLoc());
545   return TypeDecl::getSourceRange();
546 }
547
548 unsigned TemplateTypeParmDecl::getDepth() const {
549   return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth();
550 }
551
552 unsigned TemplateTypeParmDecl::getIndex() const {
553   return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex();
554 }
555
556 bool TemplateTypeParmDecl::isParameterPack() const {
557   return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack();
558 }
559
560 //===----------------------------------------------------------------------===//
561 // NonTypeTemplateParmDecl Method Implementations
562 //===----------------------------------------------------------------------===//
563
564 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(
565     DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D,
566     unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
567     ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos)
568     : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
569       TemplateParmPosition(D, P), ParameterPack(true),
570       ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) {
571   if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) {
572     auto TypesAndInfos =
573         getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
574     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
575       new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]);
576       TypesAndInfos[I].second = ExpandedTInfos[I];
577     }
578   }
579 }
580
581 NonTypeTemplateParmDecl *
582 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
583                                 SourceLocation StartLoc, SourceLocation IdLoc,
584                                 unsigned D, unsigned P, IdentifierInfo *Id,
585                                 QualType T, bool ParameterPack,
586                                 TypeSourceInfo *TInfo) {
587   return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
588                                              T, ParameterPack, TInfo);
589 }
590
591 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create(
592     const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
593     SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
594     QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes,
595     ArrayRef<TypeSourceInfo *> ExpandedTInfos) {
596   return new (C, DC,
597               additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
598                   ExpandedTypes.size()))
599       NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
600                               ExpandedTypes, ExpandedTInfos);
601 }
602
603 NonTypeTemplateParmDecl *
604 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
605   return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
606                                              SourceLocation(), 0, 0, nullptr,
607                                              QualType(), false, nullptr);
608 }
609
610 NonTypeTemplateParmDecl *
611 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
612                                             unsigned NumExpandedTypes) {
613   auto *NTTP =
614       new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>(
615                       NumExpandedTypes))
616           NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(),
617                                   0, 0, nullptr, QualType(), nullptr, None,
618                                   None);
619   NTTP->NumExpandedTypes = NumExpandedTypes;
620   return NTTP;
621 }
622
623 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
624   if (hasDefaultArgument() && !defaultArgumentWasInherited())
625     return SourceRange(getOuterLocStart(),
626                        getDefaultArgument()->getSourceRange().getEnd());
627   return DeclaratorDecl::getSourceRange();
628 }
629
630 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
631   return hasDefaultArgument()
632     ? getDefaultArgument()->getSourceRange().getBegin()
633     : SourceLocation();
634 }
635
636 //===----------------------------------------------------------------------===//
637 // TemplateTemplateParmDecl Method Implementations
638 //===----------------------------------------------------------------------===//
639
640 void TemplateTemplateParmDecl::anchor() {}
641
642 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
643     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
644     IdentifierInfo *Id, TemplateParameterList *Params,
645     ArrayRef<TemplateParameterList *> Expansions)
646     : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
647       TemplateParmPosition(D, P), ParameterPack(true),
648       ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) {
649   if (!Expansions.empty())
650     std::uninitialized_copy(Expansions.begin(), Expansions.end(),
651                             getTrailingObjects<TemplateParameterList *>());
652 }
653
654 TemplateTemplateParmDecl *
655 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
656                                  SourceLocation L, unsigned D, unsigned P,
657                                  bool ParameterPack, IdentifierInfo *Id,
658                                  TemplateParameterList *Params) {
659   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
660                                               Params);
661 }
662
663 TemplateTemplateParmDecl *
664 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
665                                  SourceLocation L, unsigned D, unsigned P,
666                                  IdentifierInfo *Id,
667                                  TemplateParameterList *Params,
668                                  ArrayRef<TemplateParameterList *> Expansions) {
669   return new (C, DC,
670               additionalSizeToAlloc<TemplateParameterList *>(Expansions.size()))
671       TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions);
672 }
673
674 TemplateTemplateParmDecl *
675 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
676   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
677                                               false, nullptr, nullptr);
678 }
679
680 TemplateTemplateParmDecl *
681 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
682                                              unsigned NumExpansions) {
683   auto *TTP =
684       new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions))
685           TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
686                                    nullptr, None);
687   TTP->NumExpandedParams = NumExpansions;
688   return TTP;
689 }
690
691 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
692   return hasDefaultArgument() ? getDefaultArgument().getLocation()
693                               : SourceLocation();
694 }
695
696 void TemplateTemplateParmDecl::setDefaultArgument(
697     const ASTContext &C, const TemplateArgumentLoc &DefArg) {
698   if (DefArg.getArgument().isNull())
699     DefaultArgument.set(nullptr);
700   else
701     DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg));
702 }
703
704 //===----------------------------------------------------------------------===//
705 // TemplateArgumentList Implementation
706 //===----------------------------------------------------------------------===//
707 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args)
708     : Arguments(getTrailingObjects<TemplateArgument>()),
709       NumArguments(Args.size()) {
710   std::uninitialized_copy(Args.begin(), Args.end(),
711                           getTrailingObjects<TemplateArgument>());
712 }
713
714 TemplateArgumentList *
715 TemplateArgumentList::CreateCopy(ASTContext &Context,
716                                  ArrayRef<TemplateArgument> Args) {
717   void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size()));
718   return new (Mem) TemplateArgumentList(Args);
719 }
720
721 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
722     ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
723     TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs,
724     const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI,
725     MemberSpecializationInfo *MSInfo) {
726   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
727   if (TemplateArgsAsWritten)
728     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
729                                                         *TemplateArgsAsWritten);
730
731   void *Mem =
732       C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0));
733   return new (Mem) FunctionTemplateSpecializationInfo(
734       FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo);
735 }
736
737 //===----------------------------------------------------------------------===//
738 // ClassTemplateSpecializationDecl Implementation
739 //===----------------------------------------------------------------------===//
740
741 ClassTemplateSpecializationDecl::
742 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
743                                 DeclContext *DC, SourceLocation StartLoc,
744                                 SourceLocation IdLoc,
745                                 ClassTemplateDecl *SpecializedTemplate,
746                                 ArrayRef<TemplateArgument> Args,
747                                 ClassTemplateSpecializationDecl *PrevDecl)
748     : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
749                     SpecializedTemplate->getIdentifier(), PrevDecl),
750     SpecializedTemplate(SpecializedTemplate),
751     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
752     SpecializationKind(TSK_Undeclared) {
753 }
754
755 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
756                                                                  Kind DK)
757     : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
758                     SourceLocation(), nullptr, nullptr),
759       SpecializationKind(TSK_Undeclared) {}
760
761 ClassTemplateSpecializationDecl *
762 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
763                                         DeclContext *DC,
764                                         SourceLocation StartLoc,
765                                         SourceLocation IdLoc,
766                                         ClassTemplateDecl *SpecializedTemplate,
767                                         ArrayRef<TemplateArgument> Args,
768                                    ClassTemplateSpecializationDecl *PrevDecl) {
769   auto *Result =
770       new (Context, DC) ClassTemplateSpecializationDecl(
771           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
772           SpecializedTemplate, Args, PrevDecl);
773   Result->setMayHaveOutOfDateDef(false);
774
775   Context.getTypeDeclType(Result, PrevDecl);
776   return Result;
777 }
778
779 ClassTemplateSpecializationDecl *
780 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
781                                                     unsigned ID) {
782   auto *Result =
783     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
784   Result->setMayHaveOutOfDateDef(false);
785   return Result;
786 }
787
788 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
789     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
790   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
791
792   const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
793   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
794           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
795     printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
796   } else {
797     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
798     printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
799   }
800 }
801
802 ClassTemplateDecl *
803 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
804   if (const auto *PartialSpec =
805           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
806     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
807   return SpecializedTemplate.get<ClassTemplateDecl*>();
808 }
809
810 SourceRange
811 ClassTemplateSpecializationDecl::getSourceRange() const {
812   if (ExplicitInfo) {
813     SourceLocation Begin = getTemplateKeywordLoc();
814     if (Begin.isValid()) {
815       // Here we have an explicit (partial) specialization or instantiation.
816       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
817              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
818              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
819       if (getExternLoc().isValid())
820         Begin = getExternLoc();
821       SourceLocation End = getBraceRange().getEnd();
822       if (End.isInvalid())
823         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
824       return SourceRange(Begin, End);
825     }
826     // An implicit instantiation of a class template partial specialization
827     // uses ExplicitInfo to record the TypeAsWritten, but the source
828     // locations should be retrieved from the instantiation pattern.
829     using CTPSDecl = ClassTemplatePartialSpecializationDecl;
830     auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
831     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
832     assert(inst_from != nullptr);
833     return inst_from->getSourceRange();
834   }
835   else {
836     // No explicit info available.
837     llvm::PointerUnion<ClassTemplateDecl *,
838                        ClassTemplatePartialSpecializationDecl *>
839       inst_from = getInstantiatedFrom();
840     if (inst_from.isNull())
841       return getSpecializedTemplate()->getSourceRange();
842     if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
843       return ctd->getSourceRange();
844     return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
845       ->getSourceRange();
846   }
847 }
848
849 //===----------------------------------------------------------------------===//
850 // ConceptDecl Implementation
851 //===----------------------------------------------------------------------===//
852 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
853                                  SourceLocation L, DeclarationName Name,
854                                  TemplateParameterList *Params,
855                                  Expr *ConstraintExpr) {
856   AdoptTemplateParameterList(Params, DC);
857   return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
858 }
859
860 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
861                                              unsigned ID) {
862   ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
863                                                 DeclarationName(),
864                                                 nullptr, nullptr);
865
866   return Result;
867 }
868
869 //===----------------------------------------------------------------------===//
870 // ClassTemplatePartialSpecializationDecl Implementation
871 //===----------------------------------------------------------------------===//
872 void ClassTemplatePartialSpecializationDecl::anchor() {}
873
874 ClassTemplatePartialSpecializationDecl::
875 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
876                                        DeclContext *DC,
877                                        SourceLocation StartLoc,
878                                        SourceLocation IdLoc,
879                                        TemplateParameterList *Params,
880                                        ClassTemplateDecl *SpecializedTemplate,
881                                        ArrayRef<TemplateArgument> Args,
882                                const ASTTemplateArgumentListInfo *ArgInfos,
883                                ClassTemplatePartialSpecializationDecl *PrevDecl)
884     : ClassTemplateSpecializationDecl(Context,
885                                       ClassTemplatePartialSpecialization,
886                                       TK, DC, StartLoc, IdLoc,
887                                       SpecializedTemplate, Args, PrevDecl),
888       TemplateParams(Params), ArgsAsWritten(ArgInfos),
889       InstantiatedFromMember(nullptr, false) {
890   AdoptTemplateParameterList(Params, this);
891 }
892
893 ClassTemplatePartialSpecializationDecl *
894 ClassTemplatePartialSpecializationDecl::
895 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
896        SourceLocation StartLoc, SourceLocation IdLoc,
897        TemplateParameterList *Params,
898        ClassTemplateDecl *SpecializedTemplate,
899        ArrayRef<TemplateArgument> Args,
900        const TemplateArgumentListInfo &ArgInfos,
901        QualType CanonInjectedType,
902        ClassTemplatePartialSpecializationDecl *PrevDecl) {
903   const ASTTemplateArgumentListInfo *ASTArgInfos =
904     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
905
906   auto *Result = new (Context, DC)
907       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
908                                              Params, SpecializedTemplate, Args,
909                                              ASTArgInfos, PrevDecl);
910   Result->setSpecializationKind(TSK_ExplicitSpecialization);
911   Result->setMayHaveOutOfDateDef(false);
912
913   Context.getInjectedClassNameType(Result, CanonInjectedType);
914   return Result;
915 }
916
917 ClassTemplatePartialSpecializationDecl *
918 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
919                                                            unsigned ID) {
920   auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
921   Result->setMayHaveOutOfDateDef(false);
922   return Result;
923 }
924
925 //===----------------------------------------------------------------------===//
926 // FriendTemplateDecl Implementation
927 //===----------------------------------------------------------------------===//
928
929 void FriendTemplateDecl::anchor() {}
930
931 FriendTemplateDecl *
932 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
933                            SourceLocation L,
934                            MutableArrayRef<TemplateParameterList *> Params,
935                            FriendUnion Friend, SourceLocation FLoc) {
936   return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc);
937 }
938
939 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
940                                                            unsigned ID) {
941   return new (C, ID) FriendTemplateDecl(EmptyShell());
942 }
943
944 //===----------------------------------------------------------------------===//
945 // TypeAliasTemplateDecl Implementation
946 //===----------------------------------------------------------------------===//
947
948 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
949                                                      DeclContext *DC,
950                                                      SourceLocation L,
951                                                      DeclarationName Name,
952                                                   TemplateParameterList *Params,
953                                                      NamedDecl *Decl) {
954   AdoptTemplateParameterList(Params, DC);
955   return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
956 }
957
958 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
959                                                                  unsigned ID) {
960   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
961                                            DeclarationName(), nullptr, nullptr);
962 }
963
964 RedeclarableTemplateDecl::CommonBase *
965 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
966   auto *CommonPtr = new (C) Common;
967   C.addDestruction(CommonPtr);
968   return CommonPtr;
969 }
970
971 //===----------------------------------------------------------------------===//
972 // ClassScopeFunctionSpecializationDecl Implementation
973 //===----------------------------------------------------------------------===//
974
975 void ClassScopeFunctionSpecializationDecl::anchor() {}
976
977 ClassScopeFunctionSpecializationDecl *
978 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
979                                                          unsigned ID) {
980   return new (C, ID) ClassScopeFunctionSpecializationDecl(
981       nullptr, SourceLocation(), nullptr, nullptr);
982 }
983
984 //===----------------------------------------------------------------------===//
985 // VarTemplateDecl Implementation
986 //===----------------------------------------------------------------------===//
987
988 VarTemplateDecl *VarTemplateDecl::getDefinition() {
989   VarTemplateDecl *CurD = this;
990   while (CurD) {
991     if (CurD->isThisDeclarationADefinition())
992       return CurD;
993     CurD = CurD->getPreviousDecl();
994   }
995   return nullptr;
996 }
997
998 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
999                                          SourceLocation L, DeclarationName Name,
1000                                          TemplateParameterList *Params,
1001                                          VarDecl *Decl) {
1002   AdoptTemplateParameterList(Params, DC);
1003   return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
1004 }
1005
1006 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
1007                                                      unsigned ID) {
1008   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
1009                                      DeclarationName(), nullptr, nullptr);
1010 }
1011
1012 void VarTemplateDecl::LoadLazySpecializations() const {
1013   loadLazySpecializationsImpl();
1014 }
1015
1016 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
1017 VarTemplateDecl::getSpecializations() const {
1018   LoadLazySpecializations();
1019   return getCommonPtr()->Specializations;
1020 }
1021
1022 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
1023 VarTemplateDecl::getPartialSpecializations() {
1024   LoadLazySpecializations();
1025   return getCommonPtr()->PartialSpecializations;
1026 }
1027
1028 RedeclarableTemplateDecl::CommonBase *
1029 VarTemplateDecl::newCommon(ASTContext &C) const {
1030   auto *CommonPtr = new (C) Common;
1031   C.addDestruction(CommonPtr);
1032   return CommonPtr;
1033 }
1034
1035 VarTemplateSpecializationDecl *
1036 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
1037                                     void *&InsertPos) {
1038   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
1039 }
1040
1041 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
1042                                         void *InsertPos) {
1043   addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
1044 }
1045
1046 VarTemplatePartialSpecializationDecl *
1047 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1048                                            void *&InsertPos) {
1049   return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1050 }
1051
1052 void VarTemplateDecl::AddPartialSpecialization(
1053     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1054   if (InsertPos)
1055     getPartialSpecializations().InsertNode(D, InsertPos);
1056   else {
1057     VarTemplatePartialSpecializationDecl *Existing =
1058         getPartialSpecializations().GetOrInsertNode(D);
1059     (void)Existing;
1060     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1061   }
1062
1063   if (ASTMutationListener *L = getASTMutationListener())
1064     L->AddedCXXTemplateSpecialization(this, D);
1065 }
1066
1067 void VarTemplateDecl::getPartialSpecializations(
1068     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1069   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1070       getPartialSpecializations();
1071   PS.clear();
1072   PS.reserve(PartialSpecs.size());
1073   for (VarTemplatePartialSpecializationDecl &P : PartialSpecs)
1074     PS.push_back(P.getMostRecentDecl());
1075 }
1076
1077 VarTemplatePartialSpecializationDecl *
1078 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1079     VarTemplatePartialSpecializationDecl *D) {
1080   Decl *DCanon = D->getCanonicalDecl();
1081   for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) {
1082     if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1083       return P.getMostRecentDecl();
1084   }
1085
1086   return nullptr;
1087 }
1088
1089 //===----------------------------------------------------------------------===//
1090 // VarTemplateSpecializationDecl Implementation
1091 //===----------------------------------------------------------------------===//
1092
1093 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1094     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1095     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1096     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
1097     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1098               SpecializedTemplate->getIdentifier(), T, TInfo, S),
1099       SpecializedTemplate(SpecializedTemplate),
1100       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
1101       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1102
1103 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1104                                                              ASTContext &C)
1105     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1106               QualType(), nullptr, SC_None),
1107       SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
1108
1109 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1110     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1111     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1112     TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) {
1113   return new (Context, DC) VarTemplateSpecializationDecl(
1114       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1115       SpecializedTemplate, T, TInfo, S, Args);
1116 }
1117
1118 VarTemplateSpecializationDecl *
1119 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1120   return new (C, ID)
1121       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1122 }
1123
1124 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1125     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1126   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1127
1128   const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
1129   if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
1130           PS ? PS->getTemplateArgsAsWritten() : nullptr) {
1131     printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
1132   } else {
1133     const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1134     printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
1135   }
1136 }
1137
1138 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1139   if (const auto *PartialSpec =
1140           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1141     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1142   return SpecializedTemplate.get<VarTemplateDecl *>();
1143 }
1144
1145 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1146     const TemplateArgumentListInfo &ArgsInfo) {
1147   TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1148   TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1149   for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
1150     TemplateArgsInfo.addArgument(Loc);
1151 }
1152
1153 //===----------------------------------------------------------------------===//
1154 // VarTemplatePartialSpecializationDecl Implementation
1155 //===----------------------------------------------------------------------===//
1156
1157 void VarTemplatePartialSpecializationDecl::anchor() {}
1158
1159 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1160     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1161     SourceLocation IdLoc, TemplateParameterList *Params,
1162     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1163     StorageClass S, ArrayRef<TemplateArgument> Args,
1164     const ASTTemplateArgumentListInfo *ArgInfos)
1165     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1166                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1167                                     TInfo, S, Args),
1168       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1169       InstantiatedFromMember(nullptr, false) {
1170   // TODO: The template parameters should be in DC by now. Verify.
1171   // AdoptTemplateParameterList(Params, DC);
1172 }
1173
1174 VarTemplatePartialSpecializationDecl *
1175 VarTemplatePartialSpecializationDecl::Create(
1176     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1177     SourceLocation IdLoc, TemplateParameterList *Params,
1178     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1179     StorageClass S, ArrayRef<TemplateArgument> Args,
1180     const TemplateArgumentListInfo &ArgInfos) {
1181   const ASTTemplateArgumentListInfo *ASTArgInfos
1182     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1183
1184   auto *Result =
1185       new (Context, DC) VarTemplatePartialSpecializationDecl(
1186           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1187           S, Args, ASTArgInfos);
1188   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1189   return Result;
1190 }
1191
1192 VarTemplatePartialSpecializationDecl *
1193 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1194                                                          unsigned ID) {
1195   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1196 }
1197
1198 static TemplateParameterList *
1199 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
1200   // typename T
1201   auto *T = TemplateTypeParmDecl::Create(
1202       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0,
1203       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1204   T->setImplicit(true);
1205
1206   // T ...Ints
1207   TypeSourceInfo *TI =
1208       C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0));
1209   auto *N = NonTypeTemplateParmDecl::Create(
1210       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1211       /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI);
1212   N->setImplicit(true);
1213
1214   // <typename T, T ...Ints>
1215   NamedDecl *P[2] = {T, N};
1216   auto *TPL = TemplateParameterList::Create(
1217       C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr);
1218
1219   // template <typename T, ...Ints> class IntSeq
1220   auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create(
1221       C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0,
1222       /*ParameterPack=*/false, /*Id=*/nullptr, TPL);
1223   TemplateTemplateParm->setImplicit(true);
1224
1225   // typename T
1226   auto *TemplateTypeParm = TemplateTypeParmDecl::Create(
1227       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1228       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false);
1229   TemplateTypeParm->setImplicit(true);
1230
1231   // T N
1232   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(
1233       QualType(TemplateTypeParm->getTypeForDecl(), 0));
1234   auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create(
1235       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2,
1236       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1237   NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm,
1238                          NonTypeTemplateParm};
1239
1240   // template <template <typename T, T ...Ints> class IntSeq, typename T, T N>
1241   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1242                                        Params, SourceLocation(), nullptr);
1243 }
1244
1245 static TemplateParameterList *
1246 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) {
1247   // std::size_t Index
1248   TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType());
1249   auto *Index = NonTypeTemplateParmDecl::Create(
1250       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0,
1251       /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo);
1252
1253   // typename ...T
1254   auto *Ts = TemplateTypeParmDecl::Create(
1255       C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1,
1256       /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true);
1257   Ts->setImplicit(true);
1258
1259   // template <std::size_t Index, typename ...T>
1260   NamedDecl *Params[] = {Index, Ts};
1261   return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(),
1262                                        llvm::makeArrayRef(Params),
1263                                        SourceLocation(), nullptr);
1264 }
1265
1266 static TemplateParameterList *createBuiltinTemplateParameterList(
1267     const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) {
1268   switch (BTK) {
1269   case BTK__make_integer_seq:
1270     return createMakeIntegerSeqParameterList(C, DC);
1271   case BTK__type_pack_element:
1272     return createTypePackElementParameterList(C, DC);
1273   }
1274
1275   llvm_unreachable("unhandled BuiltinTemplateKind!");
1276 }
1277
1278 void BuiltinTemplateDecl::anchor() {}
1279
1280 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
1281                                          DeclarationName Name,
1282                                          BuiltinTemplateKind BTK)
1283     : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name,
1284                    createBuiltinTemplateParameterList(C, DC, BTK)),
1285       BTK(BTK) {}