• 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/DeclCXX.h"
15 #include "clang/AST/DeclTemplate.h"
16 #include "clang/AST/Expr.h"
17 #include "clang/AST/ExprCXX.h"
18 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/TypeLoc.h"
20 #include "clang/AST/ASTMutationListener.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) {
36   for (unsigned Idx = 0; Idx < NumParams; ++Idx)
37     begin()[Idx] = Params[Idx];
38 }
39 
40 TemplateParameterList *
Create(const ASTContext & C,SourceLocation TemplateLoc,SourceLocation LAngleLoc,NamedDecl ** Params,unsigned NumParams,SourceLocation RAngleLoc)41 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc,
42                               SourceLocation LAngleLoc, NamedDecl **Params,
43                               unsigned NumParams, SourceLocation RAngleLoc) {
44   unsigned Size = sizeof(TemplateParameterList)
45                 + sizeof(NamedDecl *) * NumParams;
46   unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
47   void *Mem = C.Allocate(Size, Align);
48   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
49                                          NumParams, RAngleLoc);
50 }
51 
getMinRequiredArguments() const52 unsigned TemplateParameterList::getMinRequiredArguments() const {
53   unsigned NumRequiredArgs = 0;
54   for (iterator P = const_cast<TemplateParameterList *>(this)->begin(),
55              PEnd = const_cast<TemplateParameterList *>(this)->end();
56        P != PEnd; ++P) {
57     if ((*P)->isTemplateParameterPack()) {
58       if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P))
59         if (NTTP->isExpandedParameterPack()) {
60           NumRequiredArgs += NTTP->getNumExpansionTypes();
61           continue;
62         }
63 
64       break;
65     }
66 
67     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
68       if (TTP->hasDefaultArgument())
69         break;
70     } else if (NonTypeTemplateParmDecl *NTTP
71                                     = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
72       if (NTTP->hasDefaultArgument())
73         break;
74     } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument())
75       break;
76 
77     ++NumRequiredArgs;
78   }
79 
80   return NumRequiredArgs;
81 }
82 
getDepth() const83 unsigned TemplateParameterList::getDepth() const {
84   if (size() == 0)
85     return 0;
86 
87   const NamedDecl *FirstParm = getParam(0);
88   if (const TemplateTypeParmDecl *TTP
89         = dyn_cast<TemplateTypeParmDecl>(FirstParm))
90     return TTP->getDepth();
91   else if (const NonTypeTemplateParmDecl *NTTP
92              = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
93     return NTTP->getDepth();
94   else
95     return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
96 }
97 
AdoptTemplateParameterList(TemplateParameterList * Params,DeclContext * Owner)98 static void AdoptTemplateParameterList(TemplateParameterList *Params,
99                                        DeclContext *Owner) {
100   for (TemplateParameterList::iterator P = Params->begin(),
101                                     PEnd = Params->end();
102        P != PEnd; ++P) {
103     (*P)->setDeclContext(Owner);
104 
105     if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P))
106       AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner);
107   }
108 }
109 
110 //===----------------------------------------------------------------------===//
111 // RedeclarableTemplateDecl Implementation
112 //===----------------------------------------------------------------------===//
113 
getCommonPtr()114 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() {
115   // Find the first declaration of this function template.
116   RedeclarableTemplateDecl *First = getCanonicalDecl();
117 
118   if (First->CommonOrPrev.isNull()) {
119     CommonBase *CommonPtr = First->newCommon(getASTContext());
120     First->CommonOrPrev = CommonPtr;
121     CommonPtr->Latest = First;
122   }
123   return First->CommonOrPrev.get<CommonBase*>();
124 }
125 
126 
getCanonicalDeclImpl()127 RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() {
128   RedeclarableTemplateDecl *Tmpl = this;
129   while (Tmpl->getPreviousDeclaration())
130     Tmpl = Tmpl->getPreviousDeclaration();
131   return Tmpl;
132 }
133 
setPreviousDeclarationImpl(RedeclarableTemplateDecl * Prev)134 void RedeclarableTemplateDecl::setPreviousDeclarationImpl(
135                                                RedeclarableTemplateDecl *Prev) {
136   if (Prev) {
137     CommonBase *Common = Prev->getCommonPtr();
138     Prev = Common->Latest;
139     Common->Latest = this;
140     CommonOrPrev = Prev;
141   } else {
142     assert(CommonOrPrev.is<CommonBase*>() && "Cannot reset TemplateDecl Prev");
143   }
144 }
145 
getNextRedeclaration()146 RedeclarableTemplateDecl *RedeclarableTemplateDecl::getNextRedeclaration() {
147   if (CommonOrPrev.is<RedeclarableTemplateDecl*>())
148     return CommonOrPrev.get<RedeclarableTemplateDecl*>();
149   CommonBase *Common = CommonOrPrev.get<CommonBase*>();
150   return Common ? Common->Latest : this;
151 }
152 
153 template <class EntryType>
154 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
findSpecializationImpl(llvm::FoldingSet<EntryType> & Specs,const TemplateArgument * Args,unsigned NumArgs,void * & InsertPos)155 RedeclarableTemplateDecl::findSpecializationImpl(
156                                  llvm::FoldingSet<EntryType> &Specs,
157                                  const TemplateArgument *Args, unsigned NumArgs,
158                                  void *&InsertPos) {
159   typedef SpecEntryTraits<EntryType> SETraits;
160   llvm::FoldingSetNodeID ID;
161   EntryType::Profile(ID,Args,NumArgs, getASTContext());
162   EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
163   return Entry ? SETraits::getMostRecentDeclaration(Entry) : 0;
164 }
165 
166 /// \brief Generate the injected template arguments for the given template
167 /// parameter list, e.g., for the injected-class-name of a class template.
GenerateInjectedTemplateArgs(ASTContext & Context,TemplateParameterList * Params,TemplateArgument * Args)168 static void GenerateInjectedTemplateArgs(ASTContext &Context,
169                                         TemplateParameterList *Params,
170                                          TemplateArgument *Args) {
171   for (TemplateParameterList::iterator Param = Params->begin(),
172                                     ParamEnd = Params->end();
173        Param != ParamEnd; ++Param) {
174     TemplateArgument Arg;
175     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
176       QualType ArgType = Context.getTypeDeclType(TTP);
177       if (TTP->isParameterPack())
178         ArgType = Context.getPackExpansionType(ArgType,
179                                                llvm::Optional<unsigned>());
180 
181       Arg = TemplateArgument(ArgType);
182     } else if (NonTypeTemplateParmDecl *NTTP =
183                dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
184       Expr *E = new (Context) DeclRefExpr(NTTP,
185                                   NTTP->getType().getNonLValueExprType(Context),
186                                   Expr::getValueKindForType(NTTP->getType()),
187                                           NTTP->getLocation());
188 
189       if (NTTP->isParameterPack())
190         E = new (Context) PackExpansionExpr(Context.DependentTy, E,
191                                             NTTP->getLocation(),
192                                             llvm::Optional<unsigned>());
193       Arg = TemplateArgument(E);
194     } else {
195       TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
196       if (TTP->isParameterPack())
197         Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>());
198       else
199         Arg = TemplateArgument(TemplateName(TTP));
200     }
201 
202     if ((*Param)->isTemplateParameterPack())
203       Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
204 
205     *Args++ = Arg;
206   }
207 }
208 
209 //===----------------------------------------------------------------------===//
210 // FunctionTemplateDecl Implementation
211 //===----------------------------------------------------------------------===//
212 
DeallocateCommon(void * Ptr)213 void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
214   static_cast<Common *>(Ptr)->~Common();
215 }
216 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)217 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
218                                                    DeclContext *DC,
219                                                    SourceLocation L,
220                                                    DeclarationName Name,
221                                                TemplateParameterList *Params,
222                                                    NamedDecl *Decl) {
223   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
224   return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
225 }
226 
Create(ASTContext & C,EmptyShell)227 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, EmptyShell) {
228   return new (C) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
229                                       0, 0);
230 }
231 
232 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C)233 FunctionTemplateDecl::newCommon(ASTContext &C) {
234   Common *CommonPtr = new (C) Common;
235   C.AddDeallocation(DeallocateCommon, CommonPtr);
236   return CommonPtr;
237 }
238 
239 FunctionDecl *
findSpecialization(const TemplateArgument * Args,unsigned NumArgs,void * & InsertPos)240 FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
241                                          unsigned NumArgs, void *&InsertPos) {
242   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
243 }
244 
addSpecialization(FunctionTemplateSpecializationInfo * Info,void * InsertPos)245 void FunctionTemplateDecl::addSpecialization(
246       FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
247   getSpecializations().InsertNode(Info, InsertPos);
248   if (ASTMutationListener *L = getASTMutationListener())
249     L->AddedCXXTemplateSpecialization(this, Info->Function);
250 }
251 
252 std::pair<const TemplateArgument *, unsigned>
getInjectedTemplateArgs()253 FunctionTemplateDecl::getInjectedTemplateArgs() {
254   TemplateParameterList *Params = getTemplateParameters();
255   Common *CommonPtr = getCommonPtr();
256   if (!CommonPtr->InjectedArgs) {
257     CommonPtr->InjectedArgs
258       = new (getASTContext()) TemplateArgument [Params->size()];
259     GenerateInjectedTemplateArgs(getASTContext(), Params,
260                                  CommonPtr->InjectedArgs);
261   }
262 
263   return std::make_pair(CommonPtr->InjectedArgs, Params->size());
264 }
265 
266 //===----------------------------------------------------------------------===//
267 // ClassTemplateDecl Implementation
268 //===----------------------------------------------------------------------===//
269 
DeallocateCommon(void * Ptr)270 void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
271   static_cast<Common *>(Ptr)->~Common();
272 }
273 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl,ClassTemplateDecl * PrevDecl)274 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
275                                              DeclContext *DC,
276                                              SourceLocation L,
277                                              DeclarationName Name,
278                                              TemplateParameterList *Params,
279                                              NamedDecl *Decl,
280                                              ClassTemplateDecl *PrevDecl) {
281   AdoptTemplateParameterList(Params, cast<DeclContext>(Decl));
282   ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
283   New->setPreviousDeclaration(PrevDecl);
284   return New;
285 }
286 
Create(ASTContext & C,EmptyShell Empty)287 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, EmptyShell Empty) {
288   return new (C) ClassTemplateDecl(Empty);
289 }
290 
LoadLazySpecializations()291 void ClassTemplateDecl::LoadLazySpecializations() {
292   Common *CommonPtr = getCommonPtr();
293   if (CommonPtr->LazySpecializations) {
294     ASTContext &Context = getASTContext();
295     uint32_t *Specs = CommonPtr->LazySpecializations;
296     CommonPtr->LazySpecializations = 0;
297     for (uint32_t I = 0, N = *Specs++; I != N; ++I)
298       (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
299   }
300 }
301 
302 llvm::FoldingSet<ClassTemplateSpecializationDecl> &
getSpecializations()303 ClassTemplateDecl::getSpecializations() {
304   LoadLazySpecializations();
305   return getCommonPtr()->Specializations;
306 }
307 
308 llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations()309 ClassTemplateDecl::getPartialSpecializations() {
310   LoadLazySpecializations();
311   return getCommonPtr()->PartialSpecializations;
312 }
313 
314 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C)315 ClassTemplateDecl::newCommon(ASTContext &C) {
316   Common *CommonPtr = new (C) Common;
317   C.AddDeallocation(DeallocateCommon, CommonPtr);
318   return CommonPtr;
319 }
320 
321 ClassTemplateSpecializationDecl *
findSpecialization(const TemplateArgument * Args,unsigned NumArgs,void * & InsertPos)322 ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
323                                       unsigned NumArgs, void *&InsertPos) {
324   return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
325 }
326 
AddSpecialization(ClassTemplateSpecializationDecl * D,void * InsertPos)327 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
328                                           void *InsertPos) {
329   getSpecializations().InsertNode(D, InsertPos);
330   if (ASTMutationListener *L = getASTMutationListener())
331     L->AddedCXXTemplateSpecialization(this, D);
332 }
333 
334 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(const TemplateArgument * Args,unsigned NumArgs,void * & InsertPos)335 ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
336                                              unsigned NumArgs,
337                                              void *&InsertPos) {
338   return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
339                                 InsertPos);
340 }
341 
AddPartialSpecialization(ClassTemplatePartialSpecializationDecl * D,void * InsertPos)342 void ClassTemplateDecl::AddPartialSpecialization(
343                                       ClassTemplatePartialSpecializationDecl *D,
344                                       void *InsertPos) {
345   getPartialSpecializations().InsertNode(D, InsertPos);
346   if (ASTMutationListener *L = getASTMutationListener())
347     L->AddedCXXTemplateSpecialization(this, D);
348 }
349 
getPartialSpecializations(llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl * > & PS)350 void ClassTemplateDecl::getPartialSpecializations(
351           llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
352   llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
353     = getPartialSpecializations();
354   PS.clear();
355   PS.resize(PartialSpecs.size());
356   for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
357        P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
358        P != PEnd; ++P) {
359     assert(!PS[P->getSequenceNumber()]);
360     PS[P->getSequenceNumber()] = P->getMostRecentDeclaration();
361   }
362 }
363 
364 ClassTemplatePartialSpecializationDecl *
findPartialSpecialization(QualType T)365 ClassTemplateDecl::findPartialSpecialization(QualType T) {
366   ASTContext &Context = getASTContext();
367   typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
368     partial_spec_iterator;
369   for (partial_spec_iterator P = getPartialSpecializations().begin(),
370                           PEnd = getPartialSpecializations().end();
371        P != PEnd; ++P) {
372     if (Context.hasSameType(P->getInjectedSpecializationType(), T))
373       return P->getMostRecentDeclaration();
374   }
375 
376   return 0;
377 }
378 
379 ClassTemplatePartialSpecializationDecl *
findPartialSpecInstantiatedFromMember(ClassTemplatePartialSpecializationDecl * D)380 ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
381                                     ClassTemplatePartialSpecializationDecl *D) {
382   Decl *DCanon = D->getCanonicalDecl();
383   for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
384             P = getPartialSpecializations().begin(),
385          PEnd = getPartialSpecializations().end();
386        P != PEnd; ++P) {
387     if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
388       return P->getMostRecentDeclaration();
389   }
390 
391   return 0;
392 }
393 
394 QualType
getInjectedClassNameSpecialization()395 ClassTemplateDecl::getInjectedClassNameSpecialization() {
396   Common *CommonPtr = getCommonPtr();
397   if (!CommonPtr->InjectedClassNameType.isNull())
398     return CommonPtr->InjectedClassNameType;
399 
400   // C++0x [temp.dep.type]p2:
401   //  The template argument list of a primary template is a template argument
402   //  list in which the nth template argument has the value of the nth template
403   //  parameter of the class template. If the nth template parameter is a
404   //  template parameter pack (14.5.3), the nth template argument is a pack
405   //  expansion (14.5.3) whose pattern is the name of the template parameter
406   //  pack.
407   ASTContext &Context = getASTContext();
408   TemplateParameterList *Params = getTemplateParameters();
409   llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
410   TemplateArgs.resize(Params->size());
411   GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data());
412   CommonPtr->InjectedClassNameType
413     = Context.getTemplateSpecializationType(TemplateName(this),
414                                             &TemplateArgs[0],
415                                             TemplateArgs.size());
416   return CommonPtr->InjectedClassNameType;
417 }
418 
419 //===----------------------------------------------------------------------===//
420 // TemplateTypeParm Allocation/Deallocation Method Implementations
421 //===----------------------------------------------------------------------===//
422 
423 TemplateTypeParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation KeyLoc,SourceLocation NameLoc,unsigned D,unsigned P,IdentifierInfo * Id,bool Typename,bool ParameterPack)424 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
425                              SourceLocation KeyLoc, SourceLocation NameLoc,
426                              unsigned D, unsigned P, IdentifierInfo *Id,
427                              bool Typename, bool ParameterPack) {
428   TemplateTypeParmDecl *TTPDecl =
429     new (C) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename);
430   QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl);
431   TTPDecl->TypeForDecl = TTPType.getTypePtr();
432   return TTPDecl;
433 }
434 
435 TemplateTypeParmDecl *
Create(const ASTContext & C,EmptyShell Empty)436 TemplateTypeParmDecl::Create(const ASTContext &C, EmptyShell Empty) {
437   return new (C) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
438                                       0, false);
439 }
440 
getDefaultArgumentLoc() const441 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
442   return hasDefaultArgument()
443     ? DefaultArgument->getTypeLoc().getBeginLoc()
444     : SourceLocation();
445 }
446 
getSourceRange() const447 SourceRange TemplateTypeParmDecl::getSourceRange() const {
448   if (hasDefaultArgument() && !defaultArgumentWasInherited())
449     return SourceRange(getLocStart(),
450                        DefaultArgument->getTypeLoc().getEndLoc());
451   else
452     return TypeDecl::getSourceRange();
453 }
454 
getDepth() const455 unsigned TemplateTypeParmDecl::getDepth() const {
456   return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
457 }
458 
getIndex() const459 unsigned TemplateTypeParmDecl::getIndex() const {
460   return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
461 }
462 
isParameterPack() const463 bool TemplateTypeParmDecl::isParameterPack() const {
464   return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
465 }
466 
467 //===----------------------------------------------------------------------===//
468 // NonTypeTemplateParmDecl Method Implementations
469 //===----------------------------------------------------------------------===//
470 
NonTypeTemplateParmDecl(DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,TypeSourceInfo * TInfo,const QualType * ExpandedTypes,unsigned NumExpandedTypes,TypeSourceInfo ** ExpandedTInfos)471 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
472                                                  SourceLocation StartLoc,
473                                                  SourceLocation IdLoc,
474                                                  unsigned D, unsigned P,
475                                                  IdentifierInfo *Id,
476                                                  QualType T,
477                                                  TypeSourceInfo *TInfo,
478                                                  const QualType *ExpandedTypes,
479                                                  unsigned NumExpandedTypes,
480                                                 TypeSourceInfo **ExpandedTInfos)
481   : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
482     TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
483     ParameterPack(true), ExpandedParameterPack(true),
484     NumExpandedTypes(NumExpandedTypes)
485 {
486   if (ExpandedTypes && ExpandedTInfos) {
487     void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
488     for (unsigned I = 0; I != NumExpandedTypes; ++I) {
489       TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
490       TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
491     }
492   }
493 }
494 
495 NonTypeTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,unsigned D,unsigned P,IdentifierInfo * Id,QualType T,bool ParameterPack,TypeSourceInfo * TInfo)496 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
497                                 SourceLocation StartLoc, SourceLocation IdLoc,
498                                 unsigned D, unsigned P, IdentifierInfo *Id,
499                                 QualType T, bool ParameterPack,
500                                 TypeSourceInfo *TInfo) {
501   return new (C) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id,
502                                          T, ParameterPack, TInfo);
503 }
504 
505 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)506 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
507                                 SourceLocation StartLoc, SourceLocation IdLoc,
508                                 unsigned D, unsigned P,
509                                 IdentifierInfo *Id, QualType T,
510                                 TypeSourceInfo *TInfo,
511                                 const QualType *ExpandedTypes,
512                                 unsigned NumExpandedTypes,
513                                 TypeSourceInfo **ExpandedTInfos) {
514   unsigned Size = sizeof(NonTypeTemplateParmDecl)
515                 + NumExpandedTypes * 2 * sizeof(void*);
516   void *Mem = C.Allocate(Size);
517   return new (Mem) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc,
518                                            D, P, Id, T, TInfo,
519                                            ExpandedTypes, NumExpandedTypes,
520                                            ExpandedTInfos);
521 }
522 
getSourceRange() const523 SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
524   if (hasDefaultArgument() && !defaultArgumentWasInherited())
525     return SourceRange(getOuterLocStart(),
526                        getDefaultArgument()->getSourceRange().getEnd());
527   return DeclaratorDecl::getSourceRange();
528 }
529 
getDefaultArgumentLoc() const530 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
531   return hasDefaultArgument()
532     ? getDefaultArgument()->getSourceRange().getBegin()
533     : SourceLocation();
534 }
535 
536 //===----------------------------------------------------------------------===//
537 // TemplateTemplateParmDecl Method Implementations
538 //===----------------------------------------------------------------------===//
539 
540 TemplateTemplateParmDecl *
Create(const ASTContext & C,DeclContext * DC,SourceLocation L,unsigned D,unsigned P,bool ParameterPack,IdentifierInfo * Id,TemplateParameterList * Params)541 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
542                                  SourceLocation L, unsigned D, unsigned P,
543                                  bool ParameterPack, IdentifierInfo *Id,
544                                  TemplateParameterList *Params) {
545   return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
546                                           Params);
547 }
548 
549 //===----------------------------------------------------------------------===//
550 // TemplateArgumentList Implementation
551 //===----------------------------------------------------------------------===//
552 TemplateArgumentList *
CreateCopy(ASTContext & Context,const TemplateArgument * Args,unsigned NumArgs)553 TemplateArgumentList::CreateCopy(ASTContext &Context,
554                                  const TemplateArgument *Args,
555                                  unsigned NumArgs) {
556   std::size_t Size = sizeof(TemplateArgumentList)
557                    + NumArgs * sizeof(TemplateArgument);
558   void *Mem = Context.Allocate(Size);
559   TemplateArgument *StoredArgs
560     = reinterpret_cast<TemplateArgument *>(
561                                 static_cast<TemplateArgumentList *>(Mem) + 1);
562   std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
563   return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
564 }
565 
566 //===----------------------------------------------------------------------===//
567 // ClassTemplateSpecializationDecl Implementation
568 //===----------------------------------------------------------------------===//
569 ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext & Context,Kind DK,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,const TemplateArgument * Args,unsigned NumArgs,ClassTemplateSpecializationDecl * PrevDecl)570 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
571                                 DeclContext *DC, SourceLocation StartLoc,
572                                 SourceLocation IdLoc,
573                                 ClassTemplateDecl *SpecializedTemplate,
574                                 const TemplateArgument *Args,
575                                 unsigned NumArgs,
576                                 ClassTemplateSpecializationDecl *PrevDecl)
577   : CXXRecordDecl(DK, TK, DC, StartLoc, IdLoc,
578                   SpecializedTemplate->getIdentifier(),
579                   PrevDecl),
580     SpecializedTemplate(SpecializedTemplate),
581     ExplicitInfo(0),
582     TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
583     SpecializationKind(TSK_Undeclared) {
584 }
585 
ClassTemplateSpecializationDecl(Kind DK)586 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
587   : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
588     ExplicitInfo(0),
589     SpecializationKind(TSK_Undeclared) {
590 }
591 
592 ClassTemplateSpecializationDecl *
Create(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,ClassTemplateDecl * SpecializedTemplate,const TemplateArgument * Args,unsigned NumArgs,ClassTemplateSpecializationDecl * PrevDecl)593 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
594                                         DeclContext *DC,
595                                         SourceLocation StartLoc,
596                                         SourceLocation IdLoc,
597                                         ClassTemplateDecl *SpecializedTemplate,
598                                         const TemplateArgument *Args,
599                                         unsigned NumArgs,
600                                    ClassTemplateSpecializationDecl *PrevDecl) {
601   ClassTemplateSpecializationDecl *Result
602     = new (Context)ClassTemplateSpecializationDecl(Context,
603                                                    ClassTemplateSpecialization,
604                                                    TK, DC, StartLoc, IdLoc,
605                                                    SpecializedTemplate,
606                                                    Args, NumArgs,
607                                                    PrevDecl);
608   Context.getTypeDeclType(Result, PrevDecl);
609   return Result;
610 }
611 
612 ClassTemplateSpecializationDecl *
Create(ASTContext & Context,EmptyShell Empty)613 ClassTemplateSpecializationDecl::Create(ASTContext &Context, EmptyShell Empty) {
614   return
615     new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
616 }
617 
618 void
getNameForDiagnostic(std::string & S,const PrintingPolicy & Policy,bool Qualified) const619 ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
620                                                   const PrintingPolicy &Policy,
621                                                       bool Qualified) const {
622   NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
623 
624   const TemplateArgumentList &TemplateArgs = getTemplateArgs();
625   S += TemplateSpecializationType::PrintTemplateArgumentList(
626                                                           TemplateArgs.data(),
627                                                           TemplateArgs.size(),
628                                                              Policy);
629 }
630 
631 ClassTemplateDecl *
getSpecializedTemplate() const632 ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
633   if (SpecializedPartialSpecialization *PartialSpec
634       = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
635     return PartialSpec->PartialSpecialization->getSpecializedTemplate();
636   return SpecializedTemplate.get<ClassTemplateDecl*>();
637 }
638 
639 SourceRange
getSourceRange() const640 ClassTemplateSpecializationDecl::getSourceRange() const {
641   if (!ExplicitInfo)
642     return SourceRange();
643   SourceLocation Begin = getExternLoc();
644   if (Begin.isInvalid())
645     Begin = getTemplateKeywordLoc();
646   SourceLocation End = getRBraceLoc();
647   if (End.isInvalid())
648     End = getTypeAsWritten()->getTypeLoc().getEndLoc();
649   return SourceRange(Begin, End);
650 }
651 
652 //===----------------------------------------------------------------------===//
653 // ClassTemplatePartialSpecializationDecl Implementation
654 //===----------------------------------------------------------------------===//
655 ClassTemplatePartialSpecializationDecl::
ClassTemplatePartialSpecializationDecl(ASTContext & Context,TagKind TK,DeclContext * DC,SourceLocation StartLoc,SourceLocation IdLoc,TemplateParameterList * Params,ClassTemplateDecl * SpecializedTemplate,const TemplateArgument * Args,unsigned NumArgs,TemplateArgumentLoc * ArgInfos,unsigned NumArgInfos,ClassTemplatePartialSpecializationDecl * PrevDecl,unsigned SequenceNumber)656 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
657                                        DeclContext *DC,
658                                        SourceLocation StartLoc,
659                                        SourceLocation IdLoc,
660                                        TemplateParameterList *Params,
661                                        ClassTemplateDecl *SpecializedTemplate,
662                                        const TemplateArgument *Args,
663                                        unsigned NumArgs,
664                                        TemplateArgumentLoc *ArgInfos,
665                                        unsigned NumArgInfos,
666                                ClassTemplatePartialSpecializationDecl *PrevDecl,
667                                        unsigned SequenceNumber)
668   : ClassTemplateSpecializationDecl(Context,
669                                     ClassTemplatePartialSpecialization,
670                                     TK, DC, StartLoc, IdLoc,
671                                     SpecializedTemplate,
672                                     Args, NumArgs, PrevDecl),
673     TemplateParams(Params), ArgsAsWritten(ArgInfos),
674     NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
675     InstantiatedFromMember(0, false)
676 {
677   AdoptTemplateParameterList(Params, this);
678 }
679 
680 ClassTemplatePartialSpecializationDecl *
681 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,unsigned SequenceNumber)682 Create(ASTContext &Context, TagKind TK,DeclContext *DC,
683        SourceLocation StartLoc, SourceLocation IdLoc,
684        TemplateParameterList *Params,
685        ClassTemplateDecl *SpecializedTemplate,
686        const TemplateArgument *Args,
687        unsigned NumArgs,
688        const TemplateArgumentListInfo &ArgInfos,
689        QualType CanonInjectedType,
690        ClassTemplatePartialSpecializationDecl *PrevDecl,
691        unsigned SequenceNumber) {
692   unsigned N = ArgInfos.size();
693   TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
694   for (unsigned I = 0; I != N; ++I)
695     ClonedArgs[I] = ArgInfos[I];
696 
697   ClassTemplatePartialSpecializationDecl *Result
698     = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
699                                                           StartLoc, IdLoc,
700                                                           Params,
701                                                           SpecializedTemplate,
702                                                           Args, NumArgs,
703                                                           ClonedArgs, N,
704                                                           PrevDecl,
705                                                           SequenceNumber);
706   Result->setSpecializationKind(TSK_ExplicitSpecialization);
707 
708   Context.getInjectedClassNameType(Result, CanonInjectedType);
709   return Result;
710 }
711 
712 ClassTemplatePartialSpecializationDecl *
Create(ASTContext & Context,EmptyShell Empty)713 ClassTemplatePartialSpecializationDecl::Create(ASTContext &Context,
714                                                EmptyShell Empty) {
715   return new (Context)ClassTemplatePartialSpecializationDecl();
716 }
717 
718 //===----------------------------------------------------------------------===//
719 // FriendTemplateDecl Implementation
720 //===----------------------------------------------------------------------===//
721 
Create(ASTContext & Context,DeclContext * DC,SourceLocation L,unsigned NParams,TemplateParameterList ** Params,FriendUnion Friend,SourceLocation FLoc)722 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
723                                                DeclContext *DC,
724                                                SourceLocation L,
725                                                unsigned NParams,
726                                                TemplateParameterList **Params,
727                                                FriendUnion Friend,
728                                                SourceLocation FLoc) {
729   FriendTemplateDecl *Result
730     = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
731   return Result;
732 }
733 
Create(ASTContext & Context,EmptyShell Empty)734 FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
735                                                EmptyShell Empty) {
736   return new (Context) FriendTemplateDecl(Empty);
737 }
738 
739 //===----------------------------------------------------------------------===//
740 // TypeAliasTemplateDecl Implementation
741 //===----------------------------------------------------------------------===//
742 
Create(ASTContext & C,DeclContext * DC,SourceLocation L,DeclarationName Name,TemplateParameterList * Params,NamedDecl * Decl)743 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
744                                                      DeclContext *DC,
745                                                      SourceLocation L,
746                                                      DeclarationName Name,
747                                                   TemplateParameterList *Params,
748                                                      NamedDecl *Decl) {
749   AdoptTemplateParameterList(Params, DC);
750   return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
751 }
752 
Create(ASTContext & C,EmptyShell)753 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
754                                                      EmptyShell) {
755   return new (C) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
756                                        0, 0);
757 }
758 
DeallocateCommon(void * Ptr)759 void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
760   static_cast<Common *>(Ptr)->~Common();
761 }
762 RedeclarableTemplateDecl::CommonBase *
newCommon(ASTContext & C)763 TypeAliasTemplateDecl::newCommon(ASTContext &C) {
764   Common *CommonPtr = new (C) Common;
765   C.AddDeallocation(DeallocateCommon, CommonPtr);
766   return CommonPtr;
767 }
768 
769