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