DeclTemplate.cpp revision ee4bfd412db491c489fc2ee74916edd73f9c618a
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
98//===----------------------------------------------------------------------===//
99// RedeclarableTemplateDecl Implementation
100//===----------------------------------------------------------------------===//
101
102RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() {
103  // Find the first declaration of this function template.
104  RedeclarableTemplateDecl *First = getCanonicalDecl();
105
106  if (First->CommonOrPrev.isNull()) {
107    CommonBase *CommonPtr = First->newCommon(getASTContext());
108    First->CommonOrPrev = CommonPtr;
109    CommonPtr->Latest = First;
110  }
111  return First->CommonOrPrev.get<CommonBase*>();
112}
113
114
115RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() {
116  RedeclarableTemplateDecl *Tmpl = this;
117  while (Tmpl->getPreviousDeclaration())
118    Tmpl = Tmpl->getPreviousDeclaration();
119  return Tmpl;
120}
121
122void RedeclarableTemplateDecl::setPreviousDeclarationImpl(
123                                               RedeclarableTemplateDecl *Prev) {
124  if (Prev) {
125    CommonBase *Common = Prev->getCommonPtr();
126    Prev = Common->Latest;
127    Common->Latest = this;
128    CommonOrPrev = Prev;
129  } else {
130    assert(CommonOrPrev.is<CommonBase*>() && "Cannot reset TemplateDecl Prev");
131  }
132}
133
134RedeclarableTemplateDecl *RedeclarableTemplateDecl::getNextRedeclaration() {
135  if (CommonOrPrev.is<RedeclarableTemplateDecl*>())
136    return CommonOrPrev.get<RedeclarableTemplateDecl*>();
137  CommonBase *Common = CommonOrPrev.get<CommonBase*>();
138  return Common ? Common->Latest : this;
139}
140
141template <class EntryType>
142typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
143RedeclarableTemplateDecl::findSpecializationImpl(
144                                 llvm::FoldingSet<EntryType> &Specs,
145                                 const TemplateArgument *Args, unsigned NumArgs,
146                                 void *&InsertPos) {
147  typedef SpecEntryTraits<EntryType> SETraits;
148  llvm::FoldingSetNodeID ID;
149  EntryType::Profile(ID,Args,NumArgs, getASTContext());
150  EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
151  return Entry ? SETraits::getMostRecentDeclaration(Entry) : 0;
152}
153
154//===----------------------------------------------------------------------===//
155// FunctionTemplateDecl Implementation
156//===----------------------------------------------------------------------===//
157
158void FunctionTemplateDecl::DeallocateCommon(void *Ptr) {
159  static_cast<Common *>(Ptr)->~Common();
160}
161
162FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
163                                                   DeclContext *DC,
164                                                   SourceLocation L,
165                                                   DeclarationName Name,
166                                               TemplateParameterList *Params,
167                                                   NamedDecl *Decl) {
168  return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
169}
170
171RedeclarableTemplateDecl::CommonBase *
172FunctionTemplateDecl::newCommon(ASTContext &C) {
173  Common *CommonPtr = new (C) Common;
174  C.AddDeallocation(DeallocateCommon, CommonPtr);
175  return CommonPtr;
176}
177
178FunctionDecl *
179FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args,
180                                         unsigned NumArgs, void *&InsertPos) {
181  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
182}
183
184//===----------------------------------------------------------------------===//
185// ClassTemplateDecl Implementation
186//===----------------------------------------------------------------------===//
187
188void ClassTemplateDecl::DeallocateCommon(void *Ptr) {
189  static_cast<Common *>(Ptr)->~Common();
190}
191
192ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
193                                             DeclContext *DC,
194                                             SourceLocation L,
195                                             DeclarationName Name,
196                                             TemplateParameterList *Params,
197                                             NamedDecl *Decl,
198                                             ClassTemplateDecl *PrevDecl) {
199  ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl);
200  New->setPreviousDeclaration(PrevDecl);
201  return New;
202}
203
204void ClassTemplateDecl::LoadLazySpecializations() {
205  Common *CommonPtr = getCommonPtr();
206  if (CommonPtr->LazySpecializations) {
207    ASTContext &Context = getASTContext();
208    uint32_t *Specs = CommonPtr->LazySpecializations;
209    CommonPtr->LazySpecializations = 0;
210    for (uint32_t I = 0, N = *Specs++; I != N; ++I)
211      (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
212  }
213}
214
215llvm::FoldingSet<ClassTemplateSpecializationDecl> &
216ClassTemplateDecl::getSpecializations() {
217  LoadLazySpecializations();
218  return getCommonPtr()->Specializations;
219}
220
221llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
222ClassTemplateDecl::getPartialSpecializations() {
223  LoadLazySpecializations();
224  return getCommonPtr()->PartialSpecializations;
225}
226
227RedeclarableTemplateDecl::CommonBase *
228ClassTemplateDecl::newCommon(ASTContext &C) {
229  Common *CommonPtr = new (C) Common;
230  C.AddDeallocation(DeallocateCommon, CommonPtr);
231  return CommonPtr;
232}
233
234ClassTemplateSpecializationDecl *
235ClassTemplateDecl::findSpecialization(const TemplateArgument *Args,
236                                      unsigned NumArgs, void *&InsertPos) {
237  return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos);
238}
239
240void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
241                                          void *InsertPos) {
242  getSpecializations().InsertNode(D, InsertPos);
243  if (ASTMutationListener *L = getASTMutationListener())
244    L->AddedCXXTemplateSpecialization(this, D);
245}
246
247ClassTemplatePartialSpecializationDecl *
248ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args,
249                                             unsigned NumArgs,
250                                             void *&InsertPos) {
251  return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs,
252                                InsertPos);
253}
254
255void ClassTemplateDecl::AddPartialSpecialization(
256                                      ClassTemplatePartialSpecializationDecl *D,
257                                      void *InsertPos) {
258  getPartialSpecializations().InsertNode(D, InsertPos);
259  if (ASTMutationListener *L = getASTMutationListener())
260    L->AddedCXXTemplateSpecialization(this, D);
261}
262
263void ClassTemplateDecl::getPartialSpecializations(
264          llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
265  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
266    = getPartialSpecializations();
267  PS.clear();
268  PS.resize(PartialSpecs.size());
269  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
270       P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
271       P != PEnd; ++P) {
272    assert(!PS[P->getSequenceNumber()]);
273    PS[P->getSequenceNumber()] = P->getMostRecentDeclaration();
274  }
275}
276
277ClassTemplatePartialSpecializationDecl *
278ClassTemplateDecl::findPartialSpecialization(QualType T) {
279  ASTContext &Context = getASTContext();
280  typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
281    partial_spec_iterator;
282  for (partial_spec_iterator P = getPartialSpecializations().begin(),
283                          PEnd = getPartialSpecializations().end();
284       P != PEnd; ++P) {
285    if (Context.hasSameType(P->getInjectedSpecializationType(), T))
286      return P->getMostRecentDeclaration();
287  }
288
289  return 0;
290}
291
292ClassTemplatePartialSpecializationDecl *
293ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
294                                    ClassTemplatePartialSpecializationDecl *D) {
295  Decl *DCanon = D->getCanonicalDecl();
296  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
297            P = getPartialSpecializations().begin(),
298         PEnd = getPartialSpecializations().end();
299       P != PEnd; ++P) {
300    if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
301      return P->getMostRecentDeclaration();
302  }
303
304  return 0;
305}
306
307QualType
308ClassTemplateDecl::getInjectedClassNameSpecialization() {
309  Common *CommonPtr = getCommonPtr();
310  if (!CommonPtr->InjectedClassNameType.isNull())
311    return CommonPtr->InjectedClassNameType;
312
313  // C++0x [temp.dep.type]p2:
314  //  The template argument list of a primary template is a template argument
315  //  list in which the nth template argument has the value of the nth template
316  //  parameter of the class template. If the nth template parameter is a
317  //  template parameter pack (14.5.3), the nth template argument is a pack
318  //  expansion (14.5.3) whose pattern is the name of the template parameter
319  //  pack.
320  ASTContext &Context = getASTContext();
321  TemplateParameterList *Params = getTemplateParameters();
322  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
323  TemplateArgs.reserve(Params->size());
324  for (TemplateParameterList::iterator Param = Params->begin(),
325                                    ParamEnd = Params->end();
326       Param != ParamEnd; ++Param) {
327    TemplateArgument Arg;
328    if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
329      QualType ArgType = Context.getTypeDeclType(TTP);
330      if (TTP->isParameterPack())
331        ArgType = Context.getPackExpansionType(ArgType,
332                                               llvm::Optional<unsigned>());
333
334      Arg = TemplateArgument(ArgType);
335    } else if (NonTypeTemplateParmDecl *NTTP =
336                 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
337      Expr *E = new (Context) DeclRefExpr(NTTP,
338                                  NTTP->getType().getNonLValueExprType(Context),
339                                  Expr::getValueKindForType(NTTP->getType()),
340                                          NTTP->getLocation());
341
342      if (NTTP->isParameterPack())
343        E = new (Context) PackExpansionExpr(Context.DependentTy, E,
344                                            NTTP->getLocation(),
345                                            llvm::Optional<unsigned>());
346      Arg = TemplateArgument(E);
347    } else {
348      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
349      if (TTP->isParameterPack())
350        Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>());
351      else
352        Arg = TemplateArgument(TemplateName(TTP));
353    }
354
355    if ((*Param)->isTemplateParameterPack())
356      Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1);
357
358    TemplateArgs.push_back(Arg);
359  }
360
361  CommonPtr->InjectedClassNameType
362    = Context.getTemplateSpecializationType(TemplateName(this),
363                                            &TemplateArgs[0],
364                                            TemplateArgs.size());
365  return CommonPtr->InjectedClassNameType;
366}
367
368//===----------------------------------------------------------------------===//
369// TemplateTypeParm Allocation/Deallocation Method Implementations
370//===----------------------------------------------------------------------===//
371
372TemplateTypeParmDecl *
373TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC,
374                             SourceLocation L, unsigned D, unsigned P,
375                             IdentifierInfo *Id, bool Typename,
376                             bool ParameterPack) {
377  QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
378  return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
379}
380
381TemplateTypeParmDecl *
382TemplateTypeParmDecl::Create(const ASTContext &C, EmptyShell Empty) {
383  return new (C) TemplateTypeParmDecl(0, SourceLocation(), 0, false,
384                                      QualType(), false);
385}
386
387SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
388  return DefaultArgument->getTypeLoc().getSourceRange().getBegin();
389}
390
391unsigned TemplateTypeParmDecl::getDepth() const {
392  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
393}
394
395unsigned TemplateTypeParmDecl::getIndex() const {
396  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
397}
398
399//===----------------------------------------------------------------------===//
400// NonTypeTemplateParmDecl Method Implementations
401//===----------------------------------------------------------------------===//
402
403NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC,
404                                                 SourceLocation L, unsigned D,
405                                                 unsigned P, IdentifierInfo *Id,
406                                                 QualType T,
407                                                 TypeSourceInfo *TInfo,
408                                                 const QualType *ExpandedTypes,
409                                                 unsigned NumExpandedTypes,
410                                                TypeSourceInfo **ExpandedTInfos)
411  : DeclaratorDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo),
412    TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
413    ParameterPack(true), ExpandedParameterPack(true),
414    NumExpandedTypes(NumExpandedTypes)
415{
416  if (ExpandedTypes && ExpandedTInfos) {
417    void **TypesAndInfos = reinterpret_cast<void **>(this + 1);
418    for (unsigned I = 0; I != NumExpandedTypes; ++I) {
419      TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr();
420      TypesAndInfos[2*I + 1] = ExpandedTInfos[I];
421    }
422  }
423}
424
425NonTypeTemplateParmDecl *
426NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
427                                SourceLocation L, unsigned D, unsigned P,
428                                IdentifierInfo *Id, QualType T,
429                                bool ParameterPack, TypeSourceInfo *TInfo) {
430  return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, ParameterPack,
431                                         TInfo);
432}
433
434NonTypeTemplateParmDecl *
435NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
436                                SourceLocation L, unsigned D, unsigned P,
437                                IdentifierInfo *Id, QualType T,
438                                TypeSourceInfo *TInfo,
439                                const QualType *ExpandedTypes,
440                                unsigned NumExpandedTypes,
441                                TypeSourceInfo **ExpandedTInfos) {
442  unsigned Size = sizeof(NonTypeTemplateParmDecl)
443                + NumExpandedTypes * 2 * sizeof(void*);
444  void *Mem = C.Allocate(Size);
445  return new (Mem) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo,
446                                           ExpandedTypes, NumExpandedTypes,
447                                           ExpandedTInfos);
448}
449
450SourceLocation NonTypeTemplateParmDecl::getInnerLocStart() const {
451  SourceLocation Start = getTypeSpecStartLoc();
452  if (Start.isInvalid())
453    Start = getLocation();
454  return Start;
455}
456
457SourceRange NonTypeTemplateParmDecl::getSourceRange() const {
458  SourceLocation End = getLocation();
459  if (hasDefaultArgument() && !defaultArgumentWasInherited())
460    End = getDefaultArgument()->getSourceRange().getEnd();
461  return SourceRange(getOuterLocStart(), End);
462}
463
464SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
465  return hasDefaultArgument()
466    ? getDefaultArgument()->getSourceRange().getBegin()
467    : SourceLocation();
468}
469
470//===----------------------------------------------------------------------===//
471// TemplateTemplateParmDecl Method Implementations
472//===----------------------------------------------------------------------===//
473
474TemplateTemplateParmDecl *
475TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC,
476                                 SourceLocation L, unsigned D, unsigned P,
477                                 bool ParameterPack, IdentifierInfo *Id,
478                                 TemplateParameterList *Params) {
479  return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id,
480                                          Params);
481}
482
483//===----------------------------------------------------------------------===//
484// TemplateArgumentList Implementation
485//===----------------------------------------------------------------------===//
486TemplateArgumentList *
487TemplateArgumentList::CreateCopy(ASTContext &Context,
488                                 const TemplateArgument *Args,
489                                 unsigned NumArgs) {
490  std::size_t Size = sizeof(TemplateArgumentList)
491                   + NumArgs * sizeof(TemplateArgument);
492  void *Mem = Context.Allocate(Size);
493  TemplateArgument *StoredArgs
494    = reinterpret_cast<TemplateArgument *>(
495                                static_cast<TemplateArgumentList *>(Mem) + 1);
496  std::uninitialized_copy(Args, Args + NumArgs, StoredArgs);
497  return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
498}
499
500//===----------------------------------------------------------------------===//
501// ClassTemplateSpecializationDecl Implementation
502//===----------------------------------------------------------------------===//
503ClassTemplateSpecializationDecl::
504ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
505                                DeclContext *DC, SourceLocation L,
506                                ClassTemplateDecl *SpecializedTemplate,
507                                const TemplateArgument *Args,
508                                unsigned NumArgs,
509                                ClassTemplateSpecializationDecl *PrevDecl)
510  : CXXRecordDecl(DK, TK, DC, L,
511                  SpecializedTemplate->getIdentifier(),
512                  PrevDecl),
513    SpecializedTemplate(SpecializedTemplate),
514    ExplicitInfo(0),
515    TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)),
516    SpecializationKind(TSK_Undeclared) {
517}
518
519ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
520  : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), 0, 0),
521    ExplicitInfo(0),
522    SpecializationKind(TSK_Undeclared) {
523}
524
525ClassTemplateSpecializationDecl *
526ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
527                                        DeclContext *DC, SourceLocation L,
528                                        ClassTemplateDecl *SpecializedTemplate,
529                                        const TemplateArgument *Args,
530                                        unsigned NumArgs,
531                                   ClassTemplateSpecializationDecl *PrevDecl) {
532  ClassTemplateSpecializationDecl *Result
533    = new (Context)ClassTemplateSpecializationDecl(Context,
534                                                   ClassTemplateSpecialization,
535                                                   TK, DC, L,
536                                                   SpecializedTemplate,
537                                                   Args, NumArgs,
538                                                   PrevDecl);
539  Context.getTypeDeclType(Result, PrevDecl);
540  return Result;
541}
542
543ClassTemplateSpecializationDecl *
544ClassTemplateSpecializationDecl::Create(ASTContext &Context, EmptyShell Empty) {
545  return
546    new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
547}
548
549void
550ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
551                                                  const PrintingPolicy &Policy,
552                                                      bool Qualified) const {
553  NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
554
555  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
556  S += TemplateSpecializationType::PrintTemplateArgumentList(
557                                                          TemplateArgs.data(),
558                                                          TemplateArgs.size(),
559                                                             Policy);
560}
561
562ClassTemplateDecl *
563ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
564  if (SpecializedPartialSpecialization *PartialSpec
565      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
566    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
567  return SpecializedTemplate.get<ClassTemplateDecl*>();
568}
569
570//===----------------------------------------------------------------------===//
571// ClassTemplatePartialSpecializationDecl Implementation
572//===----------------------------------------------------------------------===//
573ClassTemplatePartialSpecializationDecl *
574ClassTemplatePartialSpecializationDecl::
575Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
576       TemplateParameterList *Params,
577       ClassTemplateDecl *SpecializedTemplate,
578       const TemplateArgument *Args,
579       unsigned NumArgs,
580       const TemplateArgumentListInfo &ArgInfos,
581       QualType CanonInjectedType,
582       ClassTemplatePartialSpecializationDecl *PrevDecl,
583       unsigned SequenceNumber) {
584  unsigned N = ArgInfos.size();
585  TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
586  for (unsigned I = 0; I != N; ++I)
587    ClonedArgs[I] = ArgInfos[I];
588
589  ClassTemplatePartialSpecializationDecl *Result
590    = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK,
591                                                          DC, L, Params,
592                                                          SpecializedTemplate,
593                                                          Args, NumArgs,
594                                                          ClonedArgs, N,
595                                                          PrevDecl,
596                                                          SequenceNumber);
597  Result->setSpecializationKind(TSK_ExplicitSpecialization);
598
599  Context.getInjectedClassNameType(Result, CanonInjectedType);
600  return Result;
601}
602
603ClassTemplatePartialSpecializationDecl *
604ClassTemplatePartialSpecializationDecl::Create(ASTContext &Context,
605                                               EmptyShell Empty) {
606  return new (Context)ClassTemplatePartialSpecializationDecl();
607}
608
609//===----------------------------------------------------------------------===//
610// FriendTemplateDecl Implementation
611//===----------------------------------------------------------------------===//
612
613FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
614                                               DeclContext *DC,
615                                               SourceLocation L,
616                                               unsigned NParams,
617                                               TemplateParameterList **Params,
618                                               FriendUnion Friend,
619                                               SourceLocation FLoc) {
620  FriendTemplateDecl *Result
621    = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
622  return Result;
623}
624
625FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
626                                               EmptyShell Empty) {
627  return new (Context) FriendTemplateDecl(Empty);
628}
629