DeclTemplate.cpp revision 203955
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
181198092SrdivackyClassTemplatePartialSpecializationDecl *
182198092SrdivackyClassTemplateDecl::findPartialSpecialization(QualType T) {
183198092Srdivacky  ASTContext &Context = getASTContext();
184198092Srdivacky  typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
185198092Srdivacky    partial_spec_iterator;
186198092Srdivacky  for (partial_spec_iterator P = getPartialSpecializations().begin(),
187198092Srdivacky                          PEnd = getPartialSpecializations().end();
188198092Srdivacky       P != PEnd; ++P) {
189198092Srdivacky    if (Context.hasSameType(Context.getTypeDeclType(&*P), T))
190198092Srdivacky      return &*P;
191198092Srdivacky  }
192198092Srdivacky
193198092Srdivacky  return 0;
194198092Srdivacky}
195198092Srdivacky
196193326SedQualType ClassTemplateDecl::getInjectedClassNameType(ASTContext &Context) {
197193326Sed  if (!CommonPtr->InjectedClassNameType.isNull())
198193326Sed    return CommonPtr->InjectedClassNameType;
199193326Sed
200193326Sed  // FIXME: n2800 14.6.1p1 should say how the template arguments
201193326Sed  // corresponding to template parameter packs should be pack
202193326Sed  // expansions. We already say that in 14.6.2.1p2, so it would be
203193326Sed  // better to fix that redundancy.
204193326Sed
205193326Sed  TemplateParameterList *Params = getTemplateParameters();
206193326Sed  llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
207193326Sed  TemplateArgs.reserve(Params->size());
208198092Srdivacky  for (TemplateParameterList::iterator Param = Params->begin(),
209198092Srdivacky                                    ParamEnd = Params->end();
210193326Sed       Param != ParamEnd; ++Param) {
211193326Sed    if (isa<TemplateTypeParmDecl>(*Param)) {
212193326Sed      QualType ParamType = Context.getTypeDeclType(cast<TypeDecl>(*Param));
213198893Srdivacky      TemplateArgs.push_back(TemplateArgument(ParamType));
214198092Srdivacky    } else if (NonTypeTemplateParmDecl *NTTP =
215193326Sed                 dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
216203955Srdivacky      Expr *E = new (Context) DeclRefExpr(NTTP,
217203955Srdivacky                                          NTTP->getType().getNonReferenceType(),
218199990Srdivacky                                          NTTP->getLocation());
219193326Sed      TemplateArgs.push_back(TemplateArgument(E));
220198092Srdivacky    } else {
221193326Sed      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
222199482Srdivacky      TemplateArgs.push_back(TemplateArgument(TemplateName(TTP)));
223193326Sed    }
224193326Sed  }
225193326Sed
226193326Sed  CommonPtr->InjectedClassNameType
227198092Srdivacky    = Context.getTemplateSpecializationType(TemplateName(this),
228193326Sed                                            &TemplateArgs[0],
229198092Srdivacky                                            TemplateArgs.size());
230193326Sed  return CommonPtr->InjectedClassNameType;
231193326Sed}
232193326Sed
233193326Sed//===----------------------------------------------------------------------===//
234193326Sed// TemplateTypeParm Allocation/Deallocation Method Implementations
235193326Sed//===----------------------------------------------------------------------===//
236193326Sed
237193326SedTemplateTypeParmDecl *
238193326SedTemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
239193326Sed                             SourceLocation L, unsigned D, unsigned P,
240194179Sed                             IdentifierInfo *Id, bool Typename,
241194179Sed                             bool ParameterPack) {
242194613Sed  QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
243194179Sed  return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
244193326Sed}
245193326Sed
246198893SrdivackySourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
247198893Srdivacky  return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
248198893Srdivacky}
249198893Srdivacky
250198893Srdivackyunsigned TemplateTypeParmDecl::getDepth() const {
251198893Srdivacky  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
252198893Srdivacky}
253198893Srdivacky
254198893Srdivackyunsigned TemplateTypeParmDecl::getIndex() const {
255198893Srdivacky  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
256198893Srdivacky}
257198893Srdivacky
258193326Sed//===----------------------------------------------------------------------===//
259193326Sed// NonTypeTemplateParmDecl Method Implementations
260193326Sed//===----------------------------------------------------------------------===//
261193326Sed
262193326SedNonTypeTemplateParmDecl *
263193326SedNonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
264193326Sed                                SourceLocation L, unsigned D, unsigned P,
265193326Sed                                IdentifierInfo *Id, QualType T,
266200583Srdivacky                                TypeSourceInfo *TInfo) {
267200583Srdivacky  return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo);
268193326Sed}
269193326Sed
270193326SedSourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
271193326Sed  return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
272198092Srdivacky                        : SourceLocation();
273193326Sed}
274193326Sed
275193326Sed//===----------------------------------------------------------------------===//
276193326Sed// TemplateTemplateParmDecl Method Implementations
277193326Sed//===----------------------------------------------------------------------===//
278193326Sed
279193326SedTemplateTemplateParmDecl *
280193326SedTemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
281193326Sed                                 SourceLocation L, unsigned D, unsigned P,
282193326Sed                                 IdentifierInfo *Id,
283193326Sed                                 TemplateParameterList *Params) {
284193326Sed  return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
285193326Sed}
286193326Sed
287193326Sed//===----------------------------------------------------------------------===//
288193576Sed// TemplateArgumentListBuilder Implementation
289193576Sed//===----------------------------------------------------------------------===//
290194711Sed
291194711Sedvoid TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
292193576Sed  switch (Arg.getKind()) {
293194711Sed    default: break;
294194711Sed    case TemplateArgument::Type:
295198398Srdivacky      assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
296194711Sed      break;
297193576Sed  }
298198092Srdivacky
299194711Sed  assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
300198092Srdivacky  assert(!StructuredArgs &&
301194711Sed         "Can't append arguments when an argument pack has been added!");
302198092Srdivacky
303194711Sed  if (!FlatArgs)
304194711Sed    FlatArgs = new TemplateArgument[MaxFlatArgs];
305198092Srdivacky
306194711Sed  FlatArgs[NumFlatArgs++] = Arg;
307193576Sed}
308193576Sed
309194711Sedvoid TemplateArgumentListBuilder::BeginPack() {
310194711Sed  assert(!AddingToPack && "Already adding to pack!");
311194711Sed  assert(!StructuredArgs && "Argument list already contains a pack!");
312198092Srdivacky
313194711Sed  AddingToPack = true;
314194711Sed  PackBeginIndex = NumFlatArgs;
315194179Sed}
316194179Sed
317194711Sedvoid TemplateArgumentListBuilder::EndPack() {
318194711Sed  assert(AddingToPack && "Not adding to pack!");
319194711Sed  assert(!StructuredArgs && "Argument list already contains a pack!");
320198092Srdivacky
321194711Sed  AddingToPack = false;
322194613Sed
323194711Sed  StructuredArgs = new TemplateArgument[MaxStructuredArgs];
324198092Srdivacky
325194711Sed  // First copy the flat entries over to the list  (if any)
326194711Sed  for (unsigned I = 0; I != PackBeginIndex; ++I) {
327194711Sed    NumStructuredArgs++;
328194711Sed    StructuredArgs[I] = FlatArgs[I];
329194711Sed  }
330198092Srdivacky
331194711Sed  // Next, set the pack.
332194711Sed  TemplateArgument *PackArgs = 0;
333194711Sed  unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
334194711Sed  if (NumPackArgs)
335194711Sed    PackArgs = &FlatArgs[PackBeginIndex];
336198092Srdivacky
337198092Srdivacky  StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
338194711Sed                                                      /*CopyArgs=*/false);
339194711Sed}
340194179Sed
341194711Sedvoid TemplateArgumentListBuilder::ReleaseArgs() {
342194711Sed  FlatArgs = 0;
343194711Sed  NumFlatArgs = 0;
344194711Sed  MaxFlatArgs = 0;
345194711Sed  StructuredArgs = 0;
346194711Sed  NumStructuredArgs = 0;
347194711Sed  MaxStructuredArgs = 0;
348194711Sed}
349194711Sed
350193576Sed//===----------------------------------------------------------------------===//
351193326Sed// TemplateArgumentList Implementation
352193326Sed//===----------------------------------------------------------------------===//
353193326SedTemplateArgumentList::TemplateArgumentList(ASTContext &Context,
354193576Sed                                           TemplateArgumentListBuilder &Builder,
355194711Sed                                           bool TakeArgs)
356198092Srdivacky  : FlatArguments(Builder.getFlatArguments(), TakeArgs),
357198092Srdivacky    NumFlatArguments(Builder.flatSize()),
358194711Sed    StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
359194711Sed    NumStructuredArguments(Builder.structuredSize()) {
360198092Srdivacky
361194711Sed  if (!TakeArgs)
362193326Sed    return;
363198092Srdivacky
364194711Sed  if (Builder.getStructuredArguments() == Builder.getFlatArguments())
365194711Sed    StructuredArguments.setInt(0);
366194711Sed  Builder.ReleaseArgs();
367193326Sed}
368193326Sed
369198092SrdivackyTemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other)
370198092Srdivacky  : FlatArguments(Other.FlatArguments.getPointer(), 1),
371198092Srdivacky    NumFlatArguments(Other.flat_size()),
372198092Srdivacky    StructuredArguments(Other.StructuredArguments.getPointer(), 1),
373198092Srdivacky    NumStructuredArguments(Other.NumStructuredArguments) { }
374198092Srdivacky
375193326SedTemplateArgumentList::~TemplateArgumentList() {
376193326Sed  // FIXME: Deallocate template arguments
377193326Sed}
378193326Sed
379193326Sed//===----------------------------------------------------------------------===//
380193326Sed// ClassTemplateSpecializationDecl Implementation
381193326Sed//===----------------------------------------------------------------------===//
382193326SedClassTemplateSpecializationDecl::
383193326SedClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
384193326Sed                                DeclContext *DC, SourceLocation L,
385193326Sed                                ClassTemplateDecl *SpecializedTemplate,
386198092Srdivacky                                TemplateArgumentListBuilder &Builder,
387198092Srdivacky                                ClassTemplateSpecializationDecl *PrevDecl)
388198092Srdivacky  : CXXRecordDecl(DK,
389198092Srdivacky                  SpecializedTemplate->getTemplatedDecl()->getTagKind(),
390193326Sed                  DC, L,
391193326Sed                  // FIXME: Should we use DeclarationName for the name of
392193326Sed                  // class template specializations?
393198092Srdivacky                  SpecializedTemplate->getIdentifier(),
394198092Srdivacky                  PrevDecl),
395193326Sed    SpecializedTemplate(SpecializedTemplate),
396194711Sed    TemplateArgs(Context, Builder, /*TakeArgs=*/true),
397193326Sed    SpecializationKind(TSK_Undeclared) {
398193326Sed}
399198092Srdivacky
400193326SedClassTemplateSpecializationDecl *
401198092SrdivackyClassTemplateSpecializationDecl::Create(ASTContext &Context,
402193326Sed                                        DeclContext *DC, SourceLocation L,
403193326Sed                                        ClassTemplateDecl *SpecializedTemplate,
404193576Sed                                        TemplateArgumentListBuilder &Builder,
405193326Sed                                   ClassTemplateSpecializationDecl *PrevDecl) {
406193326Sed  ClassTemplateSpecializationDecl *Result
407198092Srdivacky    = new (Context)ClassTemplateSpecializationDecl(Context,
408193326Sed                                                   ClassTemplateSpecialization,
409198092Srdivacky                                                   DC, L,
410193326Sed                                                   SpecializedTemplate,
411198092Srdivacky                                                   Builder,
412198092Srdivacky                                                   PrevDecl);
413193326Sed  Context.getTypeDeclType(Result, PrevDecl);
414193326Sed  return Result;
415193326Sed}
416193326Sed
417198092Srdivackyvoid ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
418198092Srdivacky  if (SpecializedPartialSpecialization *PartialSpec
419198092Srdivacky        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
420198092Srdivacky    C.Deallocate(PartialSpec);
421198092Srdivacky
422198092Srdivacky  CXXRecordDecl::Destroy(C);
423198092Srdivacky}
424198092Srdivacky
425198092Srdivackyvoid
426198092SrdivackyClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
427198092Srdivacky                                                  const PrintingPolicy &Policy,
428198092Srdivacky                                                      bool Qualified) const {
429198092Srdivacky  NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
430198092Srdivacky
431198092Srdivacky  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
432198092Srdivacky  S += TemplateSpecializationType::PrintTemplateArgumentList(
433198092Srdivacky                                       TemplateArgs.getFlatArgumentList(),
434198092Srdivacky                                       TemplateArgs.flat_size(),
435198092Srdivacky                                                             Policy);
436198092Srdivacky}
437198092Srdivacky
438198092SrdivackyClassTemplateDecl *
439198092SrdivackyClassTemplateSpecializationDecl::getSpecializedTemplate() const {
440198092Srdivacky  if (SpecializedPartialSpecialization *PartialSpec
441198092Srdivacky      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
442198092Srdivacky    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
443198092Srdivacky  return SpecializedTemplate.get<ClassTemplateDecl*>();
444198092Srdivacky}
445198092Srdivacky
446193326Sed//===----------------------------------------------------------------------===//
447193326Sed// ClassTemplatePartialSpecializationDecl Implementation
448193326Sed//===----------------------------------------------------------------------===//
449193326SedClassTemplatePartialSpecializationDecl *
450193326SedClassTemplatePartialSpecializationDecl::
451193326SedCreate(ASTContext &Context, DeclContext *DC, SourceLocation L,
452193326Sed       TemplateParameterList *Params,
453193326Sed       ClassTemplateDecl *SpecializedTemplate,
454193576Sed       TemplateArgumentListBuilder &Builder,
455199990Srdivacky       const TemplateArgumentListInfo &ArgInfos,
456193326Sed       ClassTemplatePartialSpecializationDecl *PrevDecl) {
457199990Srdivacky  unsigned N = ArgInfos.size();
458198893Srdivacky  TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
459198893Srdivacky  for (unsigned I = 0; I != N; ++I)
460198893Srdivacky    ClonedArgs[I] = ArgInfos[I];
461198893Srdivacky
462193326Sed  ClassTemplatePartialSpecializationDecl *Result
463198092Srdivacky    = new (Context)ClassTemplatePartialSpecializationDecl(Context,
464193326Sed                                                          DC, L, Params,
465193326Sed                                                          SpecializedTemplate,
466198893Srdivacky                                                          Builder,
467198893Srdivacky                                                          ClonedArgs, N,
468198893Srdivacky                                                          PrevDecl);
469193326Sed  Result->setSpecializationKind(TSK_ExplicitSpecialization);
470193326Sed  Context.getTypeDeclType(Result, PrevDecl);
471193326Sed  return Result;
472193326Sed}
473198092Srdivacky
474198092Srdivacky//===----------------------------------------------------------------------===//
475198092Srdivacky// FriendTemplateDecl Implementation
476198092Srdivacky//===----------------------------------------------------------------------===//
477198092Srdivacky
478198092SrdivackyFriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
479198092Srdivacky                                               DeclContext *DC,
480198092Srdivacky                                               SourceLocation L,
481198092Srdivacky                                               unsigned NParams,
482198092Srdivacky                                               TemplateParameterList **Params,
483198092Srdivacky                                               FriendUnion Friend,
484198092Srdivacky                                               SourceLocation FLoc) {
485198092Srdivacky  FriendTemplateDecl *Result
486198092Srdivacky    = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
487198092Srdivacky  return Result;
488198092Srdivacky}
489