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