DeclTemplate.cpp revision 207619
1198893Srdivacky//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements the C++ related Decl classes for templates.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/AST/DeclCXX.h"
15193326Sed#include "clang/AST/DeclTemplate.h"
16193326Sed#include "clang/AST/Expr.h"
17193326Sed#include "clang/AST/ASTContext.h"
18198893Srdivacky#include "clang/AST/TypeLoc.h"
19193326Sed#include "clang/Basic/IdentifierTable.h"
20193326Sed#include "llvm/ADT/STLExtras.h"
21193326Sedusing namespace clang;
22193326Sed
23193326Sed//===----------------------------------------------------------------------===//
24193326Sed// TemplateParameterList Implementation
25193326Sed//===----------------------------------------------------------------------===//
26193326Sed
27193326SedTemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
28193326Sed                                             SourceLocation LAngleLoc,
29198092Srdivacky                                             NamedDecl **Params, unsigned NumParams,
30193326Sed                                             SourceLocation RAngleLoc)
31193326Sed  : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
32193326Sed    NumParams(NumParams) {
33193326Sed  for (unsigned Idx = 0; Idx < NumParams; ++Idx)
34193326Sed    begin()[Idx] = Params[Idx];
35193326Sed}
36193326Sed
37193326SedTemplateParameterList *
38193326SedTemplateParameterList::Create(ASTContext &C, SourceLocation TemplateLoc,
39198092Srdivacky                              SourceLocation LAngleLoc, NamedDecl **Params,
40193326Sed                              unsigned NumParams, SourceLocation RAngleLoc) {
41198092Srdivacky  unsigned Size = sizeof(TemplateParameterList)
42198092Srdivacky                + sizeof(NamedDecl *) * NumParams;
43193326Sed  unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
44193326Sed  void *Mem = C.Allocate(Size, Align);
45198092Srdivacky  return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
46193326Sed                                         NumParams, RAngleLoc);
47193326Sed}
48193326Sed
49193326Sedunsigned TemplateParameterList::getMinRequiredArguments() const {
50193326Sed  unsigned NumRequiredArgs = size();
51198092Srdivacky  iterator Param = const_cast<TemplateParameterList *>(this)->end(),
52193326Sed      ParamBegin = const_cast<TemplateParameterList *>(this)->begin();
53193326Sed  while (Param != ParamBegin) {
54193326Sed    --Param;
55198092Srdivacky
56194179Sed    if (!(*Param)->isTemplateParameterPack() &&
57198092Srdivacky        !(isa<TemplateTypeParmDecl>(*Param) &&
58193326Sed          cast<TemplateTypeParmDecl>(*Param)->hasDefaultArgument()) &&
59193326Sed        !(isa<NonTypeTemplateParmDecl>(*Param) &&
60193326Sed          cast<NonTypeTemplateParmDecl>(*Param)->hasDefaultArgument()) &&
61193326Sed        !(isa<TemplateTemplateParmDecl>(*Param) &&
62193326Sed          cast<TemplateTemplateParmDecl>(*Param)->hasDefaultArgument()))
63193326Sed      break;
64198092Srdivacky
65193326Sed    --NumRequiredArgs;
66193326Sed  }
67193326Sed
68193326Sed  return NumRequiredArgs;
69193326Sed}
70193326Sed
71198893Srdivackyunsigned TemplateParameterList::getDepth() const {
72198893Srdivacky  if (size() == 0)
73198893Srdivacky    return 0;
74198893Srdivacky
75198893Srdivacky  const NamedDecl *FirstParm = getParam(0);
76198893Srdivacky  if (const TemplateTypeParmDecl *TTP
77198893Srdivacky        = dyn_cast<TemplateTypeParmDecl>(FirstParm))
78198893Srdivacky    return TTP->getDepth();
79198893Srdivacky  else if (const NonTypeTemplateParmDecl *NTTP
80198893Srdivacky             = dyn_cast<NonTypeTemplateParmDecl>(FirstParm))
81198893Srdivacky    return NTTP->getDepth();
82198893Srdivacky  else
83198893Srdivacky    return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth();
84198893Srdivacky}
85198893Srdivacky
86193326Sed//===----------------------------------------------------------------------===//
87193326Sed// TemplateDecl Implementation
88193326Sed//===----------------------------------------------------------------------===//
89193326Sed
90193326SedTemplateDecl::~TemplateDecl() {
91193326Sed}
92193326Sed
93193326Sed//===----------------------------------------------------------------------===//
94193326Sed// FunctionTemplateDecl Implementation
95193326Sed//===----------------------------------------------------------------------===//
96193326Sed
97193326SedFunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
98193326Sed                                                   DeclContext *DC,
99193326Sed                                                   SourceLocation L,
100193326Sed                                                   DeclarationName Name,
101195341Sed                                               TemplateParameterList *Params,
102193326Sed                                                   NamedDecl *Decl) {
103193326Sed  return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
104193326Sed}
105193326Sed
106195341Sedvoid FunctionTemplateDecl::Destroy(ASTContext &C) {
107195341Sed  if (Common *CommonPtr = CommonOrPrev.dyn_cast<Common*>()) {
108195341Sed    for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
109195341Sed              Spec = CommonPtr->Specializations.begin(),
110195341Sed           SpecEnd = CommonPtr->Specializations.end();
111195341Sed         Spec != SpecEnd; ++Spec)
112195341Sed      C.Deallocate(&*Spec);
113195341Sed  }
114198092Srdivacky
115195341Sed  Decl::Destroy(C);
116195341Sed}
117195341Sed
118198092SrdivackyFunctionTemplateDecl *FunctionTemplateDecl::getCanonicalDecl() {
119198092Srdivacky  FunctionTemplateDecl *FunTmpl = this;
120198092Srdivacky  while (FunTmpl->getPreviousDeclaration())
121198092Srdivacky    FunTmpl = FunTmpl->getPreviousDeclaration();
122198092Srdivacky  return FunTmpl;
123198092Srdivacky}
124198092Srdivacky
125195341SedFunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
126195341Sed  // Find the first declaration of this function template.
127195341Sed  FunctionTemplateDecl *First = this;
128195341Sed  while (First->getPreviousDeclaration())
129195341Sed    First = First->getPreviousDeclaration();
130198092Srdivacky
131195341Sed  if (First->CommonOrPrev.isNull()) {
132195341Sed    // FIXME: Allocate with the ASTContext
133195341Sed    First->CommonOrPrev = new Common;
134195341Sed  }
135195341Sed  return First->CommonOrPrev.get<Common*>();
136195341Sed}
137195341Sed
138193326Sed//===----------------------------------------------------------------------===//
139193326Sed// ClassTemplateDecl Implementation
140193326Sed//===----------------------------------------------------------------------===//
141193326Sed
142198092SrdivackyClassTemplateDecl *ClassTemplateDecl::getCanonicalDecl() {
143198092Srdivacky  ClassTemplateDecl *Template = this;
144198092Srdivacky  while (Template->getPreviousDeclaration())
145198092Srdivacky    Template = Template->getPreviousDeclaration();
146198092Srdivacky  return Template;
147198092Srdivacky}
148198092Srdivacky
149193326SedClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C,
150193326Sed                                             DeclContext *DC,
151193326Sed                                             SourceLocation L,
152193326Sed                                             DeclarationName Name,
153193326Sed                                             TemplateParameterList *Params,
154193326Sed                                             NamedDecl *Decl,
155193326Sed                                             ClassTemplateDecl *PrevDecl) {
156193326Sed  Common *CommonPtr;
157193326Sed  if (PrevDecl)
158193326Sed    CommonPtr = PrevDecl->CommonPtr;
159193326Sed  else
160193326Sed    CommonPtr = new (C) Common;
161193326Sed
162198092Srdivacky  return new (C) ClassTemplateDecl(DC, L, Name, Params, Decl, PrevDecl,
163193326Sed                                   CommonPtr);
164193326Sed}
165193326Sed
166193326SedClassTemplateDecl::~ClassTemplateDecl() {
167193326Sed  assert(CommonPtr == 0 && "ClassTemplateDecl must be explicitly destroyed");
168193326Sed}
169193326Sed
170193326Sedvoid ClassTemplateDecl::Destroy(ASTContext& C) {
171193326Sed  if (!PreviousDeclaration) {
172193326Sed    CommonPtr->~Common();
173193326Sed    C.Deallocate((void*)CommonPtr);
174193326Sed  }
175193326Sed  CommonPtr = 0;
176193326Sed
177193326Sed  this->~ClassTemplateDecl();
178193326Sed  C.Deallocate((void*)this);
179193326Sed}
180193326Sed
181207619Srdivackyvoid ClassTemplateDecl::getPartialSpecializations(
182207619Srdivacky          llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
183207619Srdivacky  llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
184207619Srdivacky    = CommonPtr->PartialSpecializations;
185207619Srdivacky  PS.clear();
186207619Srdivacky  PS.resize(PartialSpecs.size());
187207619Srdivacky  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
188207619Srdivacky       P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
189207619Srdivacky       P != PEnd; ++P) {
190207619Srdivacky    assert(!PS[P->getSequenceNumber()]);
191207619Srdivacky    PS[P->getSequenceNumber()] = &*P;
192207619Srdivacky  }
193207619Srdivacky}
194207619Srdivacky
195198092SrdivackyClassTemplatePartialSpecializationDecl *
196198092SrdivackyClassTemplateDecl::findPartialSpecialization(QualType T) {
197198092Srdivacky  ASTContext &Context = getASTContext();
198198092Srdivacky  typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
199198092Srdivacky    partial_spec_iterator;
200198092Srdivacky  for (partial_spec_iterator P = getPartialSpecializations().begin(),
201198092Srdivacky                          PEnd = getPartialSpecializations().end();
202198092Srdivacky       P != PEnd; ++P) {
203207619Srdivacky    if (Context.hasSameType(P->getInjectedSpecializationType(), T))
204198092Srdivacky      return &*P;
205198092Srdivacky  }
206198092Srdivacky
207198092Srdivacky  return 0;
208198092Srdivacky}
209198092Srdivacky
210204962SrdivackyQualType
211204962SrdivackyClassTemplateDecl::getInjectedClassNameSpecialization(ASTContext &Context) {
212193326Sed  if (!CommonPtr->InjectedClassNameType.isNull())
213193326Sed    return CommonPtr->InjectedClassNameType;
214193326Sed
215193326Sed  // FIXME: n2800 14.6.1p1 should say how the template arguments
216193326Sed  // corresponding to template parameter packs should be pack
217193326Sed  // expansions. We already say that in 14.6.2.1p2, so it would be
218193326Sed  // better to fix that redundancy.
219193326Sed
220193326Sed  TemplateParameterList *Params = getTemplateParameters();
221193326Sed  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
222193326Sed  TemplateArgs.reserve(Params->size());
223198092Srdivacky  for (TemplateParameterList::iterator Param = Params->begin(),
224198092Srdivacky                                    ParamEnd = Params->end();
225193326Sed       Param != ParamEnd; ++Param) {
226193326Sed    if (isa<TemplateTypeParmDecl>(*Param)) {
227193326Sed      QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
228198893Srdivacky      TemplateArgs.push_back(TemplateArgument(ParamType));
229198092Srdivacky    } else if (NonTypeTemplateParmDecl *NTTP =
230193326Sed                 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
231203955Srdivacky      Expr *E = new (Context) DeclRefExpr(NTTP,
232203955Srdivacky                                          NTTP->getType().getNonReferenceType(),
233199990Srdivacky                                          NTTP->getLocation());
234193326Sed      TemplateArgs.push_back(TemplateArgument(E));
235198092Srdivacky    } else {
236193326Sed      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
237199482Srdivacky      TemplateArgs.push_back(TemplateArgument(TemplateName(TTP)));
238193326Sed    }
239193326Sed  }
240193326Sed
241193326Sed  CommonPtr->InjectedClassNameType
242198092Srdivacky    = Context.getTemplateSpecializationType(TemplateName(this),
243193326Sed                                            &TemplateArgs[0],
244198092Srdivacky                                            TemplateArgs.size());
245193326Sed  return CommonPtr->InjectedClassNameType;
246193326Sed}
247193326Sed
248193326Sed//===----------------------------------------------------------------------===//
249193326Sed// TemplateTypeParm Allocation/Deallocation Method Implementations
250193326Sed//===----------------------------------------------------------------------===//
251193326Sed
252193326SedTemplateTypeParmDecl *
253193326SedTemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
254193326Sed                             SourceLocation L, unsigned D, unsigned P,
255194179Sed                             IdentifierInfo *Id, bool Typename,
256194179Sed                             bool ParameterPack) {
257194613Sed  QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
258194179Sed  return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
259193326Sed}
260193326Sed
261198893SrdivackySourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
262198893Srdivacky  return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
263198893Srdivacky}
264198893Srdivacky
265198893Srdivackyunsigned TemplateTypeParmDecl::getDepth() const {
266198893Srdivacky  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
267198893Srdivacky}
268198893Srdivacky
269198893Srdivackyunsigned TemplateTypeParmDecl::getIndex() const {
270198893Srdivacky  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
271198893Srdivacky}
272198893Srdivacky
273193326Sed//===----------------------------------------------------------------------===//
274193326Sed// NonTypeTemplateParmDecl Method Implementations
275193326Sed//===----------------------------------------------------------------------===//
276193326Sed
277193326SedNonTypeTemplateParmDecl *
278193326SedNonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
279193326Sed                                SourceLocation L, unsigned D, unsigned P,
280193326Sed                                IdentifierInfo *Id, QualType T,
281200583Srdivacky                                TypeSourceInfo *TInfo) {
282200583Srdivacky  return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo);
283193326Sed}
284193326Sed
285193326SedSourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
286193326Sed  return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
287198092Srdivacky                        : SourceLocation();
288193326Sed}
289193326Sed
290193326Sed//===----------------------------------------------------------------------===//
291193326Sed// TemplateTemplateParmDecl Method Implementations
292193326Sed//===----------------------------------------------------------------------===//
293193326Sed
294193326SedTemplateTemplateParmDecl *
295193326SedTemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
296193326Sed                                 SourceLocation L, unsigned D, unsigned P,
297193326Sed                                 IdentifierInfo *Id,
298193326Sed                                 TemplateParameterList *Params) {
299193326Sed  return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
300193326Sed}
301193326Sed
302193326Sed//===----------------------------------------------------------------------===//
303193576Sed// TemplateArgumentListBuilder Implementation
304193576Sed//===----------------------------------------------------------------------===//
305194711Sed
306194711Sedvoid TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
307193576Sed  switch (Arg.getKind()) {
308194711Sed    default: break;
309194711Sed    case TemplateArgument::Type:
310198398Srdivacky      assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
311194711Sed      break;
312193576Sed  }
313198092Srdivacky
314194711Sed  assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
315198092Srdivacky  assert(!StructuredArgs &&
316194711Sed         "Can't append arguments when an argument pack has been added!");
317198092Srdivacky
318194711Sed  if (!FlatArgs)
319194711Sed    FlatArgs = new TemplateArgument[MaxFlatArgs];
320198092Srdivacky
321194711Sed  FlatArgs[NumFlatArgs++] = Arg;
322193576Sed}
323193576Sed
324194711Sedvoid TemplateArgumentListBuilder::BeginPack() {
325194711Sed  assert(!AddingToPack && "Already adding to pack!");
326194711Sed  assert(!StructuredArgs && "Argument list already contains a pack!");
327198092Srdivacky
328194711Sed  AddingToPack = true;
329194711Sed  PackBeginIndex = NumFlatArgs;
330194179Sed}
331194179Sed
332194711Sedvoid TemplateArgumentListBuilder::EndPack() {
333194711Sed  assert(AddingToPack && "Not adding to pack!");
334194711Sed  assert(!StructuredArgs && "Argument list already contains a pack!");
335198092Srdivacky
336194711Sed  AddingToPack = false;
337194613Sed
338194711Sed  StructuredArgs = new TemplateArgument[MaxStructuredArgs];
339198092Srdivacky
340194711Sed  // First copy the flat entries over to the list  (if any)
341194711Sed  for (unsigned I = 0; I != PackBeginIndex; ++I) {
342194711Sed    NumStructuredArgs++;
343194711Sed    StructuredArgs[I] = FlatArgs[I];
344194711Sed  }
345198092Srdivacky
346194711Sed  // Next, set the pack.
347194711Sed  TemplateArgument *PackArgs = 0;
348194711Sed  unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
349194711Sed  if (NumPackArgs)
350194711Sed    PackArgs = &FlatArgs[PackBeginIndex];
351198092Srdivacky
352198092Srdivacky  StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
353194711Sed                                                      /*CopyArgs=*/false);
354194711Sed}
355194179Sed
356194711Sedvoid TemplateArgumentListBuilder::ReleaseArgs() {
357194711Sed  FlatArgs = 0;
358194711Sed  NumFlatArgs = 0;
359194711Sed  MaxFlatArgs = 0;
360194711Sed  StructuredArgs = 0;
361194711Sed  NumStructuredArgs = 0;
362194711Sed  MaxStructuredArgs = 0;
363194711Sed}
364194711Sed
365193576Sed//===----------------------------------------------------------------------===//
366193326Sed// TemplateArgumentList Implementation
367193326Sed//===----------------------------------------------------------------------===//
368193326SedTemplateArgumentList::TemplateArgumentList(ASTContext &Context,
369193576Sed                                           TemplateArgumentListBuilder &Builder,
370194711Sed                                           bool TakeArgs)
371198092Srdivacky  : FlatArguments(Builder.getFlatArguments(), TakeArgs),
372198092Srdivacky    NumFlatArguments(Builder.flatSize()),
373194711Sed    StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
374194711Sed    NumStructuredArguments(Builder.structuredSize()) {
375198092Srdivacky
376194711Sed  if (!TakeArgs)
377193326Sed    return;
378198092Srdivacky
379194711Sed  if (Builder.getStructuredArguments() == Builder.getFlatArguments())
380194711Sed    StructuredArguments.setInt(0);
381194711Sed  Builder.ReleaseArgs();
382193326Sed}
383193326Sed
384198092SrdivackyTemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other)
385198092Srdivacky  : FlatArguments(Other.FlatArguments.getPointer(), 1),
386198092Srdivacky    NumFlatArguments(Other.flat_size()),
387198092Srdivacky    StructuredArguments(Other.StructuredArguments.getPointer(), 1),
388198092Srdivacky    NumStructuredArguments(Other.NumStructuredArguments) { }
389198092Srdivacky
390193326SedTemplateArgumentList::~TemplateArgumentList() {
391193326Sed  // FIXME: Deallocate template arguments
392193326Sed}
393193326Sed
394193326Sed//===----------------------------------------------------------------------===//
395193326Sed// ClassTemplateSpecializationDecl Implementation
396193326Sed//===----------------------------------------------------------------------===//
397193326SedClassTemplateSpecializationDecl::
398193326SedClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
399193326Sed                                DeclContext *DC, SourceLocation L,
400193326Sed                                ClassTemplateDecl *SpecializedTemplate,
401198092Srdivacky                                TemplateArgumentListBuilder &Builder,
402198092Srdivacky                                ClassTemplateSpecializationDecl *PrevDecl)
403198092Srdivacky  : CXXRecordDecl(DK,
404198092Srdivacky                  SpecializedTemplate->getTemplatedDecl()->getTagKind(),
405193326Sed                  DC, L,
406193326Sed                  // FIXME: Should we use DeclarationName for the name of
407193326Sed                  // class template specializations?
408198092Srdivacky                  SpecializedTemplate->getIdentifier(),
409198092Srdivacky                  PrevDecl),
410193326Sed    SpecializedTemplate(SpecializedTemplate),
411204962Srdivacky    TypeAsWritten(0),
412194711Sed    TemplateArgs(Context, Builder, /*TakeArgs=*/true),
413193326Sed    SpecializationKind(TSK_Undeclared) {
414193326Sed}
415198092Srdivacky
416193326SedClassTemplateSpecializationDecl *
417198092SrdivackyClassTemplateSpecializationDecl::Create(ASTContext &Context,
418193326Sed                                        DeclContext *DC, SourceLocation L,
419193326Sed                                        ClassTemplateDecl *SpecializedTemplate,
420193576Sed                                        TemplateArgumentListBuilder &Builder,
421193326Sed                                   ClassTemplateSpecializationDecl *PrevDecl) {
422193326Sed  ClassTemplateSpecializationDecl *Result
423198092Srdivacky    = new (Context)ClassTemplateSpecializationDecl(Context,
424193326Sed                                                   ClassTemplateSpecialization,
425198092Srdivacky                                                   DC, L,
426193326Sed                                                   SpecializedTemplate,
427198092Srdivacky                                                   Builder,
428198092Srdivacky                                                   PrevDecl);
429193326Sed  Context.getTypeDeclType(Result, PrevDecl);
430193326Sed  return Result;
431193326Sed}
432193326Sed
433198092Srdivackyvoid ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
434198092Srdivacky  if (SpecializedPartialSpecialization *PartialSpec
435198092Srdivacky        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
436198092Srdivacky    C.Deallocate(PartialSpec);
437198092Srdivacky
438198092Srdivacky  CXXRecordDecl::Destroy(C);
439198092Srdivacky}
440198092Srdivacky
441198092Srdivackyvoid
442198092SrdivackyClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
443198092Srdivacky                                                  const PrintingPolicy &Policy,
444198092Srdivacky                                                      bool Qualified) const {
445198092Srdivacky  NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
446198092Srdivacky
447198092Srdivacky  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
448198092Srdivacky  S += TemplateSpecializationType::PrintTemplateArgumentList(
449198092Srdivacky                                       TemplateArgs.getFlatArgumentList(),
450198092Srdivacky                                       TemplateArgs.flat_size(),
451198092Srdivacky                                                             Policy);
452198092Srdivacky}
453198092Srdivacky
454198092SrdivackyClassTemplateDecl *
455198092SrdivackyClassTemplateSpecializationDecl::getSpecializedTemplate() const {
456198092Srdivacky  if (SpecializedPartialSpecialization *PartialSpec
457198092Srdivacky      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
458198092Srdivacky    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
459198092Srdivacky  return SpecializedTemplate.get<ClassTemplateDecl*>();
460198092Srdivacky}
461198092Srdivacky
462193326Sed//===----------------------------------------------------------------------===//
463193326Sed// ClassTemplatePartialSpecializationDecl Implementation
464193326Sed//===----------------------------------------------------------------------===//
465193326SedClassTemplatePartialSpecializationDecl *
466193326SedClassTemplatePartialSpecializationDecl::
467193326SedCreate(ASTContext &Context, DeclContext *DC, SourceLocation L,
468193326Sed       TemplateParameterList *Params,
469193326Sed       ClassTemplateDecl *SpecializedTemplate,
470193576Sed       TemplateArgumentListBuilder &Builder,
471199990Srdivacky       const TemplateArgumentListInfo &ArgInfos,
472204962Srdivacky       QualType CanonInjectedType,
473207619Srdivacky       ClassTemplatePartialSpecializationDecl *PrevDecl,
474207619Srdivacky       unsigned SequenceNumber) {
475199990Srdivacky  unsigned N = ArgInfos.size();
476198893Srdivacky  TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
477198893Srdivacky  for (unsigned I = 0; I != N; ++I)
478198893Srdivacky    ClonedArgs[I] = ArgInfos[I];
479198893Srdivacky
480193326Sed  ClassTemplatePartialSpecializationDecl *Result
481198092Srdivacky    = new (Context)ClassTemplatePartialSpecializationDecl(Context,
482193326Sed                                                          DC, L, Params,
483193326Sed                                                          SpecializedTemplate,
484198893Srdivacky                                                          Builder,
485198893Srdivacky                                                          ClonedArgs, N,
486207619Srdivacky                                                          PrevDecl,
487207619Srdivacky                                                          SequenceNumber);
488193326Sed  Result->setSpecializationKind(TSK_ExplicitSpecialization);
489204962Srdivacky
490204962Srdivacky  Context.getInjectedClassNameType(Result, CanonInjectedType);
491193326Sed  return Result;
492193326Sed}
493198092Srdivacky
494198092Srdivacky//===----------------------------------------------------------------------===//
495198092Srdivacky// FriendTemplateDecl Implementation
496198092Srdivacky//===----------------------------------------------------------------------===//
497198092Srdivacky
498198092SrdivackyFriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
499198092Srdivacky                                               DeclContext *DC,
500198092Srdivacky                                               SourceLocation L,
501198092Srdivacky                                               unsigned NParams,
502198092Srdivacky                                               TemplateParameterList **Params,
503198092Srdivacky                                               FriendUnion Friend,
504198092Srdivacky                                               SourceLocation FLoc) {
505198092Srdivacky  FriendTemplateDecl *Result
506198092Srdivacky    = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
507198092Srdivacky  return Result;
508198092Srdivacky}
509