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