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