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