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