DeclTemplate.cpp revision 200583
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)) {
216193326Sed      Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType(),
217199990Srdivacky                                          NTTP->getLocation());
218193326Sed      TemplateArgs.push_back(TemplateArgument(E));
219198092Srdivacky    } else {
220193326Sed      TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param);
221199482Srdivacky      TemplateArgs.push_back(TemplateArgument(TemplateName(TTP)));
222193326Sed    }
223193326Sed  }
224193326Sed
225193326Sed  CommonPtr->InjectedClassNameType
226198092Srdivacky    = Context.getTemplateSpecializationType(TemplateName(this),
227193326Sed                                            &TemplateArgs[0],
228198092Srdivacky                                            TemplateArgs.size());
229193326Sed  return CommonPtr->InjectedClassNameType;
230193326Sed}
231193326Sed
232193326Sed//===----------------------------------------------------------------------===//
233193326Sed// TemplateTypeParm Allocation/Deallocation Method Implementations
234193326Sed//===----------------------------------------------------------------------===//
235193326Sed
236193326SedTemplateTypeParmDecl *
237193326SedTemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
238193326Sed                             SourceLocation L, unsigned D, unsigned P,
239194179Sed                             IdentifierInfo *Id, bool Typename,
240194179Sed                             bool ParameterPack) {
241194613Sed  QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
242194179Sed  return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
243193326Sed}
244193326Sed
245198893SrdivackySourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const {
246198893Srdivacky  return DefaultArgument->getTypeLoc().getFullSourceRange().getBegin();
247198893Srdivacky}
248198893Srdivacky
249198893Srdivackyunsigned TemplateTypeParmDecl::getDepth() const {
250198893Srdivacky  return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth();
251198893Srdivacky}
252198893Srdivacky
253198893Srdivackyunsigned TemplateTypeParmDecl::getIndex() const {
254198893Srdivacky  return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex();
255198893Srdivacky}
256198893Srdivacky
257193326Sed//===----------------------------------------------------------------------===//
258193326Sed// NonTypeTemplateParmDecl Method Implementations
259193326Sed//===----------------------------------------------------------------------===//
260193326Sed
261193326SedNonTypeTemplateParmDecl *
262193326SedNonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
263193326Sed                                SourceLocation L, unsigned D, unsigned P,
264193326Sed                                IdentifierInfo *Id, QualType T,
265200583Srdivacky                                TypeSourceInfo *TInfo) {
266200583Srdivacky  return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo);
267193326Sed}
268193326Sed
269193326SedSourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
270193326Sed  return DefaultArgument? DefaultArgument->getSourceRange().getBegin()
271198092Srdivacky                        : SourceLocation();
272193326Sed}
273193326Sed
274193326Sed//===----------------------------------------------------------------------===//
275193326Sed// TemplateTemplateParmDecl Method Implementations
276193326Sed//===----------------------------------------------------------------------===//
277193326Sed
278193326SedTemplateTemplateParmDecl *
279193326SedTemplateTemplateParmDecl::Create(ASTContext &C, DeclContext *DC,
280193326Sed                                 SourceLocation L, unsigned D, unsigned P,
281193326Sed                                 IdentifierInfo *Id,
282193326Sed                                 TemplateParameterList *Params) {
283193326Sed  return new (C) TemplateTemplateParmDecl(DC, L, D, P, Id, Params);
284193326Sed}
285193326Sed
286193326Sed//===----------------------------------------------------------------------===//
287193576Sed// TemplateArgumentListBuilder Implementation
288193576Sed//===----------------------------------------------------------------------===//
289194711Sed
290194711Sedvoid TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
291193576Sed  switch (Arg.getKind()) {
292194711Sed    default: break;
293194711Sed    case TemplateArgument::Type:
294198398Srdivacky      assert(Arg.getAsType().isCanonical() && "Type must be canonical!");
295194711Sed      break;
296193576Sed  }
297198092Srdivacky
298194711Sed  assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
299198092Srdivacky  assert(!StructuredArgs &&
300194711Sed         "Can't append arguments when an argument pack has been added!");
301198092Srdivacky
302194711Sed  if (!FlatArgs)
303194711Sed    FlatArgs = new TemplateArgument[MaxFlatArgs];
304198092Srdivacky
305194711Sed  FlatArgs[NumFlatArgs++] = Arg;
306193576Sed}
307193576Sed
308194711Sedvoid TemplateArgumentListBuilder::BeginPack() {
309194711Sed  assert(!AddingToPack && "Already adding to pack!");
310194711Sed  assert(!StructuredArgs && "Argument list already contains a pack!");
311198092Srdivacky
312194711Sed  AddingToPack = true;
313194711Sed  PackBeginIndex = NumFlatArgs;
314194179Sed}
315194179Sed
316194711Sedvoid TemplateArgumentListBuilder::EndPack() {
317194711Sed  assert(AddingToPack && "Not adding to pack!");
318194711Sed  assert(!StructuredArgs && "Argument list already contains a pack!");
319198092Srdivacky
320194711Sed  AddingToPack = false;
321194613Sed
322194711Sed  StructuredArgs = new TemplateArgument[MaxStructuredArgs];
323198092Srdivacky
324194711Sed  // First copy the flat entries over to the list  (if any)
325194711Sed  for (unsigned I = 0; I != PackBeginIndex; ++I) {
326194711Sed    NumStructuredArgs++;
327194711Sed    StructuredArgs[I] = FlatArgs[I];
328194711Sed  }
329198092Srdivacky
330194711Sed  // Next, set the pack.
331194711Sed  TemplateArgument *PackArgs = 0;
332194711Sed  unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
333194711Sed  if (NumPackArgs)
334194711Sed    PackArgs = &FlatArgs[PackBeginIndex];
335198092Srdivacky
336198092Srdivacky  StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
337194711Sed                                                      /*CopyArgs=*/false);
338194711Sed}
339194179Sed
340194711Sedvoid TemplateArgumentListBuilder::ReleaseArgs() {
341194711Sed  FlatArgs = 0;
342194711Sed  NumFlatArgs = 0;
343194711Sed  MaxFlatArgs = 0;
344194711Sed  StructuredArgs = 0;
345194711Sed  NumStructuredArgs = 0;
346194711Sed  MaxStructuredArgs = 0;
347194711Sed}
348194711Sed
349193576Sed//===----------------------------------------------------------------------===//
350193326Sed// TemplateArgumentList Implementation
351193326Sed//===----------------------------------------------------------------------===//
352193326SedTemplateArgumentList::TemplateArgumentList(ASTContext &Context,
353193576Sed                                           TemplateArgumentListBuilder &Builder,
354194711Sed                                           bool TakeArgs)
355198092Srdivacky  : FlatArguments(Builder.getFlatArguments(), TakeArgs),
356198092Srdivacky    NumFlatArguments(Builder.flatSize()),
357194711Sed    StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
358194711Sed    NumStructuredArguments(Builder.structuredSize()) {
359198092Srdivacky
360194711Sed  if (!TakeArgs)
361193326Sed    return;
362198092Srdivacky
363194711Sed  if (Builder.getStructuredArguments() == Builder.getFlatArguments())
364194711Sed    StructuredArguments.setInt(0);
365194711Sed  Builder.ReleaseArgs();
366193326Sed}
367193326Sed
368198092SrdivackyTemplateArgumentList::TemplateArgumentList(const TemplateArgumentList &Other)
369198092Srdivacky  : FlatArguments(Other.FlatArguments.getPointer(), 1),
370198092Srdivacky    NumFlatArguments(Other.flat_size()),
371198092Srdivacky    StructuredArguments(Other.StructuredArguments.getPointer(), 1),
372198092Srdivacky    NumStructuredArguments(Other.NumStructuredArguments) { }
373198092Srdivacky
374193326SedTemplateArgumentList::~TemplateArgumentList() {
375193326Sed  // FIXME: Deallocate template arguments
376193326Sed}
377193326Sed
378193326Sed//===----------------------------------------------------------------------===//
379193326Sed// ClassTemplateSpecializationDecl Implementation
380193326Sed//===----------------------------------------------------------------------===//
381193326SedClassTemplateSpecializationDecl::
382193326SedClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
383193326Sed                                DeclContext *DC, SourceLocation L,
384193326Sed                                ClassTemplateDecl *SpecializedTemplate,
385198092Srdivacky                                TemplateArgumentListBuilder &Builder,
386198092Srdivacky                                ClassTemplateSpecializationDecl *PrevDecl)
387198092Srdivacky  : CXXRecordDecl(DK,
388198092Srdivacky                  SpecializedTemplate->getTemplatedDecl()->getTagKind(),
389193326Sed                  DC, L,
390193326Sed                  // FIXME: Should we use DeclarationName for the name of
391193326Sed                  // class template specializations?
392198092Srdivacky                  SpecializedTemplate->getIdentifier(),
393198092Srdivacky                  PrevDecl),
394193326Sed    SpecializedTemplate(SpecializedTemplate),
395194711Sed    TemplateArgs(Context, Builder, /*TakeArgs=*/true),
396193326Sed    SpecializationKind(TSK_Undeclared) {
397193326Sed}
398198092Srdivacky
399193326SedClassTemplateSpecializationDecl *
400198092SrdivackyClassTemplateSpecializationDecl::Create(ASTContext &Context,
401193326Sed                                        DeclContext *DC, SourceLocation L,
402193326Sed                                        ClassTemplateDecl *SpecializedTemplate,
403193576Sed                                        TemplateArgumentListBuilder &Builder,
404193326Sed                                   ClassTemplateSpecializationDecl *PrevDecl) {
405193326Sed  ClassTemplateSpecializationDecl *Result
406198092Srdivacky    = new (Context)ClassTemplateSpecializationDecl(Context,
407193326Sed                                                   ClassTemplateSpecialization,
408198092Srdivacky                                                   DC, L,
409193326Sed                                                   SpecializedTemplate,
410198092Srdivacky                                                   Builder,
411198092Srdivacky                                                   PrevDecl);
412193326Sed  Context.getTypeDeclType(Result, PrevDecl);
413193326Sed  return Result;
414193326Sed}
415193326Sed
416198092Srdivackyvoid ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
417198092Srdivacky  if (SpecializedPartialSpecialization *PartialSpec
418198092Srdivacky        = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
419198092Srdivacky    C.Deallocate(PartialSpec);
420198092Srdivacky
421198092Srdivacky  CXXRecordDecl::Destroy(C);
422198092Srdivacky}
423198092Srdivacky
424198092Srdivackyvoid
425198092SrdivackyClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S,
426198092Srdivacky                                                  const PrintingPolicy &Policy,
427198092Srdivacky                                                      bool Qualified) const {
428198092Srdivacky  NamedDecl::getNameForDiagnostic(S, Policy, Qualified);
429198092Srdivacky
430198092Srdivacky  const TemplateArgumentList &TemplateArgs = getTemplateArgs();
431198092Srdivacky  S += TemplateSpecializationType::PrintTemplateArgumentList(
432198092Srdivacky                                       TemplateArgs.getFlatArgumentList(),
433198092Srdivacky                                       TemplateArgs.flat_size(),
434198092Srdivacky                                                             Policy);
435198092Srdivacky}
436198092Srdivacky
437198092SrdivackyClassTemplateDecl *
438198092SrdivackyClassTemplateSpecializationDecl::getSpecializedTemplate() const {
439198092Srdivacky  if (SpecializedPartialSpecialization *PartialSpec
440198092Srdivacky      = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
441198092Srdivacky    return PartialSpec->PartialSpecialization->getSpecializedTemplate();
442198092Srdivacky  return SpecializedTemplate.get<ClassTemplateDecl*>();
443198092Srdivacky}
444198092Srdivacky
445193326Sed//===----------------------------------------------------------------------===//
446193326Sed// ClassTemplatePartialSpecializationDecl Implementation
447193326Sed//===----------------------------------------------------------------------===//
448193326SedClassTemplatePartialSpecializationDecl *
449193326SedClassTemplatePartialSpecializationDecl::
450193326SedCreate(ASTContext &Context, DeclContext *DC, SourceLocation L,
451193326Sed       TemplateParameterList *Params,
452193326Sed       ClassTemplateDecl *SpecializedTemplate,
453193576Sed       TemplateArgumentListBuilder &Builder,
454199990Srdivacky       const TemplateArgumentListInfo &ArgInfos,
455193326Sed       ClassTemplatePartialSpecializationDecl *PrevDecl) {
456199990Srdivacky  unsigned N = ArgInfos.size();
457198893Srdivacky  TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
458198893Srdivacky  for (unsigned I = 0; I != N; ++I)
459198893Srdivacky    ClonedArgs[I] = ArgInfos[I];
460198893Srdivacky
461193326Sed  ClassTemplatePartialSpecializationDecl *Result
462198092Srdivacky    = new (Context)ClassTemplatePartialSpecializationDecl(Context,
463193326Sed                                                          DC, L, Params,
464193326Sed                                                          SpecializedTemplate,
465198893Srdivacky                                                          Builder,
466198893Srdivacky                                                          ClonedArgs, N,
467198893Srdivacky                                                          PrevDecl);
468193326Sed  Result->setSpecializationKind(TSK_ExplicitSpecialization);
469193326Sed  Context.getTypeDeclType(Result, PrevDecl);
470193326Sed  return Result;
471193326Sed}
472198092Srdivacky
473198092Srdivacky//===----------------------------------------------------------------------===//
474198092Srdivacky// FriendTemplateDecl Implementation
475198092Srdivacky//===----------------------------------------------------------------------===//
476198092Srdivacky
477198092SrdivackyFriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context,
478198092Srdivacky                                               DeclContext *DC,
479198092Srdivacky                                               SourceLocation L,
480198092Srdivacky                                               unsigned NParams,
481198092Srdivacky                                               TemplateParameterList **Params,
482198092Srdivacky                                               FriendUnion Friend,
483198092Srdivacky                                               SourceLocation FLoc) {
484198092Srdivacky  FriendTemplateDecl *Result
485198092Srdivacky    = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc);
486198092Srdivacky  return Result;
487198092Srdivacky}
488