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