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