DeclTemplate.cpp revision 71a7605977113c795edd44fcbd2302ad49506653
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>
24using namespace clang;
25
26//===----------------------------------------------------------------------===//
27// TemplateParameterList Implementation
28//===----------------------------------------------------------------------===//
29
30TemplateParameterList::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
40TemplateParameterList *
41TemplateParameterList::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
52unsigned 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
83unsigned 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
98static 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
114RedeclarableTemplateDecl::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
127RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() {
128  RedeclarableTemplateDecl *Tmpl = this;
129  while (Tmpl->getPreviousDeclaration())
130    Tmpl = Tmpl->getPreviousDeclaration();
131  return Tmpl;
132}
133
134void 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
146RedeclarableTemplateDecl *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
153template <class EntryType>
154typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
155RedeclarableTemplateDecl::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.
168static 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
213void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
214  static_cast<Common *>(Ptr)->~Common();
215}
216
217FunctionTemplateDecl *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
227FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, EmptyShell) {
228  return new (C) FunctionTemplateDecl(0, SourceLocation(), DeclarationName(),
229                                      0, 0);
230}
231
232RedeclarableTemplateDecl::CommonBase *
233FunctionTemplateDecl::newCommon(ASTContext &C) {
234  Common *CommonPtr = new (C) Common;
235  C.AddDeallocation(DeallocateCommon, CommonPtr);
236  return CommonPtr;
237}
238
239FunctionDecl *
240FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
241                                         unsigned NumArgs, void *&InsertPos) {
242  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
243}
244
245void 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
252std::pair<const TemplateArgument *, unsigned>
253FunctionTemplateDecl::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
270void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
271  static_cast<Common *>(Ptr)->~Common();
272}
273
274ClassTemplateDecl *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
287ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, EmptyShell Empty) {
288  return new (C) ClassTemplateDecl(Empty);
289}
290
291void 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
302llvm::FoldingSet<ClassTemplateSpecializationDecl> &
303ClassTemplateDecl::getSpecializations() {
304  LoadLazySpecializations();
305  return getCommonPtr()->Specializations;
306}
307
308llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
309ClassTemplateDecl::getPartialSpecializations() {
310  LoadLazySpecializations();
311  return getCommonPtr()->PartialSpecializations;
312}
313
314RedeclarableTemplateDecl::CommonBase *
315ClassTemplateDecl::newCommon(ASTContext &C) {
316  Common *CommonPtr = new (C) Common;
317  C.AddDeallocation(DeallocateCommon, CommonPtr);
318  return CommonPtr;
319}
320
321ClassTemplateSpecializationDecl *
322ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
323                                      unsigned NumArgs, void *&InsertPos) {
324  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
325}
326
327void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
328                                          void *InsertPos) {
329  getSpecializations().InsertNode(D, InsertPos);
330  if (ASTMutationListener *L = getASTMutationListener())
331    L->AddedCXXTemplateSpecialization(this, D);
332}
333
334ClassTemplatePartialSpecializationDecl *
335ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
336                                             unsigned NumArgs,
337                                             void *&InsertPos) {
338  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
339                                InsertPos);
340}
341
342void 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
350void 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
364ClassTemplatePartialSpecializationDecl *
365ClassTemplateDecl::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
379ClassTemplatePartialSpecializationDecl *
380ClassTemplateDecl::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
394QualType
395ClassTemplateDecl::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
423TemplateTypeParmDecl *
424TemplateTypeParmDecl::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
435TemplateTypeParmDecl *
436TemplateTypeParmDecl::Create(const ASTContext &C, EmptyShell Empty) {
437  return new (C) TemplateTypeParmDecl(0, SourceLocation(), SourceLocation(),
438                                      0, false);
439}
440
441SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
442  return hasDefaultArgument()
443    ? DefaultArgument->getTypeLoc().getBeginLoc()
444    : SourceLocation();
445}
446
447SourceRange TemplateTypeParmDecl::getSourceRange() const {
448  if (hasDefaultArgument() && !defaultArgumentWasInherited())
449    return SourceRange(getLocStart(),
450                       DefaultArgument->getTypeLoc().getEndLoc());
451  else
452    return TypeDecl::getSourceRange();
453}
454
455unsigned TemplateTypeParmDecl::getDepth() const {
456  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
457}
458
459unsigned TemplateTypeParmDecl::getIndex() const {
460  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
461}
462
463bool TemplateTypeParmDecl::isParameterPack() const {
464  return TypeForDecl->getAs<TemplateTypeParmType>()->isParameterPack();
465}
466
467//===----------------------------------------------------------------------===//
468// NonTypeTemplateParmDecl Method Implementations
469//===----------------------------------------------------------------------===//
470
471NonTypeTemplateParmDecl::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
495NonTypeTemplateParmDecl *
496NonTypeTemplateParmDecl::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
505NonTypeTemplateParmDecl *
506NonTypeTemplateParmDecl::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
523SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
524  if (hasDefaultArgument() && !defaultArgumentWasInherited())
525    return SourceRange(getOuterLocStart(),
526                       getDefaultArgument()->getSourceRange().getEnd());
527  return DeclaratorDecl::getSourceRange();
528}
529
530SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
531  return hasDefaultArgument()
532    ? getDefaultArgument()->getSourceRange().getBegin()
533    : SourceLocation();
534}
535
536//===----------------------------------------------------------------------===//
537// TemplateTemplateParmDecl Method Implementations
538//===----------------------------------------------------------------------===//
539
540TemplateTemplateParmDecl *
541TemplateTemplateParmDecl::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//===----------------------------------------------------------------------===//
552TemplateArgumentList *
553TemplateArgumentList::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
566FunctionTemplateSpecializationInfo *
567FunctionTemplateSpecializationInfo::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//===----------------------------------------------------------------------===//
587ClassTemplateSpecializationDecl::
588ClassTemplateSpecializationDecl(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
604ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
605  : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), SourceLocation(), 0, 0),
606    ExplicitInfo(0),
607    SpecializationKind(TSK_Undeclared) {
608}
609
610ClassTemplateSpecializationDecl *
611ClassTemplateSpecializationDecl::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
630ClassTemplateSpecializationDecl *
631ClassTemplateSpecializationDecl::Create(ASTContext &Context, EmptyShell Empty) {
632  return
633    new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
634}
635
636void
637ClassTemplateSpecializationDecl::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
649ClassTemplateDecl *
650ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
651  if (SpecializedPartialSpecialization *PartialSpec
652      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
653    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
654  return SpecializedTemplate.get<ClassTemplateDecl*>();
655}
656
657SourceRange
658ClassTemplateSpecializationDecl::getSourceRange() const {
659  if (!ExplicitInfo)
660    return SourceRange();
661  SourceLocation Begin = getExternLoc();
662  if (Begin.isInvalid())
663    Begin = getTemplateKeywordLoc();
664  SourceLocation End = getRBraceLoc();
665  if (End.isInvalid())
666    End = getTypeAsWritten()->getTypeLoc().getEndLoc();
667  return SourceRange(Begin, End);
668}
669
670//===----------------------------------------------------------------------===//
671// ClassTemplatePartialSpecializationDecl Implementation
672//===----------------------------------------------------------------------===//
673ClassTemplatePartialSpecializationDecl::
674ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
675                                       DeclContext *DC,
676                                       SourceLocation StartLoc,
677                                       SourceLocation IdLoc,
678                                       TemplateParameterList *Params,
679                                       ClassTemplateDecl *SpecializedTemplate,
680                                       const TemplateArgument *Args,
681                                       unsigned NumArgs,
682                                       TemplateArgumentLoc *ArgInfos,
683                                       unsigned NumArgInfos,
684                               ClassTemplatePartialSpecializationDecl *PrevDecl,
685                                       unsigned SequenceNumber)
686  : ClassTemplateSpecializationDecl(Context,
687                                    ClassTemplatePartialSpecialization,
688                                    TK, DC, StartLoc, IdLoc,
689                                    SpecializedTemplate,
690                                    Args, NumArgs, PrevDecl),
691    TemplateParams(Params), ArgsAsWritten(ArgInfos),
692    NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
693    InstantiatedFromMember(0, false)
694{
695  AdoptTemplateParameterList(Params, this);
696}
697
698ClassTemplatePartialSpecializationDecl *
699ClassTemplatePartialSpecializationDecl::
700Create(ASTContext &Context, TagKind TK,DeclContext *DC,
701       SourceLocation StartLoc, SourceLocation IdLoc,
702       TemplateParameterList *Params,
703       ClassTemplateDecl *SpecializedTemplate,
704       const TemplateArgument *Args,
705       unsigned NumArgs,
706       const TemplateArgumentListInfo &ArgInfos,
707       QualType CanonInjectedType,
708       ClassTemplatePartialSpecializationDecl *PrevDecl,
709       unsigned SequenceNumber) {
710  unsigned N = ArgInfos.size();
711  TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
712  for (unsigned I = 0; I != N; ++I)
713    ClonedArgs[I] = ArgInfos[I];
714
715  ClassTemplatePartialSpecializationDecl *Result
716    = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC,
717                                                          StartLoc, IdLoc,
718                                                          Params,
719                                                          SpecializedTemplate,
720                                                          Args, NumArgs,
721                                                          ClonedArgs, N,
722                                                          PrevDecl,
723                                                          SequenceNumber);
724  Result->setSpecializationKind(TSK_ExplicitSpecialization);
725
726  Context.getInjectedClassNameType(Result, CanonInjectedType);
727  return Result;
728}
729
730ClassTemplatePartialSpecializationDecl *
731ClassTemplatePartialSpecializationDecl::Create(ASTContext &Context,
732                                               EmptyShell Empty) {
733  return new (Context)ClassTemplatePartialSpecializationDecl();
734}
735
736//===----------------------------------------------------------------------===//
737// FriendTemplateDecl Implementation
738//===----------------------------------------------------------------------===//
739
740FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
741                                               DeclContext *DC,
742                                               SourceLocation L,
743                                               unsigned NParams,
744                                               TemplateParameterList **Params,
745                                               FriendUnion Friend,
746                                               SourceLocation FLoc) {
747  FriendTemplateDecl *Result
748    = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
749  return Result;
750}
751
752FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
753                                               EmptyShell Empty) {
754  return new (Context) FriendTemplateDecl(Empty);
755}
756
757//===----------------------------------------------------------------------===//
758// TypeAliasTemplateDecl Implementation
759//===----------------------------------------------------------------------===//
760
761TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
762                                                     DeclContext *DC,
763                                                     SourceLocation L,
764                                                     DeclarationName Name,
765                                                  TemplateParameterList *Params,
766                                                     NamedDecl *Decl) {
767  AdoptTemplateParameterList(Params, DC);
768  return new (C) TypeAliasTemplateDecl(DC, L, Name, Params, Decl);
769}
770
771TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C,
772                                                     EmptyShell) {
773  return new (C) TypeAliasTemplateDecl(0, SourceLocation(), DeclarationName(),
774                                       0, 0);
775}
776
777void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) {
778  static_cast<Common *>(Ptr)->~Common();
779}
780RedeclarableTemplateDecl::CommonBase *
781TypeAliasTemplateDecl::newCommon(ASTContext &C) {
782  Common *CommonPtr = new (C) Common;
783  C.AddDeallocation(DeallocateCommon, CommonPtr);
784  return CommonPtr;
785}
786
787