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