• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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,
167                                  ArrayRef<TemplateArgument> Args,
168                                  void *&InsertPos) {
169   typedef SpecEntryTraits<EntryType> SETraits;
170   llvm::FoldingSetNodeID ID;
171   EntryType::Profile(ID,Args, getASTContext());
172   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
173   return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
174 }
175 
176 /// \brief Generate the injected template arguments for the given template
177 /// parameter list, e.g., for the injected-class-name of a class template.
GenerateInjectedTemplateArgs(ASTContext & Context,TemplateParameterList * Params,TemplateArgument * Args)178 static void GenerateInjectedTemplateArgs(ASTContext &Context,
179                                         TemplateParameterList *Params,
180                                          TemplateArgument *Args) {
181   for (TemplateParameterList::iterator Param = Params->begin(),
182                                     ParamEnd = Params->end();
183        Param != ParamEnd; ++Param) {
184     TemplateArgument Arg;
185     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
186       QualType ArgType = Context.getTypeDeclType(TTP);
187       if (TTP->isParameterPack())
188         ArgType = Context.getPackExpansionType(ArgType, None);
189 
190       Arg = TemplateArgument(ArgType);
191     } else if (NonTypeTemplateParmDecl *NTTP =
192                dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
193       Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false,
194                                   NTTP->getType().getNonLValueExprType(Context),
195                                   Expr::getValueKindForType(NTTP->getType()),
196                                           NTTP->getLocation());
197 
198       if (NTTP->isParameterPack())
199         E = new (Context) PackExpansionExpr(Context.DependentTy, E,
200                                             NTTP->getLocation(), None);
201       Arg = TemplateArgument(E);
202     } else {
203       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
204       if (TTP->isParameterPack())
205         Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>());
206       else
207         Arg = TemplateArgument(TemplateName(TTP));
208     }
209 
210     if ((*Param)->isTemplateParameterPack())
211       Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
212 
213     *Args++ = Arg;
214   }
215 }
216 
217 //===----------------------------------------------------------------------===//
218 // FunctionTemplateDecl Implementation
219 //===----------------------------------------------------------------------===//
220 
DeallocateCommon(void * Ptr)221 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
222   static_cast<Common *>(Ptr)->~Common();
223 }
224 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)225 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
226                                                    DeclContext *DC,
227                                                    SourceLocation L,
228                                                    DeclarationName Name,
229                                                TemplateParameterList *Params,
230                                                    NamedDecl *Decl) {
231   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
232   return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl);
233 }
234 
CreateDeserialized(ASTContext & C,unsigned ID)235 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C,
236                                                                unsigned ID) {
237   return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(),
238                                           DeclarationName(), nullptr, nullptr);
239 }
240 
241 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const242 FunctionTemplateDecl::newCommon(ASTContext &C) const {
243   Common *CommonPtr = new (C) Common;
244   C.AddDeallocation(DeallocateCommon, CommonPtr);
245   return CommonPtr;
246 }
247 
LoadLazySpecializations() const248 void FunctionTemplateDecl::LoadLazySpecializations() const {
249   Common *CommonPtr = getCommonPtr();
250   if (CommonPtr->LazySpecializations) {
251     ASTContext &Context = getASTContext();
252     uint32_t *Specs = CommonPtr->LazySpecializations;
253     CommonPtr->LazySpecializations = nullptr;
254     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
255       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
256   }
257 }
258 
259 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
getSpecializations() const260 FunctionTemplateDecl::getSpecializations() const {
261   LoadLazySpecializations();
262   return getCommonPtr()->Specializations;
263 }
264 
265 FunctionDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)266 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
267                                          void *&InsertPos) {
268   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
269 }
270 
addSpecialization(FunctionTemplateSpecializationInfo * Info,void * InsertPos)271 void FunctionTemplateDecl::addSpecialization(
272       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
273   if (InsertPos)
274     getSpecializations().InsertNode(Info, InsertPos);
275   else
276     getSpecializations().GetOrInsertNode(Info);
277   if (ASTMutationListener *L = getASTMutationListener())
278     L->AddedCXXTemplateSpecialization(this, Info->Function);
279 }
280 
getInjectedTemplateArgs()281 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
282   TemplateParameterList *Params = getTemplateParameters();
283   Common *CommonPtr = getCommonPtr();
284   if (!CommonPtr->InjectedArgs) {
285     CommonPtr->InjectedArgs
286       = new (getASTContext()) TemplateArgument[Params->size()];
287     GenerateInjectedTemplateArgs(getASTContext(), Params,
288                                  CommonPtr->InjectedArgs);
289   }
290 
291   return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size());
292 }
293 
294 //===----------------------------------------------------------------------===//
295 // ClassTemplateDecl Implementation
296 //===----------------------------------------------------------------------===//
297 
DeallocateCommon(void * Ptr)298 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
299   static_cast<Common *>(Ptr)->~Common();
300 }
301 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl,ClassTemplateDecl * PrevDecl)302 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
303                                              DeclContext *DC,
304                                              SourceLocation L,
305                                              DeclarationName Name,
306                                              TemplateParameterList *Params,
307                                              NamedDecl *Decl,
308                                              ClassTemplateDecl *PrevDecl) {
309   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
310   ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name,
311                                                          Params, Decl);
312   New->setPreviousDecl(PrevDecl);
313   return New;
314 }
315 
CreateDeserialized(ASTContext & C,unsigned ID)316 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
317                                                          unsigned ID) {
318   return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(),
319                                        DeclarationName(), nullptr, nullptr);
320 }
321 
LoadLazySpecializations() const322 void ClassTemplateDecl::LoadLazySpecializations() const {
323   Common *CommonPtr = getCommonPtr();
324   if (CommonPtr->LazySpecializations) {
325     ASTContext &Context = getASTContext();
326     uint32_t *Specs = CommonPtr->LazySpecializations;
327     CommonPtr->LazySpecializations = nullptr;
328     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
329       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
330   }
331 }
332 
333 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
getSpecializations() const334 ClassTemplateDecl::getSpecializations() const {
335   LoadLazySpecializations();
336   return getCommonPtr()->Specializations;
337 }
338 
339 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations()340 ClassTemplateDecl::getPartialSpecializations() {
341   LoadLazySpecializations();
342   return getCommonPtr()->PartialSpecializations;
343 }
344 
345 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const346 ClassTemplateDecl::newCommon(ASTContext &C) const {
347   Common *CommonPtr = new (C) Common;
348   C.AddDeallocation(DeallocateCommon, CommonPtr);
349   return CommonPtr;
350 }
351 
352 ClassTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)353 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
354                                       void *&InsertPos) {
355   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
356 }
357 
AddSpecialization(ClassTemplateSpecializationDecl * D,void * InsertPos)358 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
359                                           void *InsertPos) {
360   if (InsertPos)
361     getSpecializations().InsertNode(D, InsertPos);
362   else {
363     ClassTemplateSpecializationDecl *Existing
364       = getSpecializations().GetOrInsertNode(D);
365     (void)Existing;
366     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
367   }
368   if (ASTMutationListener *L = getASTMutationListener())
369     L->AddedCXXTemplateSpecialization(this, D);
370 }
371 
372 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)373 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
374                                              void *&InsertPos) {
375   return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
376 }
377 
AddPartialSpecialization(ClassTemplatePartialSpecializationDecl * D,void * InsertPos)378 void ClassTemplateDecl::AddPartialSpecialization(
379                                       ClassTemplatePartialSpecializationDecl *D,
380                                       void *InsertPos) {
381   if (InsertPos)
382     getPartialSpecializations().InsertNode(D, InsertPos);
383   else {
384     ClassTemplatePartialSpecializationDecl *Existing
385       = getPartialSpecializations().GetOrInsertNode(D);
386     (void)Existing;
387     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
388   }
389 
390   if (ASTMutationListener *L = getASTMutationListener())
391     L->AddedCXXTemplateSpecialization(this, D);
392 }
393 
getPartialSpecializations(SmallVectorImpl<ClassTemplatePartialSpecializationDecl * > & PS)394 void ClassTemplateDecl::getPartialSpecializations(
395           SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
396   llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs
397     = getPartialSpecializations();
398   PS.clear();
399   PS.reserve(PartialSpecs.size());
400   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
401        P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
402        P != PEnd; ++P)
403     PS.push_back(P->getMostRecentDecl());
404 }
405 
406 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(QualType T)407 ClassTemplateDecl::findPartialSpecialization(QualType T) {
408   ASTContext &Context = getASTContext();
409   using llvm::FoldingSetVector;
410   typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
411     partial_spec_iterator;
412   for (partial_spec_iterator P = getPartialSpecializations().begin(),
413                           PEnd = getPartialSpecializations().end();
414        P != PEnd; ++P) {
415     if (Context.hasSameType(P->getInjectedSpecializationType(), T))
416       return P->getMostRecentDecl();
417   }
418 
419   return nullptr;
420 }
421 
422 ClassTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl * D)423 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
424                                     ClassTemplatePartialSpecializationDecl *D) {
425   Decl *DCanon = D->getCanonicalDecl();
426   for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator
427             P = getPartialSpecializations().begin(),
428          PEnd = getPartialSpecializations().end();
429        P != PEnd; ++P) {
430     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
431       return P->getMostRecentDecl();
432   }
433 
434   return nullptr;
435 }
436 
437 QualType
getInjectedClassNameSpecialization()438 ClassTemplateDecl::getInjectedClassNameSpecialization() {
439   Common *CommonPtr = getCommonPtr();
440   if (!CommonPtr->InjectedClassNameType.isNull())
441     return CommonPtr->InjectedClassNameType;
442 
443   // C++0x [temp.dep.type]p2:
444   //  The template argument list of a primary template is a template argument
445   //  list in which the nth template argument has the value of the nth template
446   //  parameter of the class template. If the nth template parameter is a
447   //  template parameter pack (14.5.3), the nth template argument is a pack
448   //  expansion (14.5.3) whose pattern is the name of the template parameter
449   //  pack.
450   ASTContext &Context = getASTContext();
451   TemplateParameterList *Params = getTemplateParameters();
452   SmallVector<TemplateArgument, 16> TemplateArgs;
453   TemplateArgs.resize(Params->size());
454   GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
455   CommonPtr->InjectedClassNameType
456     = Context.getTemplateSpecializationType(TemplateName(this),
457                                             &TemplateArgs[0],
458                                             TemplateArgs.size());
459   return CommonPtr->InjectedClassNameType;
460 }
461 
462 //===----------------------------------------------------------------------===//
463 // TemplateTypeParm Allocation/Deallocation Method Implementations
464 //===----------------------------------------------------------------------===//
465 
466 TemplateTypeParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation KeyLoc,SourceLocation NameLoc,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,bool ParameterPack)467 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
468                              SourceLocation KeyLoc, SourceLocation NameLoc,
469                              unsigned D, unsigned P, IdentifierInfo *Id,
470                              bool Typename, bool ParameterPack) {
471   TemplateTypeParmDecl *TTPDecl =
472     new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
473   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
474   TTPDecl->setTypeForDecl(TTPType.getTypePtr());
475   return TTPDecl;
476 }
477 
478 TemplateTypeParmDecl *
CreateDeserialized(const ASTContext & C,unsigned ID)479 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
480   return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(),
481                                           SourceLocation(), nullptr, false);
482 }
483 
getDefaultArgumentLoc() const484 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
485   return hasDefaultArgument()
486     ? DefaultArgument->getTypeLoc().getBeginLoc()
487     : SourceLocation();
488 }
489 
getSourceRange() const490 SourceRange TemplateTypeParmDecl::getSourceRange() const {
491   if (hasDefaultArgument() && !defaultArgumentWasInherited())
492     return SourceRange(getLocStart(),
493                        DefaultArgument->getTypeLoc().getEndLoc());
494   else
495     return TypeDecl::getSourceRange();
496 }
497 
getDepth() const498 unsigned TemplateTypeParmDecl::getDepth() const {
499   return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth();
500 }
501 
getIndex() const502 unsigned TemplateTypeParmDecl::getIndex() const {
503   return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex();
504 }
505 
isParameterPack() const506 bool TemplateTypeParmDecl::isParameterPack() const {
507   return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack();
508 }
509 
510 //===----------------------------------------------------------------------===//
511 // NonTypeTemplateParmDecl Method Implementations
512 //===----------------------------------------------------------------------===//
513 
NonTypeTemplateParmDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,const QualType * ExpandedTypes,unsigned NumExpandedTypes,TypeSourceInfo ** ExpandedTInfos)514 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
515                                                  SourceLocation StartLoc,
516                                                  SourceLocation IdLoc,
517                                                  unsigned D, unsigned P,
518                                                  IdentifierInfo *Id,
519                                                  QualType T,
520                                                  TypeSourceInfo *TInfo,
521                                                  const QualType *ExpandedTypes,
522                                                  unsigned NumExpandedTypes,
523                                                 TypeSourceInfo **ExpandedTInfos)
524   : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
525     TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
526     ParameterPack(true), ExpandedParameterPack(true),
527     NumExpandedTypes(NumExpandedTypes)
528 {
529   if (ExpandedTypes && ExpandedTInfos) {
530     void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
531     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
532       TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
533       TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
534     }
535   }
536 }
537 
538 NonTypeTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,bool ParameterPack,TypeSourceInfo * TInfo)539 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
540                                 SourceLocation StartLoc, SourceLocation IdLoc,
541                                 unsigned D, unsigned P, IdentifierInfo *Id,
542                                 QualType T, bool ParameterPack,
543                                 TypeSourceInfo *TInfo) {
544   return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
545                                              T, ParameterPack, TInfo);
546 }
547 
548 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)549 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
550                                 SourceLocation StartLoc, SourceLocation IdLoc,
551                                 unsigned D, unsigned P,
552                                 IdentifierInfo *Id, QualType T,
553                                 TypeSourceInfo *TInfo,
554                                 const QualType *ExpandedTypes,
555                                 unsigned NumExpandedTypes,
556                                 TypeSourceInfo **ExpandedTInfos) {
557   unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
558   return new (C, DC, Extra) NonTypeTemplateParmDecl(
559       DC, StartLoc, IdLoc, D, P, Id, T, TInfo,
560       ExpandedTypes, NumExpandedTypes, ExpandedTInfos);
561 }
562 
563 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)564 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
565   return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(),
566                                              SourceLocation(), 0, 0, nullptr,
567                                              QualType(), false, nullptr);
568 }
569 
570 NonTypeTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpandedTypes)571 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
572                                             unsigned NumExpandedTypes) {
573   unsigned Extra = NumExpandedTypes * 2 * sizeof(void*);
574   return new (C, ID, Extra) NonTypeTemplateParmDecl(
575       nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(),
576       nullptr, nullptr, NumExpandedTypes, nullptr);
577 }
578 
getSourceRange() const579 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
580   if (hasDefaultArgument() && !defaultArgumentWasInherited())
581     return SourceRange(getOuterLocStart(),
582                        getDefaultArgument()->getSourceRange().getEnd());
583   return DeclaratorDecl::getSourceRange();
584 }
585 
getDefaultArgumentLoc() const586 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
587   return hasDefaultArgument()
588     ? getDefaultArgument()->getSourceRange().getBegin()
589     : SourceLocation();
590 }
591 
592 //===----------------------------------------------------------------------===//
593 // TemplateTemplateParmDecl Method Implementations
594 //===----------------------------------------------------------------------===//
595 
anchor()596 void TemplateTemplateParmDecl::anchor() { }
597 
TemplateTemplateParmDecl(DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,unsigned NumExpansions,TemplateParameterList * const * Expansions)598 TemplateTemplateParmDecl::TemplateTemplateParmDecl(
599     DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
600     IdentifierInfo *Id, TemplateParameterList *Params,
601     unsigned NumExpansions, TemplateParameterList * const *Expansions)
602   : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
603     TemplateParmPosition(D, P), DefaultArgument(),
604     DefaultArgumentWasInherited(false), ParameterPack(true),
605     ExpandedParameterPack(true), NumExpandedParams(NumExpansions) {
606   if (Expansions)
607     std::memcpy(reinterpret_cast<void*>(this + 1), Expansions,
608                 sizeof(TemplateParameterList*) * NumExpandedParams);
609 }
610 
611 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,bool ParameterPack,IdentifierInfo * Id,TemplateParameterList * Params)612 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
613                                  SourceLocation L, unsigned D, unsigned P,
614                                  bool ParameterPack, IdentifierInfo *Id,
615                                  TemplateParameterList *Params) {
616   return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
617                                               Params);
618 }
619 
620 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,IdentifierInfo * Id,TemplateParameterList * Params,ArrayRef<TemplateParameterList * > Expansions)621 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
622                                  SourceLocation L, unsigned D, unsigned P,
623                                  IdentifierInfo *Id,
624                                  TemplateParameterList *Params,
625                                  ArrayRef<TemplateParameterList *> Expansions) {
626   return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size())
627       TemplateTemplateParmDecl(DC, L, D, P, Id, Params,
628                                Expansions.size(), Expansions.data());
629 }
630 
631 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID)632 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
633   return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0,
634                                               false, nullptr, nullptr);
635 }
636 
637 TemplateTemplateParmDecl *
CreateDeserialized(ASTContext & C,unsigned ID,unsigned NumExpansions)638 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID,
639                                              unsigned NumExpansions) {
640   return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions)
641       TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr,
642                                nullptr, NumExpansions, nullptr);
643 }
644 
645 //===----------------------------------------------------------------------===//
646 // TemplateArgumentList Implementation
647 //===----------------------------------------------------------------------===//
648 TemplateArgumentList *
CreateCopy(ASTContext & Context,const TemplateArgument * Args,unsigned NumArgs)649 TemplateArgumentList::CreateCopy(ASTContext &Context,
650                                  const TemplateArgument *Args,
651                                  unsigned NumArgs) {
652   std::size_t Size = sizeof(TemplateArgumentList)
653                    + NumArgs * sizeof(TemplateArgument);
654   void *Mem = Context.Allocate(Size);
655   TemplateArgument *StoredArgs
656     = reinterpret_cast<TemplateArgument *>(
657                                 static_cast<TemplateArgumentList *>(Mem) + 1);
658   std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
659   return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
660 }
661 
662 FunctionTemplateSpecializationInfo *
Create(ASTContext & C,FunctionDecl * FD,FunctionTemplateDecl * Template,TemplateSpecializationKind TSK,const TemplateArgumentList * TemplateArgs,const TemplateArgumentListInfo * TemplateArgsAsWritten,SourceLocation POI)663 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
664                                            FunctionTemplateDecl *Template,
665                                            TemplateSpecializationKind TSK,
666                                        const TemplateArgumentList *TemplateArgs,
667                           const TemplateArgumentListInfo *TemplateArgsAsWritten,
668                                            SourceLocation POI) {
669   const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
670   if (TemplateArgsAsWritten)
671     ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
672                                                         *TemplateArgsAsWritten);
673 
674   return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
675                                                     TemplateArgs,
676                                                     ArgsAsWritten,
677                                                     POI);
678 }
679 
680 //===----------------------------------------------------------------------===//
681 // TemplateDecl Implementation
682 //===----------------------------------------------------------------------===//
683 
anchor()684 void TemplateDecl::anchor() { }
685 
686 //===----------------------------------------------------------------------===//
687 // ClassTemplateSpecializationDecl Implementation
688 //===----------------------------------------------------------------------===//
689 ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext & Context,Kind DK,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,const TemplateArgument * Args,unsigned NumArgs,ClassTemplateSpecializationDecl * PrevDecl)690 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
691                                 DeclContext *DC, SourceLocation StartLoc,
692                                 SourceLocation IdLoc,
693                                 ClassTemplateDecl *SpecializedTemplate,
694                                 const TemplateArgument *Args,
695                                 unsigned NumArgs,
696                                 ClassTemplateSpecializationDecl *PrevDecl)
697   : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
698                   SpecializedTemplate->getIdentifier(),
699                   PrevDecl),
700     SpecializedTemplate(SpecializedTemplate),
701     ExplicitInfo(nullptr),
702     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
703     SpecializationKind(TSK_Undeclared) {
704 }
705 
ClassTemplateSpecializationDecl(ASTContext & C,Kind DK)706 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
707                                                                  Kind DK)
708     : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
709                     SourceLocation(), nullptr, nullptr),
710       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
711 
712 ClassTemplateSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,const TemplateArgument * Args,unsigned NumArgs,ClassTemplateSpecializationDecl * PrevDecl)713 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
714                                         DeclContext *DC,
715                                         SourceLocation StartLoc,
716                                         SourceLocation IdLoc,
717                                         ClassTemplateDecl *SpecializedTemplate,
718                                         const TemplateArgument *Args,
719                                         unsigned NumArgs,
720                                    ClassTemplateSpecializationDecl *PrevDecl) {
721   ClassTemplateSpecializationDecl *Result =
722       new (Context, DC) ClassTemplateSpecializationDecl(
723           Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
724           SpecializedTemplate, Args, NumArgs, PrevDecl);
725   Result->MayHaveOutOfDateDef = false;
726 
727   Context.getTypeDeclType(Result, PrevDecl);
728   return Result;
729 }
730 
731 ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)732 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
733                                                     unsigned ID) {
734   ClassTemplateSpecializationDecl *Result =
735     new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
736   Result->MayHaveOutOfDateDef = false;
737   return Result;
738 }
739 
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const740 void ClassTemplateSpecializationDecl::getNameForDiagnostic(
741     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
742   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
743 
744   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
745   TemplateSpecializationType::PrintTemplateArgumentList(
746       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
747 }
748 
749 ClassTemplateDecl *
getSpecializedTemplate() const750 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
751   if (SpecializedPartialSpecialization *PartialSpec
752       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
753     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
754   return SpecializedTemplate.get<ClassTemplateDecl*>();
755 }
756 
757 SourceRange
getSourceRange() const758 ClassTemplateSpecializationDecl::getSourceRange() const {
759   if (ExplicitInfo) {
760     SourceLocation Begin = getTemplateKeywordLoc();
761     if (Begin.isValid()) {
762       // Here we have an explicit (partial) specialization or instantiation.
763       assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
764              getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
765              getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
766       if (getExternLoc().isValid())
767         Begin = getExternLoc();
768       SourceLocation End = getRBraceLoc();
769       if (End.isInvalid())
770         End = getTypeAsWritten()->getTypeLoc().getEndLoc();
771       return SourceRange(Begin, End);
772     }
773     // An implicit instantiation of a class template partial specialization
774     // uses ExplicitInfo to record the TypeAsWritten, but the source
775     // locations should be retrieved from the instantiation pattern.
776     typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
777     CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
778     CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
779     assert(inst_from != nullptr);
780     return inst_from->getSourceRange();
781   }
782   else {
783     // No explicit info available.
784     llvm::PointerUnion<ClassTemplateDecl *,
785                        ClassTemplatePartialSpecializationDecl *>
786       inst_from = getInstantiatedFrom();
787     if (inst_from.isNull())
788       return getSpecializedTemplate()->getSourceRange();
789     if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>())
790       return ctd->getSourceRange();
791     return inst_from.get<ClassTemplatePartialSpecializationDecl*>()
792       ->getSourceRange();
793   }
794 }
795 
796 //===----------------------------------------------------------------------===//
797 // ClassTemplatePartialSpecializationDecl Implementation
798 //===----------------------------------------------------------------------===//
anchor()799 void ClassTemplatePartialSpecializationDecl::anchor() { }
800 
801 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)802 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
803                                        DeclContext *DC,
804                                        SourceLocation StartLoc,
805                                        SourceLocation IdLoc,
806                                        TemplateParameterList *Params,
807                                        ClassTemplateDecl *SpecializedTemplate,
808                                        const TemplateArgument *Args,
809                                        unsigned NumArgs,
810                                const ASTTemplateArgumentListInfo *ArgInfos,
811                                ClassTemplatePartialSpecializationDecl *PrevDecl)
812   : ClassTemplateSpecializationDecl(Context,
813                                     ClassTemplatePartialSpecialization,
814                                     TK, DC, StartLoc, IdLoc,
815                                     SpecializedTemplate,
816                                     Args, NumArgs, PrevDecl),
817     TemplateParams(Params), ArgsAsWritten(ArgInfos),
818     InstantiatedFromMember(nullptr, false)
819 {
820   AdoptTemplateParameterList(Params, this);
821 }
822 
823 ClassTemplatePartialSpecializationDecl *
824 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)825 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
826        SourceLocation StartLoc, SourceLocation IdLoc,
827        TemplateParameterList *Params,
828        ClassTemplateDecl *SpecializedTemplate,
829        const TemplateArgument *Args,
830        unsigned NumArgs,
831        const TemplateArgumentListInfo &ArgInfos,
832        QualType CanonInjectedType,
833        ClassTemplatePartialSpecializationDecl *PrevDecl) {
834   const ASTTemplateArgumentListInfo *ASTArgInfos =
835     ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
836 
837   ClassTemplatePartialSpecializationDecl *Result = new (Context, DC)
838       ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
839                                              Params, SpecializedTemplate, Args,
840                                              NumArgs, ASTArgInfos, PrevDecl);
841   Result->setSpecializationKind(TSK_ExplicitSpecialization);
842   Result->MayHaveOutOfDateDef = false;
843 
844   Context.getInjectedClassNameType(Result, CanonInjectedType);
845   return Result;
846 }
847 
848 ClassTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)849 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
850                                                            unsigned ID) {
851   ClassTemplatePartialSpecializationDecl *Result =
852       new (C, ID) ClassTemplatePartialSpecializationDecl(C);
853   Result->MayHaveOutOfDateDef = false;
854   return Result;
855 }
856 
857 //===----------------------------------------------------------------------===//
858 // FriendTemplateDecl Implementation
859 //===----------------------------------------------------------------------===//
860 
anchor()861 void FriendTemplateDecl::anchor() { }
862 
Create(ASTContext & Context,DeclContext * DC,SourceLocation L,unsigned NParams,TemplateParameterList ** Params,FriendUnion Friend,SourceLocation FLoc)863 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
864                                                DeclContext *DC,
865                                                SourceLocation L,
866                                                unsigned NParams,
867                                                TemplateParameterList **Params,
868                                                FriendUnion Friend,
869                                                SourceLocation FLoc) {
870   return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params,
871                                               Friend, FLoc);
872 }
873 
CreateDeserialized(ASTContext & C,unsigned ID)874 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C,
875                                                            unsigned ID) {
876   return new (C, ID) FriendTemplateDecl(EmptyShell());
877 }
878 
879 //===----------------------------------------------------------------------===//
880 // TypeAliasTemplateDecl Implementation
881 //===----------------------------------------------------------------------===//
882 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)883 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
884                                                      DeclContext *DC,
885                                                      SourceLocation L,
886                                                      DeclarationName Name,
887                                                   TemplateParameterList *Params,
888                                                      NamedDecl *Decl) {
889   AdoptTemplateParameterList(Params, DC);
890   return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl);
891 }
892 
CreateDeserialized(ASTContext & C,unsigned ID)893 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C,
894                                                                  unsigned ID) {
895   return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(),
896                                            DeclarationName(), nullptr, nullptr);
897 }
898 
DeallocateCommon(void * Ptr)899 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
900   static_cast<Common *>(Ptr)->~Common();
901 }
902 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const903 TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
904   Common *CommonPtr = new (C) Common;
905   C.AddDeallocation(DeallocateCommon, CommonPtr);
906   return CommonPtr;
907 }
908 
909 //===----------------------------------------------------------------------===//
910 // ClassScopeFunctionSpecializationDecl Implementation
911 //===----------------------------------------------------------------------===//
912 
anchor()913 void ClassScopeFunctionSpecializationDecl::anchor() { }
914 
915 ClassScopeFunctionSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)916 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
917                                                          unsigned ID) {
918   return new (C, ID) ClassScopeFunctionSpecializationDecl(
919       nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo());
920 }
921 
922 //===----------------------------------------------------------------------===//
923 // VarTemplateDecl Implementation
924 //===----------------------------------------------------------------------===//
925 
DeallocateCommon(void * Ptr)926 void VarTemplateDecl::DeallocateCommon(void *Ptr) {
927   static_cast<Common *>(Ptr)->~Common();
928 }
929 
getDefinition()930 VarTemplateDecl *VarTemplateDecl::getDefinition() {
931   VarTemplateDecl *CurD = this;
932   while (CurD) {
933     if (CurD->isThisDeclarationADefinition())
934       return CurD;
935     CurD = CurD->getPreviousDecl();
936   }
937   return nullptr;
938 }
939 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,VarDecl * Decl)940 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
941                                          SourceLocation L, DeclarationName Name,
942                                          TemplateParameterList *Params,
943                                          VarDecl *Decl) {
944   return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl);
945 }
946 
CreateDeserialized(ASTContext & C,unsigned ID)947 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
948                                                      unsigned ID) {
949   return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(),
950                                      DeclarationName(), nullptr, nullptr);
951 }
952 
953 // TODO: Unify across class, function and variable templates?
954 //       May require moving this and Common to RedeclarableTemplateDecl.
LoadLazySpecializations() const955 void VarTemplateDecl::LoadLazySpecializations() const {
956   Common *CommonPtr = getCommonPtr();
957   if (CommonPtr->LazySpecializations) {
958     ASTContext &Context = getASTContext();
959     uint32_t *Specs = CommonPtr->LazySpecializations;
960     CommonPtr->LazySpecializations = nullptr;
961     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
962       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
963   }
964 }
965 
966 llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
getSpecializations() const967 VarTemplateDecl::getSpecializations() const {
968   LoadLazySpecializations();
969   return getCommonPtr()->Specializations;
970 }
971 
972 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations()973 VarTemplateDecl::getPartialSpecializations() {
974   LoadLazySpecializations();
975   return getCommonPtr()->PartialSpecializations;
976 }
977 
978 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C) const979 VarTemplateDecl::newCommon(ASTContext &C) const {
980   Common *CommonPtr = new (C) Common;
981   C.AddDeallocation(DeallocateCommon, CommonPtr);
982   return CommonPtr;
983 }
984 
985 VarTemplateSpecializationDecl *
findSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)986 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
987                                     void *&InsertPos) {
988   return findSpecializationImpl(getSpecializations(), Args, InsertPos);
989 }
990 
AddSpecialization(VarTemplateSpecializationDecl * D,void * InsertPos)991 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
992                                         void *InsertPos) {
993   if (InsertPos)
994     getSpecializations().InsertNode(D, InsertPos);
995   else {
996     VarTemplateSpecializationDecl *Existing =
997         getSpecializations().GetOrInsertNode(D);
998     (void)Existing;
999     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1000   }
1001   if (ASTMutationListener *L = getASTMutationListener())
1002     L->AddedCXXTemplateSpecialization(this, D);
1003 }
1004 
1005 VarTemplatePartialSpecializationDecl *
findPartialSpecialization(ArrayRef<TemplateArgument> Args,void * & InsertPos)1006 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args,
1007                                            void *&InsertPos) {
1008   return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos);
1009 }
1010 
AddPartialSpecialization(VarTemplatePartialSpecializationDecl * D,void * InsertPos)1011 void VarTemplateDecl::AddPartialSpecialization(
1012     VarTemplatePartialSpecializationDecl *D, void *InsertPos) {
1013   if (InsertPos)
1014     getPartialSpecializations().InsertNode(D, InsertPos);
1015   else {
1016     VarTemplatePartialSpecializationDecl *Existing =
1017         getPartialSpecializations().GetOrInsertNode(D);
1018     (void)Existing;
1019     assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
1020   }
1021 
1022   if (ASTMutationListener *L = getASTMutationListener())
1023     L->AddedCXXTemplateSpecialization(this, D);
1024 }
1025 
getPartialSpecializations(SmallVectorImpl<VarTemplatePartialSpecializationDecl * > & PS)1026 void VarTemplateDecl::getPartialSpecializations(
1027     SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) {
1028   llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs =
1029       getPartialSpecializations();
1030   PS.clear();
1031   PS.reserve(PartialSpecs.size());
1032   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1033            P = PartialSpecs.begin(),
1034            PEnd = PartialSpecs.end();
1035        P != PEnd; ++P)
1036     PS.push_back(P->getMostRecentDecl());
1037 }
1038 
1039 VarTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(VarTemplatePartialSpecializationDecl * D)1040 VarTemplateDecl::findPartialSpecInstantiatedFromMember(
1041     VarTemplatePartialSpecializationDecl *D) {
1042   Decl *DCanon = D->getCanonicalDecl();
1043   for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator
1044            P = getPartialSpecializations().begin(),
1045            PEnd = getPartialSpecializations().end();
1046        P != PEnd; ++P) {
1047     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
1048       return P->getMostRecentDecl();
1049   }
1050 
1051   return nullptr;
1052 }
1053 
1054 //===----------------------------------------------------------------------===//
1055 // VarTemplateSpecializationDecl Implementation
1056 //===----------------------------------------------------------------------===//
VarTemplateSpecializationDecl(Kind DK,ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,const TemplateArgument * Args,unsigned NumArgs)1057 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
1058     Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1059     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1060     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1061     unsigned NumArgs)
1062     : VarDecl(DK, Context, DC, StartLoc, IdLoc,
1063               SpecializedTemplate->getIdentifier(), T, TInfo, S),
1064       SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
1065       TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
1066       SpecializationKind(TSK_Undeclared) {}
1067 
VarTemplateSpecializationDecl(Kind DK,ASTContext & C)1068 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
1069                                                              ASTContext &C)
1070     : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
1071               QualType(), nullptr, SC_None),
1072       ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
1073 
Create(ASTContext & Context,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,VarTemplateDecl * SpecializedTemplate,QualType T,TypeSourceInfo * TInfo,StorageClass S,const TemplateArgument * Args,unsigned NumArgs)1074 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
1075     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1076     SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
1077     TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
1078     unsigned NumArgs) {
1079   return new (Context, DC) VarTemplateSpecializationDecl(
1080       VarTemplateSpecialization, Context, DC, StartLoc, IdLoc,
1081       SpecializedTemplate, T, TInfo, S, Args, NumArgs);
1082 }
1083 
1084 VarTemplateSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1085 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
1086   return new (C, ID)
1087       VarTemplateSpecializationDecl(VarTemplateSpecialization, C);
1088 }
1089 
getNameForDiagnostic(raw_ostream & OS,const PrintingPolicy & Policy,bool Qualified) const1090 void VarTemplateSpecializationDecl::getNameForDiagnostic(
1091     raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const {
1092   NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
1093 
1094   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
1095   TemplateSpecializationType::PrintTemplateArgumentList(
1096       OS, TemplateArgs.data(), TemplateArgs.size(), Policy);
1097 }
1098 
getSpecializedTemplate() const1099 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
1100   if (SpecializedPartialSpecialization *PartialSpec =
1101           SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1102     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1103   return SpecializedTemplate.get<VarTemplateDecl *>();
1104 }
1105 
setTemplateArgsInfo(const TemplateArgumentListInfo & ArgsInfo)1106 void VarTemplateSpecializationDecl::setTemplateArgsInfo(
1107     const TemplateArgumentListInfo &ArgsInfo) {
1108   unsigned N = ArgsInfo.size();
1109   TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
1110   TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
1111   for (unsigned I = 0; I != N; ++I)
1112     TemplateArgsInfo.addArgument(ArgsInfo[I]);
1113 }
1114 
1115 //===----------------------------------------------------------------------===//
1116 // VarTemplatePartialSpecializationDecl Implementation
1117 //===----------------------------------------------------------------------===//
anchor()1118 void VarTemplatePartialSpecializationDecl::anchor() {}
1119 
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)1120 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
1121     ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
1122     SourceLocation IdLoc, TemplateParameterList *Params,
1123     VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
1124     StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
1125     const ASTTemplateArgumentListInfo *ArgInfos)
1126     : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
1127                                     DC, StartLoc, IdLoc, SpecializedTemplate, T,
1128                                     TInfo, S, Args, NumArgs),
1129       TemplateParams(Params), ArgsAsWritten(ArgInfos),
1130       InstantiatedFromMember(nullptr, false) {
1131   // TODO: The template parameters should be in DC by now. Verify.
1132   // AdoptTemplateParameterList(Params, DC);
1133 }
1134 
1135 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)1136 VarTemplatePartialSpecializationDecl::Create(
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 TemplateArgumentListInfo &ArgInfos) {
1142   const ASTTemplateArgumentListInfo *ASTArgInfos
1143     = ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
1144 
1145   VarTemplatePartialSpecializationDecl *Result =
1146       new (Context, DC) VarTemplatePartialSpecializationDecl(
1147           Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
1148           S, Args, NumArgs, ASTArgInfos);
1149   Result->setSpecializationKind(TSK_ExplicitSpecialization);
1150   return Result;
1151 }
1152 
1153 VarTemplatePartialSpecializationDecl *
CreateDeserialized(ASTContext & C,unsigned ID)1154 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
1155                                                          unsigned ID) {
1156   return new (C, ID) VarTemplatePartialSpecializationDecl(C);
1157 }
1158