DeclTemplate.cpp revision ee4bfd412db491c489fc2ee74916edd73f9c618a
1//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the C++ related Decl classes for templates. 11// 12//===----------------------------------------------------------------------===// 13 14#include "clang/AST/DeclCXX.h" 15#include "clang/AST/DeclTemplate.h" 16#include "clang/AST/Expr.h" 17#include "clang/AST/ExprCXX.h" 18#include "clang/AST/ASTContext.h" 19#include "clang/AST/TypeLoc.h" 20#include "clang/AST/ASTMutationListener.h" 21#include "clang/Basic/IdentifierTable.h" 22#include "llvm/ADT/STLExtras.h" 23#include <memory> 24using namespace clang; 25 26//===----------------------------------------------------------------------===// 27// TemplateParameterList Implementation 28//===----------------------------------------------------------------------===// 29 30TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, 31 SourceLocation LAngleLoc, 32 NamedDecl **Params, unsigned NumParams, 33 SourceLocation RAngleLoc) 34 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), 35 NumParams(NumParams) { 36 for (unsigned Idx = 0; Idx < NumParams; ++Idx) 37 begin()[Idx] = Params[Idx]; 38} 39 40TemplateParameterList * 41TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, 42 SourceLocation LAngleLoc, NamedDecl **Params, 43 unsigned NumParams, SourceLocation RAngleLoc) { 44 unsigned Size = sizeof(TemplateParameterList) 45 + sizeof(NamedDecl *) * NumParams; 46 unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment; 47 void *Mem = C.Allocate(Size, Align); 48 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 49 NumParams, RAngleLoc); 50} 51 52unsigned TemplateParameterList::getMinRequiredArguments() const { 53 unsigned NumRequiredArgs = 0; 54 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), 55 PEnd = const_cast<TemplateParameterList *>(this)->end(); 56 P != PEnd; ++P) { 57 if ((*P)->isTemplateParameterPack()) { 58 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) 59 if (NTTP->isExpandedParameterPack()) { 60 NumRequiredArgs += NTTP->getNumExpansionTypes(); 61 continue; 62 } 63 64 break; 65 } 66 67 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 68 if (TTP->hasDefaultArgument()) 69 break; 70 } else if (NonTypeTemplateParmDecl *NTTP 71 = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 72 if (NTTP->hasDefaultArgument()) 73 break; 74 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument()) 75 break; 76 77 ++NumRequiredArgs; 78 } 79 80 return NumRequiredArgs; 81} 82 83unsigned TemplateParameterList::getDepth() const { 84 if (size() == 0) 85 return 0; 86 87 const NamedDecl *FirstParm = getParam(0); 88 if (const TemplateTypeParmDecl *TTP 89 = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 90 return TTP->getDepth(); 91 else if (const NonTypeTemplateParmDecl *NTTP 92 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 93 return NTTP->getDepth(); 94 else 95 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 96} 97 98//===----------------------------------------------------------------------===// 99// RedeclarableTemplateDecl Implementation 100//===----------------------------------------------------------------------===// 101 102RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() { 103 // Find the first declaration of this function template. 104 RedeclarableTemplateDecl *First = getCanonicalDecl(); 105 106 if (First->CommonOrPrev.isNull()) { 107 CommonBase *CommonPtr = First->newCommon(getASTContext()); 108 First->CommonOrPrev = CommonPtr; 109 CommonPtr->Latest = First; 110 } 111 return First->CommonOrPrev.get<CommonBase*>(); 112} 113 114 115RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() { 116 RedeclarableTemplateDecl *Tmpl = this; 117 while (Tmpl->getPreviousDeclaration()) 118 Tmpl = Tmpl->getPreviousDeclaration(); 119 return Tmpl; 120} 121 122void RedeclarableTemplateDecl::setPreviousDeclarationImpl( 123 RedeclarableTemplateDecl *Prev) { 124 if (Prev) { 125 CommonBase *Common = Prev->getCommonPtr(); 126 Prev = Common->Latest; 127 Common->Latest = this; 128 CommonOrPrev = Prev; 129 } else { 130 assert(CommonOrPrev.is<CommonBase*>() && "Cannot reset TemplateDecl Prev"); 131 } 132} 133 134RedeclarableTemplateDecl *RedeclarableTemplateDecl::getNextRedeclaration() { 135 if (CommonOrPrev.is<RedeclarableTemplateDecl*>()) 136 return CommonOrPrev.get<RedeclarableTemplateDecl*>(); 137 CommonBase *Common = CommonOrPrev.get<CommonBase*>(); 138 return Common ? Common->Latest : this; 139} 140 141template <class EntryType> 142typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType* 143RedeclarableTemplateDecl::findSpecializationImpl( 144 llvm::FoldingSet<EntryType> &Specs, 145 const TemplateArgument *Args, unsigned NumArgs, 146 void *&InsertPos) { 147 typedef SpecEntryTraits<EntryType> SETraits; 148 llvm::FoldingSetNodeID ID; 149 EntryType::Profile(ID,Args,NumArgs, getASTContext()); 150 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 151 return Entry ? SETraits::getMostRecentDeclaration(Entry) : 0; 152} 153 154//===----------------------------------------------------------------------===// 155// FunctionTemplateDecl Implementation 156//===----------------------------------------------------------------------===// 157 158void FunctionTemplateDecl::DeallocateCommon(void *Ptr) { 159 static_cast<Common *>(Ptr)->~Common(); 160} 161 162FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 163 DeclContext *DC, 164 SourceLocation L, 165 DeclarationName Name, 166 TemplateParameterList *Params, 167 NamedDecl *Decl) { 168 return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl); 169} 170 171RedeclarableTemplateDecl::CommonBase * 172FunctionTemplateDecl::newCommon(ASTContext &C) { 173 Common *CommonPtr = new (C) Common; 174 C.AddDeallocation(DeallocateCommon, CommonPtr); 175 return CommonPtr; 176} 177 178FunctionDecl * 179FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args, 180 unsigned NumArgs, void *&InsertPos) { 181 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 182} 183 184//===----------------------------------------------------------------------===// 185// ClassTemplateDecl Implementation 186//===----------------------------------------------------------------------===// 187 188void ClassTemplateDecl::DeallocateCommon(void *Ptr) { 189 static_cast<Common *>(Ptr)->~Common(); 190} 191 192ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 193 DeclContext *DC, 194 SourceLocation L, 195 DeclarationName Name, 196 TemplateParameterList *Params, 197 NamedDecl *Decl, 198 ClassTemplateDecl *PrevDecl) { 199 ClassTemplateDecl *New = new (C) ClassTemplateDecl(DC, L, Name, Params, Decl); 200 New->setPreviousDeclaration(PrevDecl); 201 return New; 202} 203 204void ClassTemplateDecl::LoadLazySpecializations() { 205 Common *CommonPtr = getCommonPtr(); 206 if (CommonPtr->LazySpecializations) { 207 ASTContext &Context = getASTContext(); 208 uint32_t *Specs = CommonPtr->LazySpecializations; 209 CommonPtr->LazySpecializations = 0; 210 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 211 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 212 } 213} 214 215llvm::FoldingSet<ClassTemplateSpecializationDecl> & 216ClassTemplateDecl::getSpecializations() { 217 LoadLazySpecializations(); 218 return getCommonPtr()->Specializations; 219} 220 221llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> & 222ClassTemplateDecl::getPartialSpecializations() { 223 LoadLazySpecializations(); 224 return getCommonPtr()->PartialSpecializations; 225} 226 227RedeclarableTemplateDecl::CommonBase * 228ClassTemplateDecl::newCommon(ASTContext &C) { 229 Common *CommonPtr = new (C) Common; 230 C.AddDeallocation(DeallocateCommon, CommonPtr); 231 return CommonPtr; 232} 233 234ClassTemplateSpecializationDecl * 235ClassTemplateDecl::findSpecialization(const TemplateArgument *Args, 236 unsigned NumArgs, void *&InsertPos) { 237 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 238} 239 240void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 241 void *InsertPos) { 242 getSpecializations().InsertNode(D, InsertPos); 243 if (ASTMutationListener *L = getASTMutationListener()) 244 L->AddedCXXTemplateSpecialization(this, D); 245} 246 247ClassTemplatePartialSpecializationDecl * 248ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, 249 unsigned NumArgs, 250 void *&InsertPos) { 251 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, 252 InsertPos); 253} 254 255void ClassTemplateDecl::AddPartialSpecialization( 256 ClassTemplatePartialSpecializationDecl *D, 257 void *InsertPos) { 258 getPartialSpecializations().InsertNode(D, InsertPos); 259 if (ASTMutationListener *L = getASTMutationListener()) 260 L->AddedCXXTemplateSpecialization(this, D); 261} 262 263void ClassTemplateDecl::getPartialSpecializations( 264 llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 265 llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs 266 = getPartialSpecializations(); 267 PS.clear(); 268 PS.resize(PartialSpecs.size()); 269 for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator 270 P = PartialSpecs.begin(), PEnd = PartialSpecs.end(); 271 P != PEnd; ++P) { 272 assert(!PS[P->getSequenceNumber()]); 273 PS[P->getSequenceNumber()] = P->getMostRecentDeclaration(); 274 } 275} 276 277ClassTemplatePartialSpecializationDecl * 278ClassTemplateDecl::findPartialSpecialization(QualType T) { 279 ASTContext &Context = getASTContext(); 280 typedef llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator 281 partial_spec_iterator; 282 for (partial_spec_iterator P = getPartialSpecializations().begin(), 283 PEnd = getPartialSpecializations().end(); 284 P != PEnd; ++P) { 285 if (Context.hasSameType(P->getInjectedSpecializationType(), T)) 286 return P->getMostRecentDeclaration(); 287 } 288 289 return 0; 290} 291 292ClassTemplatePartialSpecializationDecl * 293ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 294 ClassTemplatePartialSpecializationDecl *D) { 295 Decl *DCanon = D->getCanonicalDecl(); 296 for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator 297 P = getPartialSpecializations().begin(), 298 PEnd = getPartialSpecializations().end(); 299 P != PEnd; ++P) { 300 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 301 return P->getMostRecentDeclaration(); 302 } 303 304 return 0; 305} 306 307QualType 308ClassTemplateDecl::getInjectedClassNameSpecialization() { 309 Common *CommonPtr = getCommonPtr(); 310 if (!CommonPtr->InjectedClassNameType.isNull()) 311 return CommonPtr->InjectedClassNameType; 312 313 // C++0x [temp.dep.type]p2: 314 // The template argument list of a primary template is a template argument 315 // list in which the nth template argument has the value of the nth template 316 // parameter of the class template. If the nth template parameter is a 317 // template parameter pack (14.5.3), the nth template argument is a pack 318 // expansion (14.5.3) whose pattern is the name of the template parameter 319 // pack. 320 ASTContext &Context = getASTContext(); 321 TemplateParameterList *Params = getTemplateParameters(); 322 llvm::SmallVector<TemplateArgument, 16> TemplateArgs; 323 TemplateArgs.reserve(Params->size()); 324 for (TemplateParameterList::iterator Param = Params->begin(), 325 ParamEnd = Params->end(); 326 Param != ParamEnd; ++Param) { 327 TemplateArgument Arg; 328 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { 329 QualType ArgType = Context.getTypeDeclType(TTP); 330 if (TTP->isParameterPack()) 331 ArgType = Context.getPackExpansionType(ArgType, 332 llvm::Optional<unsigned>()); 333 334 Arg = TemplateArgument(ArgType); 335 } else if (NonTypeTemplateParmDecl *NTTP = 336 dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 337 Expr *E = new (Context) DeclRefExpr(NTTP, 338 NTTP->getType().getNonLValueExprType(Context), 339 Expr::getValueKindForType(NTTP->getType()), 340 NTTP->getLocation()); 341 342 if (NTTP->isParameterPack()) 343 E = new (Context) PackExpansionExpr(Context.DependentTy, E, 344 NTTP->getLocation(), 345 llvm::Optional<unsigned>()); 346 Arg = TemplateArgument(E); 347 } else { 348 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 349 if (TTP->isParameterPack()) 350 Arg = TemplateArgument(TemplateName(TTP), llvm::Optional<unsigned>()); 351 else 352 Arg = TemplateArgument(TemplateName(TTP)); 353 } 354 355 if ((*Param)->isTemplateParameterPack()) 356 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1); 357 358 TemplateArgs.push_back(Arg); 359 } 360 361 CommonPtr->InjectedClassNameType 362 = Context.getTemplateSpecializationType(TemplateName(this), 363 &TemplateArgs[0], 364 TemplateArgs.size()); 365 return CommonPtr->InjectedClassNameType; 366} 367 368//===----------------------------------------------------------------------===// 369// TemplateTypeParm Allocation/Deallocation Method Implementations 370//===----------------------------------------------------------------------===// 371 372TemplateTypeParmDecl * 373TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 374 SourceLocation L, unsigned D, unsigned P, 375 IdentifierInfo *Id, bool Typename, 376 bool ParameterPack) { 377 QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id); 378 return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack); 379} 380 381TemplateTypeParmDecl * 382TemplateTypeParmDecl::Create(const ASTContext &C, EmptyShell Empty) { 383 return new (C) TemplateTypeParmDecl(0, SourceLocation(), 0, false, 384 QualType(), false); 385} 386 387SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 388 return DefaultArgument->getTypeLoc().getSourceRange().getBegin(); 389} 390 391unsigned TemplateTypeParmDecl::getDepth() const { 392 return TypeForDecl->getAs<TemplateTypeParmType>()->getDepth(); 393} 394 395unsigned TemplateTypeParmDecl::getIndex() const { 396 return TypeForDecl->getAs<TemplateTypeParmType>()->getIndex(); 397} 398 399//===----------------------------------------------------------------------===// 400// NonTypeTemplateParmDecl Method Implementations 401//===----------------------------------------------------------------------===// 402 403NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 404 SourceLocation L, unsigned D, 405 unsigned P, IdentifierInfo *Id, 406 QualType T, 407 TypeSourceInfo *TInfo, 408 const QualType *ExpandedTypes, 409 unsigned NumExpandedTypes, 410 TypeSourceInfo **ExpandedTInfos) 411 : DeclaratorDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo), 412 TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false), 413 ParameterPack(true), ExpandedParameterPack(true), 414 NumExpandedTypes(NumExpandedTypes) 415{ 416 if (ExpandedTypes && ExpandedTInfos) { 417 void **TypesAndInfos = reinterpret_cast<void **>(this + 1); 418 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 419 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr(); 420 TypesAndInfos[2*I + 1] = ExpandedTInfos[I]; 421 } 422 } 423} 424 425NonTypeTemplateParmDecl * 426NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 427 SourceLocation L, unsigned D, unsigned P, 428 IdentifierInfo *Id, QualType T, 429 bool ParameterPack, TypeSourceInfo *TInfo) { 430 return new (C) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, ParameterPack, 431 TInfo); 432} 433 434NonTypeTemplateParmDecl * 435NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 436 SourceLocation L, unsigned D, unsigned P, 437 IdentifierInfo *Id, QualType T, 438 TypeSourceInfo *TInfo, 439 const QualType *ExpandedTypes, 440 unsigned NumExpandedTypes, 441 TypeSourceInfo **ExpandedTInfos) { 442 unsigned Size = sizeof(NonTypeTemplateParmDecl) 443 + NumExpandedTypes * 2 * sizeof(void*); 444 void *Mem = C.Allocate(Size); 445 return new (Mem) NonTypeTemplateParmDecl(DC, L, D, P, Id, T, TInfo, 446 ExpandedTypes, NumExpandedTypes, 447 ExpandedTInfos); 448} 449 450SourceLocation NonTypeTemplateParmDecl::getInnerLocStart() const { 451 SourceLocation Start = getTypeSpecStartLoc(); 452 if (Start.isInvalid()) 453 Start = getLocation(); 454 return Start; 455} 456 457SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 458 SourceLocation End = getLocation(); 459 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 460 End = getDefaultArgument()->getSourceRange().getEnd(); 461 return SourceRange(getOuterLocStart(), End); 462} 463 464SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 465 return hasDefaultArgument() 466 ? getDefaultArgument()->getSourceRange().getBegin() 467 : SourceLocation(); 468} 469 470//===----------------------------------------------------------------------===// 471// TemplateTemplateParmDecl Method Implementations 472//===----------------------------------------------------------------------===// 473 474TemplateTemplateParmDecl * 475TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 476 SourceLocation L, unsigned D, unsigned P, 477 bool ParameterPack, IdentifierInfo *Id, 478 TemplateParameterList *Params) { 479 return new (C) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 480 Params); 481} 482 483//===----------------------------------------------------------------------===// 484// TemplateArgumentList Implementation 485//===----------------------------------------------------------------------===// 486TemplateArgumentList * 487TemplateArgumentList::CreateCopy(ASTContext &Context, 488 const TemplateArgument *Args, 489 unsigned NumArgs) { 490 std::size_t Size = sizeof(TemplateArgumentList) 491 + NumArgs * sizeof(TemplateArgument); 492 void *Mem = Context.Allocate(Size); 493 TemplateArgument *StoredArgs 494 = reinterpret_cast<TemplateArgument *>( 495 static_cast<TemplateArgumentList *>(Mem) + 1); 496 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs); 497 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true); 498} 499 500//===----------------------------------------------------------------------===// 501// ClassTemplateSpecializationDecl Implementation 502//===----------------------------------------------------------------------===// 503ClassTemplateSpecializationDecl:: 504ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 505 DeclContext *DC, SourceLocation L, 506 ClassTemplateDecl *SpecializedTemplate, 507 const TemplateArgument *Args, 508 unsigned NumArgs, 509 ClassTemplateSpecializationDecl *PrevDecl) 510 : CXXRecordDecl(DK, TK, DC, L, 511 SpecializedTemplate->getIdentifier(), 512 PrevDecl), 513 SpecializedTemplate(SpecializedTemplate), 514 ExplicitInfo(0), 515 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 516 SpecializationKind(TSK_Undeclared) { 517} 518 519ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK) 520 : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), 0, 0), 521 ExplicitInfo(0), 522 SpecializationKind(TSK_Undeclared) { 523} 524 525ClassTemplateSpecializationDecl * 526ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 527 DeclContext *DC, SourceLocation L, 528 ClassTemplateDecl *SpecializedTemplate, 529 const TemplateArgument *Args, 530 unsigned NumArgs, 531 ClassTemplateSpecializationDecl *PrevDecl) { 532 ClassTemplateSpecializationDecl *Result 533 = new (Context)ClassTemplateSpecializationDecl(Context, 534 ClassTemplateSpecialization, 535 TK, DC, L, 536 SpecializedTemplate, 537 Args, NumArgs, 538 PrevDecl); 539 Context.getTypeDeclType(Result, PrevDecl); 540 return Result; 541} 542 543ClassTemplateSpecializationDecl * 544ClassTemplateSpecializationDecl::Create(ASTContext &Context, EmptyShell Empty) { 545 return 546 new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization); 547} 548 549void 550ClassTemplateSpecializationDecl::getNameForDiagnostic(std::string &S, 551 const PrintingPolicy &Policy, 552 bool Qualified) const { 553 NamedDecl::getNameForDiagnostic(S, Policy, Qualified); 554 555 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 556 S += TemplateSpecializationType::PrintTemplateArgumentList( 557 TemplateArgs.data(), 558 TemplateArgs.size(), 559 Policy); 560} 561 562ClassTemplateDecl * 563ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 564 if (SpecializedPartialSpecialization *PartialSpec 565 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 566 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 567 return SpecializedTemplate.get<ClassTemplateDecl*>(); 568} 569 570//===----------------------------------------------------------------------===// 571// ClassTemplatePartialSpecializationDecl Implementation 572//===----------------------------------------------------------------------===// 573ClassTemplatePartialSpecializationDecl * 574ClassTemplatePartialSpecializationDecl:: 575Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L, 576 TemplateParameterList *Params, 577 ClassTemplateDecl *SpecializedTemplate, 578 const TemplateArgument *Args, 579 unsigned NumArgs, 580 const TemplateArgumentListInfo &ArgInfos, 581 QualType CanonInjectedType, 582 ClassTemplatePartialSpecializationDecl *PrevDecl, 583 unsigned SequenceNumber) { 584 unsigned N = ArgInfos.size(); 585 TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N]; 586 for (unsigned I = 0; I != N; ++I) 587 ClonedArgs[I] = ArgInfos[I]; 588 589 ClassTemplatePartialSpecializationDecl *Result 590 = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, 591 DC, L, Params, 592 SpecializedTemplate, 593 Args, NumArgs, 594 ClonedArgs, N, 595 PrevDecl, 596 SequenceNumber); 597 Result->setSpecializationKind(TSK_ExplicitSpecialization); 598 599 Context.getInjectedClassNameType(Result, CanonInjectedType); 600 return Result; 601} 602 603ClassTemplatePartialSpecializationDecl * 604ClassTemplatePartialSpecializationDecl::Create(ASTContext &Context, 605 EmptyShell Empty) { 606 return new (Context)ClassTemplatePartialSpecializationDecl(); 607} 608 609//===----------------------------------------------------------------------===// 610// FriendTemplateDecl Implementation 611//===----------------------------------------------------------------------===// 612 613FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 614 DeclContext *DC, 615 SourceLocation L, 616 unsigned NParams, 617 TemplateParameterList **Params, 618 FriendUnion Friend, 619 SourceLocation FLoc) { 620 FriendTemplateDecl *Result 621 = new (Context) FriendTemplateDecl(DC, L, NParams, Params, Friend, FLoc); 622 return Result; 623} 624 625FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 626 EmptyShell Empty) { 627 return new (Context) FriendTemplateDecl(Empty); 628} 629