DeclTemplate.cpp revision 6bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89
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/DeclTemplate.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/AST/ASTMutationListener.h" 17#include "clang/AST/DeclCXX.h" 18#include "clang/AST/Expr.h" 19#include "clang/AST/ExprCXX.h" 20#include "clang/AST/TypeLoc.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), ContainsUnexpandedParameterPack(false) { 36 assert(this->NumParams == NumParams && "Too many template parameters"); 37 for (unsigned Idx = 0; Idx < NumParams; ++Idx) { 38 NamedDecl *P = Params[Idx]; 39 begin()[Idx] = P; 40 41 if (!P->isTemplateParameterPack()) { 42 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) 43 if (NTTP->getType()->containsUnexpandedParameterPack()) 44 ContainsUnexpandedParameterPack = true; 45 46 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) 47 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack()) 48 ContainsUnexpandedParameterPack = true; 49 50 // FIXME: If a default argument contains an unexpanded parameter pack, the 51 // template parameter list does too. 52 } 53 } 54} 55 56TemplateParameterList * 57TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, 58 SourceLocation LAngleLoc, NamedDecl **Params, 59 unsigned NumParams, SourceLocation RAngleLoc) { 60 unsigned Size = sizeof(TemplateParameterList) 61 + sizeof(NamedDecl *) * NumParams; 62 unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(), 63 llvm::alignOf<NamedDecl*>()); 64 void *Mem = C.Allocate(Size, Align); 65 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 66 NumParams, RAngleLoc); 67} 68 69unsigned TemplateParameterList::getMinRequiredArguments() const { 70 unsigned NumRequiredArgs = 0; 71 for (iterator P = const_cast<TemplateParameterList *>(this)->begin(), 72 PEnd = const_cast<TemplateParameterList *>(this)->end(); 73 P != PEnd; ++P) { 74 if ((*P)->isTemplateParameterPack()) { 75 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) 76 if (NTTP->isExpandedParameterPack()) { 77 NumRequiredArgs += NTTP->getNumExpansionTypes(); 78 continue; 79 } 80 81 break; 82 } 83 84 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) { 85 if (TTP->hasDefaultArgument()) 86 break; 87 } else if (NonTypeTemplateParmDecl *NTTP 88 = dyn_cast<NonTypeTemplateParmDecl>(*P)) { 89 if (NTTP->hasDefaultArgument()) 90 break; 91 } else if (cast<TemplateTemplateParmDecl>(*P)->hasDefaultArgument()) 92 break; 93 94 ++NumRequiredArgs; 95 } 96 97 return NumRequiredArgs; 98} 99 100unsigned TemplateParameterList::getDepth() const { 101 if (size() == 0) 102 return 0; 103 104 const NamedDecl *FirstParm = getParam(0); 105 if (const TemplateTypeParmDecl *TTP 106 = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 107 return TTP->getDepth(); 108 else if (const NonTypeTemplateParmDecl *NTTP 109 = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 110 return NTTP->getDepth(); 111 else 112 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 113} 114 115static void AdoptTemplateParameterList(TemplateParameterList *Params, 116 DeclContext *Owner) { 117 for (TemplateParameterList::iterator P = Params->begin(), 118 PEnd = Params->end(); 119 P != PEnd; ++P) { 120 (*P)->setDeclContext(Owner); 121 122 if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(*P)) 123 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner); 124 } 125} 126 127//===----------------------------------------------------------------------===// 128// RedeclarableTemplateDecl Implementation 129//===----------------------------------------------------------------------===// 130 131RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const { 132 if (Common) 133 return Common; 134 135 // Walk the previous-declaration chain until we either find a declaration 136 // with a common pointer or we run out of previous declarations. 137 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls; 138 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; 139 Prev = Prev->getPreviousDecl()) { 140 if (Prev->Common) { 141 Common = Prev->Common; 142 break; 143 } 144 145 PrevDecls.push_back(Prev); 146 } 147 148 // If we never found a common pointer, allocate one now. 149 if (!Common) { 150 // FIXME: If any of the declarations is from an AST file, we probably 151 // need an update record to add the common data. 152 153 Common = newCommon(getASTContext()); 154 } 155 156 // Update any previous declarations we saw with the common pointer. 157 for (unsigned I = 0, N = PrevDecls.size(); I != N; ++I) 158 PrevDecls[I]->Common = Common; 159 160 return Common; 161} 162 163template <class EntryType> 164typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType* 165RedeclarableTemplateDecl::findSpecializationImpl( 166 llvm::FoldingSetVector<EntryType> &Specs, 167 const TemplateArgument *Args, unsigned NumArgs, 168 void *&InsertPos) { 169 typedef SpecEntryTraits<EntryType> SETraits; 170 llvm::FoldingSetNodeID ID; 171 EntryType::Profile(ID,Args,NumArgs, getASTContext()); 172 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 173 return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr; 174} 175 176/// \brief Generate the injected template arguments for the given template 177/// parameter list, e.g., for the injected-class-name of a class template. 178static void GenerateInjectedTemplateArgs(ASTContext &Context, 179 TemplateParameterList *Params, 180 TemplateArgument *Args) { 181 for (TemplateParameterList::iterator Param = Params->begin(), 182 ParamEnd = Params->end(); 183 Param != ParamEnd; ++Param) { 184 TemplateArgument Arg; 185 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { 186 QualType ArgType = Context.getTypeDeclType(TTP); 187 if (TTP->isParameterPack()) 188 ArgType = Context.getPackExpansionType(ArgType, None); 189 190 Arg = TemplateArgument(ArgType); 191 } else if (NonTypeTemplateParmDecl *NTTP = 192 dyn_cast<NonTypeTemplateParmDecl>(*Param)) { 193 Expr *E = new (Context) DeclRefExpr(NTTP, /*enclosing*/ false, 194 NTTP->getType().getNonLValueExprType(Context), 195 Expr::getValueKindForType(NTTP->getType()), 196 NTTP->getLocation()); 197 198 if (NTTP->isParameterPack()) 199 E = new (Context) PackExpansionExpr(Context.DependentTy, E, 200 NTTP->getLocation(), None); 201 Arg = TemplateArgument(E); 202 } else { 203 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*Param); 204 if (TTP->isParameterPack()) 205 Arg = TemplateArgument(TemplateName(TTP), Optional<unsigned>()); 206 else 207 Arg = TemplateArgument(TemplateName(TTP)); 208 } 209 210 if ((*Param)->isTemplateParameterPack()) 211 Arg = TemplateArgument::CreatePackCopy(Context, &Arg, 1); 212 213 *Args++ = Arg; 214 } 215} 216 217//===----------------------------------------------------------------------===// 218// FunctionTemplateDecl Implementation 219//===----------------------------------------------------------------------===// 220 221void FunctionTemplateDecl::DeallocateCommon(void *Ptr) { 222 static_cast<Common *>(Ptr)->~Common(); 223} 224 225FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 226 DeclContext *DC, 227 SourceLocation L, 228 DeclarationName Name, 229 TemplateParameterList *Params, 230 NamedDecl *Decl) { 231 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 232 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl); 233} 234 235FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, 236 unsigned ID) { 237 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), 238 DeclarationName(), nullptr, nullptr); 239} 240 241RedeclarableTemplateDecl::CommonBase * 242FunctionTemplateDecl::newCommon(ASTContext &C) const { 243 Common *CommonPtr = new (C) Common; 244 C.AddDeallocation(DeallocateCommon, CommonPtr); 245 return CommonPtr; 246} 247 248void FunctionTemplateDecl::LoadLazySpecializations() const { 249 Common *CommonPtr = getCommonPtr(); 250 if (CommonPtr->LazySpecializations) { 251 ASTContext &Context = getASTContext(); 252 uint32_t *Specs = CommonPtr->LazySpecializations; 253 CommonPtr->LazySpecializations = nullptr; 254 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 255 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 256 } 257} 258 259llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & 260FunctionTemplateDecl::getSpecializations() const { 261 LoadLazySpecializations(); 262 return getCommonPtr()->Specializations; 263} 264 265FunctionDecl * 266FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args, 267 unsigned NumArgs, void *&InsertPos) { 268 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 269} 270 271void FunctionTemplateDecl::addSpecialization( 272 FunctionTemplateSpecializationInfo *Info, void *InsertPos) { 273 if (InsertPos) 274 getSpecializations().InsertNode(Info, InsertPos); 275 else 276 getSpecializations().GetOrInsertNode(Info); 277 if (ASTMutationListener *L = getASTMutationListener()) 278 L->AddedCXXTemplateSpecialization(this, Info->Function); 279} 280 281ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() { 282 TemplateParameterList *Params = getTemplateParameters(); 283 Common *CommonPtr = getCommonPtr(); 284 if (!CommonPtr->InjectedArgs) { 285 CommonPtr->InjectedArgs 286 = new (getASTContext()) TemplateArgument[Params->size()]; 287 GenerateInjectedTemplateArgs(getASTContext(), Params, 288 CommonPtr->InjectedArgs); 289 } 290 291 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size()); 292} 293 294//===----------------------------------------------------------------------===// 295// ClassTemplateDecl Implementation 296//===----------------------------------------------------------------------===// 297 298void ClassTemplateDecl::DeallocateCommon(void *Ptr) { 299 static_cast<Common *>(Ptr)->~Common(); 300} 301 302ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 303 DeclContext *DC, 304 SourceLocation L, 305 DeclarationName Name, 306 TemplateParameterList *Params, 307 NamedDecl *Decl, 308 ClassTemplateDecl *PrevDecl) { 309 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 310 ClassTemplateDecl *New = new (C, DC) ClassTemplateDecl(C, DC, L, Name, 311 Params, Decl); 312 New->setPreviousDecl(PrevDecl); 313 return New; 314} 315 316ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 317 unsigned ID) { 318 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), 319 DeclarationName(), nullptr, nullptr); 320} 321 322void ClassTemplateDecl::LoadLazySpecializations() const { 323 Common *CommonPtr = getCommonPtr(); 324 if (CommonPtr->LazySpecializations) { 325 ASTContext &Context = getASTContext(); 326 uint32_t *Specs = CommonPtr->LazySpecializations; 327 CommonPtr->LazySpecializations = nullptr; 328 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 329 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 330 } 331} 332 333llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 334ClassTemplateDecl::getSpecializations() const { 335 LoadLazySpecializations(); 336 return getCommonPtr()->Specializations; 337} 338 339llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 340ClassTemplateDecl::getPartialSpecializations() { 341 LoadLazySpecializations(); 342 return getCommonPtr()->PartialSpecializations; 343} 344 345RedeclarableTemplateDecl::CommonBase * 346ClassTemplateDecl::newCommon(ASTContext &C) const { 347 Common *CommonPtr = new (C) Common; 348 C.AddDeallocation(DeallocateCommon, CommonPtr); 349 return CommonPtr; 350} 351 352ClassTemplateSpecializationDecl * 353ClassTemplateDecl::findSpecialization(const TemplateArgument *Args, 354 unsigned NumArgs, void *&InsertPos) { 355 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 356} 357 358void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 359 void *InsertPos) { 360 if (InsertPos) 361 getSpecializations().InsertNode(D, InsertPos); 362 else { 363 ClassTemplateSpecializationDecl *Existing 364 = getSpecializations().GetOrInsertNode(D); 365 (void)Existing; 366 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 367 } 368 if (ASTMutationListener *L = getASTMutationListener()) 369 L->AddedCXXTemplateSpecialization(this, D); 370} 371 372ClassTemplatePartialSpecializationDecl * 373ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, 374 unsigned NumArgs, 375 void *&InsertPos) { 376 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, 377 InsertPos); 378} 379 380void ClassTemplateDecl::AddPartialSpecialization( 381 ClassTemplatePartialSpecializationDecl *D, 382 void *InsertPos) { 383 if (InsertPos) 384 getPartialSpecializations().InsertNode(D, InsertPos); 385 else { 386 ClassTemplatePartialSpecializationDecl *Existing 387 = getPartialSpecializations().GetOrInsertNode(D); 388 (void)Existing; 389 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 390 } 391 392 if (ASTMutationListener *L = getASTMutationListener()) 393 L->AddedCXXTemplateSpecialization(this, D); 394} 395 396void ClassTemplateDecl::getPartialSpecializations( 397 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 398 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs 399 = getPartialSpecializations(); 400 PS.clear(); 401 PS.reserve(PartialSpecs.size()); 402 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 403 P = PartialSpecs.begin(), PEnd = PartialSpecs.end(); 404 P != PEnd; ++P) 405 PS.push_back(P->getMostRecentDecl()); 406} 407 408ClassTemplatePartialSpecializationDecl * 409ClassTemplateDecl::findPartialSpecialization(QualType T) { 410 ASTContext &Context = getASTContext(); 411 using llvm::FoldingSetVector; 412 typedef FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 413 partial_spec_iterator; 414 for (partial_spec_iterator P = getPartialSpecializations().begin(), 415 PEnd = getPartialSpecializations().end(); 416 P != PEnd; ++P) { 417 if (Context.hasSameType(P->getInjectedSpecializationType(), T)) 418 return P->getMostRecentDecl(); 419 } 420 421 return nullptr; 422} 423 424ClassTemplatePartialSpecializationDecl * 425ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 426 ClassTemplatePartialSpecializationDecl *D) { 427 Decl *DCanon = D->getCanonicalDecl(); 428 for (llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>::iterator 429 P = getPartialSpecializations().begin(), 430 PEnd = getPartialSpecializations().end(); 431 P != PEnd; ++P) { 432 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 433 return P->getMostRecentDecl(); 434 } 435 436 return nullptr; 437} 438 439QualType 440ClassTemplateDecl::getInjectedClassNameSpecialization() { 441 Common *CommonPtr = getCommonPtr(); 442 if (!CommonPtr->InjectedClassNameType.isNull()) 443 return CommonPtr->InjectedClassNameType; 444 445 // C++0x [temp.dep.type]p2: 446 // The template argument list of a primary template is a template argument 447 // list in which the nth template argument has the value of the nth template 448 // parameter of the class template. If the nth template parameter is a 449 // template parameter pack (14.5.3), the nth template argument is a pack 450 // expansion (14.5.3) whose pattern is the name of the template parameter 451 // pack. 452 ASTContext &Context = getASTContext(); 453 TemplateParameterList *Params = getTemplateParameters(); 454 SmallVector<TemplateArgument, 16> TemplateArgs; 455 TemplateArgs.resize(Params->size()); 456 GenerateInjectedTemplateArgs(getASTContext(), Params, TemplateArgs.data()); 457 CommonPtr->InjectedClassNameType 458 = Context.getTemplateSpecializationType(TemplateName(this), 459 &TemplateArgs[0], 460 TemplateArgs.size()); 461 return CommonPtr->InjectedClassNameType; 462} 463 464//===----------------------------------------------------------------------===// 465// TemplateTypeParm Allocation/Deallocation Method Implementations 466//===----------------------------------------------------------------------===// 467 468TemplateTypeParmDecl * 469TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 470 SourceLocation KeyLoc, SourceLocation NameLoc, 471 unsigned D, unsigned P, IdentifierInfo *Id, 472 bool Typename, bool ParameterPack) { 473 TemplateTypeParmDecl *TTPDecl = 474 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename); 475 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 476 TTPDecl->setTypeForDecl(TTPType.getTypePtr()); 477 return TTPDecl; 478} 479 480TemplateTypeParmDecl * 481TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 482 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), 483 SourceLocation(), nullptr, false); 484} 485 486SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 487 return hasDefaultArgument() 488 ? DefaultArgument->getTypeLoc().getBeginLoc() 489 : SourceLocation(); 490} 491 492SourceRange TemplateTypeParmDecl::getSourceRange() const { 493 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 494 return SourceRange(getLocStart(), 495 DefaultArgument->getTypeLoc().getEndLoc()); 496 else 497 return TypeDecl::getSourceRange(); 498} 499 500unsigned TemplateTypeParmDecl::getDepth() const { 501 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth(); 502} 503 504unsigned TemplateTypeParmDecl::getIndex() const { 505 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex(); 506} 507 508bool TemplateTypeParmDecl::isParameterPack() const { 509 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack(); 510} 511 512//===----------------------------------------------------------------------===// 513// NonTypeTemplateParmDecl Method Implementations 514//===----------------------------------------------------------------------===// 515 516NonTypeTemplateParmDecl::NonTypeTemplateParmDecl(DeclContext *DC, 517 SourceLocation StartLoc, 518 SourceLocation IdLoc, 519 unsigned D, unsigned P, 520 IdentifierInfo *Id, 521 QualType T, 522 TypeSourceInfo *TInfo, 523 const QualType *ExpandedTypes, 524 unsigned NumExpandedTypes, 525 TypeSourceInfo **ExpandedTInfos) 526 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 527 TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false), 528 ParameterPack(true), ExpandedParameterPack(true), 529 NumExpandedTypes(NumExpandedTypes) 530{ 531 if (ExpandedTypes && ExpandedTInfos) { 532 void **TypesAndInfos = reinterpret_cast<void **>(this + 1); 533 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 534 TypesAndInfos[2*I] = ExpandedTypes[I].getAsOpaquePtr(); 535 TypesAndInfos[2*I + 1] = ExpandedTInfos[I]; 536 } 537 } 538} 539 540NonTypeTemplateParmDecl * 541NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 542 SourceLocation StartLoc, SourceLocation IdLoc, 543 unsigned D, unsigned P, IdentifierInfo *Id, 544 QualType T, bool ParameterPack, 545 TypeSourceInfo *TInfo) { 546 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 547 T, ParameterPack, TInfo); 548} 549 550NonTypeTemplateParmDecl * 551NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 552 SourceLocation StartLoc, SourceLocation IdLoc, 553 unsigned D, unsigned P, 554 IdentifierInfo *Id, QualType T, 555 TypeSourceInfo *TInfo, 556 const QualType *ExpandedTypes, 557 unsigned NumExpandedTypes, 558 TypeSourceInfo **ExpandedTInfos) { 559 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*); 560 return new (C, DC, Extra) NonTypeTemplateParmDecl( 561 DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 562 ExpandedTypes, NumExpandedTypes, ExpandedTInfos); 563} 564 565NonTypeTemplateParmDecl * 566NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 567 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(), 568 SourceLocation(), 0, 0, nullptr, 569 QualType(), false, nullptr); 570} 571 572NonTypeTemplateParmDecl * 573NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 574 unsigned NumExpandedTypes) { 575 unsigned Extra = NumExpandedTypes * 2 * sizeof(void*); 576 return new (C, ID, Extra) NonTypeTemplateParmDecl( 577 nullptr, SourceLocation(), SourceLocation(), 0, 0, nullptr, QualType(), 578 nullptr, nullptr, NumExpandedTypes, nullptr); 579} 580 581SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 582 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 583 return SourceRange(getOuterLocStart(), 584 getDefaultArgument()->getSourceRange().getEnd()); 585 return DeclaratorDecl::getSourceRange(); 586} 587 588SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 589 return hasDefaultArgument() 590 ? getDefaultArgument()->getSourceRange().getBegin() 591 : SourceLocation(); 592} 593 594//===----------------------------------------------------------------------===// 595// TemplateTemplateParmDecl Method Implementations 596//===----------------------------------------------------------------------===// 597 598void TemplateTemplateParmDecl::anchor() { } 599 600TemplateTemplateParmDecl::TemplateTemplateParmDecl( 601 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 602 IdentifierInfo *Id, TemplateParameterList *Params, 603 unsigned NumExpansions, TemplateParameterList * const *Expansions) 604 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 605 TemplateParmPosition(D, P), DefaultArgument(), 606 DefaultArgumentWasInherited(false), ParameterPack(true), 607 ExpandedParameterPack(true), NumExpandedParams(NumExpansions) { 608 if (Expansions) 609 std::memcpy(reinterpret_cast<void*>(this + 1), Expansions, 610 sizeof(TemplateParameterList*) * NumExpandedParams); 611} 612 613TemplateTemplateParmDecl * 614TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 615 SourceLocation L, unsigned D, unsigned P, 616 bool ParameterPack, IdentifierInfo *Id, 617 TemplateParameterList *Params) { 618 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 619 Params); 620} 621 622TemplateTemplateParmDecl * 623TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 624 SourceLocation L, unsigned D, unsigned P, 625 IdentifierInfo *Id, 626 TemplateParameterList *Params, 627 ArrayRef<TemplateParameterList *> Expansions) { 628 return new (C, DC, sizeof(TemplateParameterList*) * Expansions.size()) 629 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, 630 Expansions.size(), Expansions.data()); 631} 632 633TemplateTemplateParmDecl * 634TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 635 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 636 false, nullptr, nullptr); 637} 638 639TemplateTemplateParmDecl * 640TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 641 unsigned NumExpansions) { 642 return new (C, ID, sizeof(TemplateParameterList*) * NumExpansions) 643 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 644 nullptr, NumExpansions, nullptr); 645} 646 647//===----------------------------------------------------------------------===// 648// TemplateArgumentList Implementation 649//===----------------------------------------------------------------------===// 650TemplateArgumentList * 651TemplateArgumentList::CreateCopy(ASTContext &Context, 652 const TemplateArgument *Args, 653 unsigned NumArgs) { 654 std::size_t Size = sizeof(TemplateArgumentList) 655 + NumArgs * sizeof(TemplateArgument); 656 void *Mem = Context.Allocate(Size); 657 TemplateArgument *StoredArgs 658 = reinterpret_cast<TemplateArgument *>( 659 static_cast<TemplateArgumentList *>(Mem) + 1); 660 std::uninitialized_copy(Args, Args + NumArgs, StoredArgs); 661 return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true); 662} 663 664FunctionTemplateSpecializationInfo * 665FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 666 FunctionTemplateDecl *Template, 667 TemplateSpecializationKind TSK, 668 const TemplateArgumentList *TemplateArgs, 669 const TemplateArgumentListInfo *TemplateArgsAsWritten, 670 SourceLocation POI) { 671 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 672 if (TemplateArgsAsWritten) 673 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 674 *TemplateArgsAsWritten); 675 676 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 677 TemplateArgs, 678 ArgsAsWritten, 679 POI); 680} 681 682//===----------------------------------------------------------------------===// 683// TemplateDecl Implementation 684//===----------------------------------------------------------------------===// 685 686void TemplateDecl::anchor() { } 687 688//===----------------------------------------------------------------------===// 689// ClassTemplateSpecializationDecl Implementation 690//===----------------------------------------------------------------------===// 691ClassTemplateSpecializationDecl:: 692ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 693 DeclContext *DC, SourceLocation StartLoc, 694 SourceLocation IdLoc, 695 ClassTemplateDecl *SpecializedTemplate, 696 const TemplateArgument *Args, 697 unsigned NumArgs, 698 ClassTemplateSpecializationDecl *PrevDecl) 699 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 700 SpecializedTemplate->getIdentifier(), 701 PrevDecl), 702 SpecializedTemplate(SpecializedTemplate), 703 ExplicitInfo(nullptr), 704 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 705 SpecializationKind(TSK_Undeclared) { 706} 707 708ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 709 Kind DK) 710 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(), 711 SourceLocation(), nullptr, nullptr), 712 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {} 713 714ClassTemplateSpecializationDecl * 715ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 716 DeclContext *DC, 717 SourceLocation StartLoc, 718 SourceLocation IdLoc, 719 ClassTemplateDecl *SpecializedTemplate, 720 const TemplateArgument *Args, 721 unsigned NumArgs, 722 ClassTemplateSpecializationDecl *PrevDecl) { 723 ClassTemplateSpecializationDecl *Result = 724 new (Context, DC) ClassTemplateSpecializationDecl( 725 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 726 SpecializedTemplate, Args, NumArgs, PrevDecl); 727 Result->MayHaveOutOfDateDef = false; 728 729 Context.getTypeDeclType(Result, PrevDecl); 730 return Result; 731} 732 733ClassTemplateSpecializationDecl * 734ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 735 unsigned ID) { 736 ClassTemplateSpecializationDecl *Result = 737 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 738 Result->MayHaveOutOfDateDef = false; 739 return Result; 740} 741 742void ClassTemplateSpecializationDecl::getNameForDiagnostic( 743 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 744 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 745 746 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 747 TemplateSpecializationType::PrintTemplateArgumentList( 748 OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 749} 750 751ClassTemplateDecl * 752ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 753 if (SpecializedPartialSpecialization *PartialSpec 754 = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 755 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 756 return SpecializedTemplate.get<ClassTemplateDecl*>(); 757} 758 759SourceRange 760ClassTemplateSpecializationDecl::getSourceRange() const { 761 if (ExplicitInfo) { 762 SourceLocation Begin = getTemplateKeywordLoc(); 763 if (Begin.isValid()) { 764 // Here we have an explicit (partial) specialization or instantiation. 765 assert(getSpecializationKind() == TSK_ExplicitSpecialization || 766 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 767 getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 768 if (getExternLoc().isValid()) 769 Begin = getExternLoc(); 770 SourceLocation End = getRBraceLoc(); 771 if (End.isInvalid()) 772 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 773 return SourceRange(Begin, End); 774 } 775 // An implicit instantiation of a class template partial specialization 776 // uses ExplicitInfo to record the TypeAsWritten, but the source 777 // locations should be retrieved from the instantiation pattern. 778 typedef ClassTemplatePartialSpecializationDecl CTPSDecl; 779 CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this)); 780 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 781 assert(inst_from != nullptr); 782 return inst_from->getSourceRange(); 783 } 784 else { 785 // No explicit info available. 786 llvm::PointerUnion<ClassTemplateDecl *, 787 ClassTemplatePartialSpecializationDecl *> 788 inst_from = getInstantiatedFrom(); 789 if (inst_from.isNull()) 790 return getSpecializedTemplate()->getSourceRange(); 791 if (ClassTemplateDecl *ctd = inst_from.dyn_cast<ClassTemplateDecl*>()) 792 return ctd->getSourceRange(); 793 return inst_from.get<ClassTemplatePartialSpecializationDecl*>() 794 ->getSourceRange(); 795 } 796} 797 798//===----------------------------------------------------------------------===// 799// ClassTemplatePartialSpecializationDecl Implementation 800//===----------------------------------------------------------------------===// 801void ClassTemplatePartialSpecializationDecl::anchor() { } 802 803ClassTemplatePartialSpecializationDecl:: 804ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 805 DeclContext *DC, 806 SourceLocation StartLoc, 807 SourceLocation IdLoc, 808 TemplateParameterList *Params, 809 ClassTemplateDecl *SpecializedTemplate, 810 const TemplateArgument *Args, 811 unsigned NumArgs, 812 const ASTTemplateArgumentListInfo *ArgInfos, 813 ClassTemplatePartialSpecializationDecl *PrevDecl) 814 : ClassTemplateSpecializationDecl(Context, 815 ClassTemplatePartialSpecialization, 816 TK, DC, StartLoc, IdLoc, 817 SpecializedTemplate, 818 Args, NumArgs, PrevDecl), 819 TemplateParams(Params), ArgsAsWritten(ArgInfos), 820 InstantiatedFromMember(nullptr, false) 821{ 822 AdoptTemplateParameterList(Params, this); 823} 824 825ClassTemplatePartialSpecializationDecl * 826ClassTemplatePartialSpecializationDecl:: 827Create(ASTContext &Context, TagKind TK,DeclContext *DC, 828 SourceLocation StartLoc, SourceLocation IdLoc, 829 TemplateParameterList *Params, 830 ClassTemplateDecl *SpecializedTemplate, 831 const TemplateArgument *Args, 832 unsigned NumArgs, 833 const TemplateArgumentListInfo &ArgInfos, 834 QualType CanonInjectedType, 835 ClassTemplatePartialSpecializationDecl *PrevDecl) { 836 const ASTTemplateArgumentListInfo *ASTArgInfos = 837 ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 838 839 ClassTemplatePartialSpecializationDecl *Result = new (Context, DC) 840 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, 841 Params, SpecializedTemplate, Args, 842 NumArgs, ASTArgInfos, PrevDecl); 843 Result->setSpecializationKind(TSK_ExplicitSpecialization); 844 Result->MayHaveOutOfDateDef = false; 845 846 Context.getInjectedClassNameType(Result, CanonInjectedType); 847 return Result; 848} 849 850ClassTemplatePartialSpecializationDecl * 851ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 852 unsigned ID) { 853 ClassTemplatePartialSpecializationDecl *Result = 854 new (C, ID) ClassTemplatePartialSpecializationDecl(C); 855 Result->MayHaveOutOfDateDef = false; 856 return Result; 857} 858 859//===----------------------------------------------------------------------===// 860// FriendTemplateDecl Implementation 861//===----------------------------------------------------------------------===// 862 863void FriendTemplateDecl::anchor() { } 864 865FriendTemplateDecl *FriendTemplateDecl::Create(ASTContext &Context, 866 DeclContext *DC, 867 SourceLocation L, 868 unsigned NParams, 869 TemplateParameterList **Params, 870 FriendUnion Friend, 871 SourceLocation FLoc) { 872 return new (Context, DC) FriendTemplateDecl(DC, L, NParams, Params, 873 Friend, FLoc); 874} 875 876FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 877 unsigned ID) { 878 return new (C, ID) FriendTemplateDecl(EmptyShell()); 879} 880 881//===----------------------------------------------------------------------===// 882// TypeAliasTemplateDecl Implementation 883//===----------------------------------------------------------------------===// 884 885TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 886 DeclContext *DC, 887 SourceLocation L, 888 DeclarationName Name, 889 TemplateParameterList *Params, 890 NamedDecl *Decl) { 891 AdoptTemplateParameterList(Params, DC); 892 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 893} 894 895TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 896 unsigned ID) { 897 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 898 DeclarationName(), nullptr, nullptr); 899} 900 901void TypeAliasTemplateDecl::DeallocateCommon(void *Ptr) { 902 static_cast<Common *>(Ptr)->~Common(); 903} 904RedeclarableTemplateDecl::CommonBase * 905TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 906 Common *CommonPtr = new (C) Common; 907 C.AddDeallocation(DeallocateCommon, CommonPtr); 908 return CommonPtr; 909} 910 911//===----------------------------------------------------------------------===// 912// ClassScopeFunctionSpecializationDecl Implementation 913//===----------------------------------------------------------------------===// 914 915void ClassScopeFunctionSpecializationDecl::anchor() { } 916 917ClassScopeFunctionSpecializationDecl * 918ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 919 unsigned ID) { 920 return new (C, ID) ClassScopeFunctionSpecializationDecl( 921 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo()); 922} 923 924//===----------------------------------------------------------------------===// 925// VarTemplateDecl Implementation 926//===----------------------------------------------------------------------===// 927 928void VarTemplateDecl::DeallocateCommon(void *Ptr) { 929 static_cast<Common *>(Ptr)->~Common(); 930} 931 932VarTemplateDecl *VarTemplateDecl::getDefinition() { 933 VarTemplateDecl *CurD = this; 934 while (CurD) { 935 if (CurD->isThisDeclarationADefinition()) 936 return CurD; 937 CurD = CurD->getPreviousDecl(); 938 } 939 return nullptr; 940} 941 942VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 943 SourceLocation L, DeclarationName Name, 944 TemplateParameterList *Params, 945 VarDecl *Decl) { 946 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 947} 948 949VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 950 unsigned ID) { 951 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 952 DeclarationName(), nullptr, nullptr); 953} 954 955// TODO: Unify across class, function and variable templates? 956// May require moving this and Common to RedeclarableTemplateDecl. 957void VarTemplateDecl::LoadLazySpecializations() const { 958 Common *CommonPtr = getCommonPtr(); 959 if (CommonPtr->LazySpecializations) { 960 ASTContext &Context = getASTContext(); 961 uint32_t *Specs = CommonPtr->LazySpecializations; 962 CommonPtr->LazySpecializations = nullptr; 963 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 964 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 965 } 966} 967 968llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 969VarTemplateDecl::getSpecializations() const { 970 LoadLazySpecializations(); 971 return getCommonPtr()->Specializations; 972} 973 974llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 975VarTemplateDecl::getPartialSpecializations() { 976 LoadLazySpecializations(); 977 return getCommonPtr()->PartialSpecializations; 978} 979 980RedeclarableTemplateDecl::CommonBase * 981VarTemplateDecl::newCommon(ASTContext &C) const { 982 Common *CommonPtr = new (C) Common; 983 C.AddDeallocation(DeallocateCommon, CommonPtr); 984 return CommonPtr; 985} 986 987VarTemplateSpecializationDecl * 988VarTemplateDecl::findSpecialization(const TemplateArgument *Args, 989 unsigned NumArgs, void *&InsertPos) { 990 return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); 991} 992 993void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 994 void *InsertPos) { 995 if (InsertPos) 996 getSpecializations().InsertNode(D, InsertPos); 997 else { 998 VarTemplateSpecializationDecl *Existing = 999 getSpecializations().GetOrInsertNode(D); 1000 (void)Existing; 1001 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1002 } 1003 if (ASTMutationListener *L = getASTMutationListener()) 1004 L->AddedCXXTemplateSpecialization(this, D); 1005} 1006 1007VarTemplatePartialSpecializationDecl * 1008VarTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, 1009 unsigned NumArgs, void *&InsertPos) { 1010 return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, 1011 InsertPos); 1012} 1013 1014void VarTemplateDecl::AddPartialSpecialization( 1015 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1016 if (InsertPos) 1017 getPartialSpecializations().InsertNode(D, InsertPos); 1018 else { 1019 VarTemplatePartialSpecializationDecl *Existing = 1020 getPartialSpecializations().GetOrInsertNode(D); 1021 (void)Existing; 1022 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1023 } 1024 1025 if (ASTMutationListener *L = getASTMutationListener()) 1026 L->AddedCXXTemplateSpecialization(this, D); 1027} 1028 1029void VarTemplateDecl::getPartialSpecializations( 1030 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) { 1031 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1032 getPartialSpecializations(); 1033 PS.clear(); 1034 PS.reserve(PartialSpecs.size()); 1035 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 1036 P = PartialSpecs.begin(), 1037 PEnd = PartialSpecs.end(); 1038 P != PEnd; ++P) 1039 PS.push_back(P->getMostRecentDecl()); 1040} 1041 1042VarTemplatePartialSpecializationDecl * 1043VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1044 VarTemplatePartialSpecializationDecl *D) { 1045 Decl *DCanon = D->getCanonicalDecl(); 1046 for (llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>::iterator 1047 P = getPartialSpecializations().begin(), 1048 PEnd = getPartialSpecializations().end(); 1049 P != PEnd; ++P) { 1050 if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1051 return P->getMostRecentDecl(); 1052 } 1053 1054 return nullptr; 1055} 1056 1057//===----------------------------------------------------------------------===// 1058// VarTemplateSpecializationDecl Implementation 1059//===----------------------------------------------------------------------===// 1060VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1061 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1062 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1063 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 1064 unsigned NumArgs) 1065 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 1066 SpecializedTemplate->getIdentifier(), T, TInfo, S), 1067 SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr), 1068 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args, NumArgs)), 1069 SpecializationKind(TSK_Undeclared) {} 1070 1071VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 1072 ASTContext &C) 1073 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 1074 QualType(), nullptr, SC_None), 1075 ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {} 1076 1077VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1078 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1079 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1080 TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, 1081 unsigned NumArgs) { 1082 return new (Context, DC) VarTemplateSpecializationDecl( 1083 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 1084 SpecializedTemplate, T, TInfo, S, Args, NumArgs); 1085} 1086 1087VarTemplateSpecializationDecl * 1088VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1089 return new (C, ID) 1090 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 1091} 1092 1093void VarTemplateSpecializationDecl::getNameForDiagnostic( 1094 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1095 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1096 1097 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1098 TemplateSpecializationType::PrintTemplateArgumentList( 1099 OS, TemplateArgs.data(), TemplateArgs.size(), Policy); 1100} 1101 1102VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1103 if (SpecializedPartialSpecialization *PartialSpec = 1104 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1105 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1106 return SpecializedTemplate.get<VarTemplateDecl *>(); 1107} 1108 1109void VarTemplateSpecializationDecl::setTemplateArgsInfo( 1110 const TemplateArgumentListInfo &ArgsInfo) { 1111 unsigned N = ArgsInfo.size(); 1112 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); 1113 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); 1114 for (unsigned I = 0; I != N; ++I) 1115 TemplateArgsInfo.addArgument(ArgsInfo[I]); 1116} 1117 1118//===----------------------------------------------------------------------===// 1119// VarTemplatePartialSpecializationDecl Implementation 1120//===----------------------------------------------------------------------===// 1121void VarTemplatePartialSpecializationDecl::anchor() {} 1122 1123VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1124 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1125 SourceLocation IdLoc, TemplateParameterList *Params, 1126 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1127 StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 1128 const ASTTemplateArgumentListInfo *ArgInfos) 1129 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 1130 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1131 TInfo, S, Args, NumArgs), 1132 TemplateParams(Params), ArgsAsWritten(ArgInfos), 1133 InstantiatedFromMember(nullptr, false) { 1134 // TODO: The template parameters should be in DC by now. Verify. 1135 // AdoptTemplateParameterList(Params, DC); 1136} 1137 1138VarTemplatePartialSpecializationDecl * 1139VarTemplatePartialSpecializationDecl::Create( 1140 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1141 SourceLocation IdLoc, TemplateParameterList *Params, 1142 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1143 StorageClass S, const TemplateArgument *Args, unsigned NumArgs, 1144 const TemplateArgumentListInfo &ArgInfos) { 1145 const ASTTemplateArgumentListInfo *ASTArgInfos 1146 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1147 1148 VarTemplatePartialSpecializationDecl *Result = 1149 new (Context, DC) VarTemplatePartialSpecializationDecl( 1150 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 1151 S, Args, NumArgs, ASTArgInfos); 1152 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1153 return Result; 1154} 1155 1156VarTemplatePartialSpecializationDecl * 1157VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1158 unsigned ID) { 1159 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 1160} 1161