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