1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the C++ related Decl classes for templates. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/DeclTemplate.h" 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/ASTMutationListener.h" 16 #include "clang/AST/DeclCXX.h" 17 #include "clang/AST/DeclarationName.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/AST/ExprCXX.h" 20 #include "clang/AST/ExternalASTSource.h" 21 #include "clang/AST/ODRHash.h" 22 #include "clang/AST/TemplateBase.h" 23 #include "clang/AST/TemplateName.h" 24 #include "clang/AST/Type.h" 25 #include "clang/AST/TypeLoc.h" 26 #include "clang/Basic/Builtins.h" 27 #include "clang/Basic/LLVM.h" 28 #include "clang/Basic/SourceLocation.h" 29 #include "llvm/ADT/ArrayRef.h" 30 #include "llvm/ADT/FoldingSet.h" 31 #include "llvm/ADT/PointerUnion.h" 32 #include "llvm/ADT/STLExtras.h" 33 #include "llvm/ADT/SmallVector.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include <cassert> 36 #include <optional> 37 #include <utility> 38 39 using namespace clang; 40 41 //===----------------------------------------------------------------------===// 42 // TemplateParameterList Implementation 43 //===----------------------------------------------------------------------===// 44 45 template <class TemplateParam> 46 static bool 47 DefaultTemplateArgumentContainsUnexpandedPack(const TemplateParam &P) { 48 return P.hasDefaultArgument() && 49 P.getDefaultArgument().getArgument().containsUnexpandedParameterPack(); 50 } 51 52 TemplateParameterList::TemplateParameterList(const ASTContext &C, 53 SourceLocation TemplateLoc, 54 SourceLocation LAngleLoc, 55 ArrayRef<NamedDecl *> Params, 56 SourceLocation RAngleLoc, 57 Expr *RequiresClause) 58 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), 59 NumParams(Params.size()), ContainsUnexpandedParameterPack(false), 60 HasRequiresClause(RequiresClause != nullptr), 61 HasConstrainedParameters(false) { 62 for (unsigned Idx = 0; Idx < NumParams; ++Idx) { 63 NamedDecl *P = Params[Idx]; 64 begin()[Idx] = P; 65 66 bool IsPack = P->isTemplateParameterPack(); 67 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) { 68 if (!IsPack && (NTTP->getType()->containsUnexpandedParameterPack() || 69 DefaultTemplateArgumentContainsUnexpandedPack(*NTTP))) 70 ContainsUnexpandedParameterPack = true; 71 if (NTTP->hasPlaceholderTypeConstraint()) 72 HasConstrainedParameters = true; 73 } else if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) { 74 if (!IsPack && 75 (TTP->getTemplateParameters()->containsUnexpandedParameterPack() || 76 DefaultTemplateArgumentContainsUnexpandedPack(*TTP))) { 77 ContainsUnexpandedParameterPack = true; 78 } 79 } else if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) { 80 if (!IsPack && DefaultTemplateArgumentContainsUnexpandedPack(*TTP)) { 81 ContainsUnexpandedParameterPack = true; 82 } else if (const TypeConstraint *TC = TTP->getTypeConstraint(); 83 TC && TC->getImmediatelyDeclaredConstraint() 84 ->containsUnexpandedParameterPack()) { 85 ContainsUnexpandedParameterPack = true; 86 } 87 if (TTP->hasTypeConstraint()) 88 HasConstrainedParameters = true; 89 } else { 90 llvm_unreachable("unexpected template parameter type"); 91 } 92 } 93 94 if (HasRequiresClause) { 95 if (RequiresClause->containsUnexpandedParameterPack()) 96 ContainsUnexpandedParameterPack = true; 97 *getTrailingObjects<Expr *>() = RequiresClause; 98 } 99 } 100 101 bool TemplateParameterList::containsUnexpandedParameterPack() const { 102 if (ContainsUnexpandedParameterPack) 103 return true; 104 if (!HasConstrainedParameters) 105 return false; 106 107 // An implicit constrained parameter might have had a use of an unexpanded 108 // pack added to it after the template parameter list was created. All 109 // implicit parameters are at the end of the parameter list. 110 for (const NamedDecl *Param : llvm::reverse(asArray())) { 111 if (!Param->isImplicit()) 112 break; 113 114 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) { 115 const auto *TC = TTP->getTypeConstraint(); 116 if (TC && TC->getImmediatelyDeclaredConstraint() 117 ->containsUnexpandedParameterPack()) 118 return true; 119 } 120 } 121 122 return false; 123 } 124 125 TemplateParameterList * 126 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, 127 SourceLocation LAngleLoc, 128 ArrayRef<NamedDecl *> Params, 129 SourceLocation RAngleLoc, Expr *RequiresClause) { 130 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>( 131 Params.size(), RequiresClause ? 1u : 0u), 132 alignof(TemplateParameterList)); 133 return new (Mem) TemplateParameterList(C, TemplateLoc, LAngleLoc, Params, 134 RAngleLoc, RequiresClause); 135 } 136 137 void TemplateParameterList::Profile(llvm::FoldingSetNodeID &ID, 138 const ASTContext &C) const { 139 const Expr *RC = getRequiresClause(); 140 ID.AddBoolean(RC != nullptr); 141 if (RC) 142 RC->Profile(ID, C, /*Canonical=*/true); 143 ID.AddInteger(size()); 144 for (NamedDecl *D : *this) { 145 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) { 146 ID.AddInteger(0); 147 ID.AddBoolean(NTTP->isParameterPack()); 148 NTTP->getType().getCanonicalType().Profile(ID); 149 ID.AddBoolean(NTTP->hasPlaceholderTypeConstraint()); 150 if (const Expr *E = NTTP->getPlaceholderTypeConstraint()) 151 E->Profile(ID, C, /*Canonical=*/true); 152 continue; 153 } 154 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) { 155 ID.AddInteger(1); 156 ID.AddBoolean(TTP->isParameterPack()); 157 ID.AddBoolean(TTP->hasTypeConstraint()); 158 if (const TypeConstraint *TC = TTP->getTypeConstraint()) 159 TC->getImmediatelyDeclaredConstraint()->Profile(ID, C, 160 /*Canonical=*/true); 161 continue; 162 } 163 const auto *TTP = cast<TemplateTemplateParmDecl>(D); 164 ID.AddInteger(2); 165 ID.AddBoolean(TTP->isParameterPack()); 166 TTP->getTemplateParameters()->Profile(ID, C); 167 } 168 } 169 170 unsigned TemplateParameterList::getMinRequiredArguments() const { 171 unsigned NumRequiredArgs = 0; 172 for (const NamedDecl *P : asArray()) { 173 if (P->isTemplateParameterPack()) { 174 if (UnsignedOrNone Expansions = getExpandedPackSize(P)) { 175 NumRequiredArgs += *Expansions; 176 continue; 177 } 178 break; 179 } 180 181 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) { 182 if (TTP->hasDefaultArgument()) 183 break; 184 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) { 185 if (NTTP->hasDefaultArgument()) 186 break; 187 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument()) 188 break; 189 190 ++NumRequiredArgs; 191 } 192 193 return NumRequiredArgs; 194 } 195 196 unsigned TemplateParameterList::getDepth() const { 197 if (size() == 0) 198 return 0; 199 200 const NamedDecl *FirstParm = getParam(0); 201 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 202 return TTP->getDepth(); 203 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 204 return NTTP->getDepth(); 205 else 206 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 207 } 208 209 static bool AdoptTemplateParameterList(TemplateParameterList *Params, 210 DeclContext *Owner) { 211 bool Invalid = false; 212 for (NamedDecl *P : *Params) { 213 P->setDeclContext(Owner); 214 215 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) 216 if (AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner)) 217 Invalid = true; 218 219 if (P->isInvalidDecl()) 220 Invalid = true; 221 } 222 return Invalid; 223 } 224 225 void TemplateParameterList::getAssociatedConstraints( 226 llvm::SmallVectorImpl<AssociatedConstraint> &ACs) const { 227 if (HasConstrainedParameters) 228 for (const NamedDecl *Param : *this) { 229 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) { 230 if (const auto *TC = TTP->getTypeConstraint()) 231 ACs.emplace_back(TC->getImmediatelyDeclaredConstraint(), 232 TC->getArgPackSubstIndex()); 233 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) { 234 if (const Expr *E = NTTP->getPlaceholderTypeConstraint()) 235 ACs.emplace_back(E); 236 } 237 } 238 if (HasRequiresClause) 239 ACs.emplace_back(getRequiresClause()); 240 } 241 242 bool TemplateParameterList::hasAssociatedConstraints() const { 243 return HasRequiresClause || HasConstrainedParameters; 244 } 245 246 ArrayRef<TemplateArgument> 247 TemplateParameterList::getInjectedTemplateArgs(const ASTContext &Context) { 248 if (!InjectedArgs) { 249 InjectedArgs = new (Context) TemplateArgument[size()]; 250 llvm::transform(*this, InjectedArgs, [&](NamedDecl *ND) { 251 return Context.getInjectedTemplateArg(ND); 252 }); 253 } 254 return {InjectedArgs, NumParams}; 255 } 256 257 bool TemplateParameterList::shouldIncludeTypeForArgument( 258 const PrintingPolicy &Policy, const TemplateParameterList *TPL, 259 unsigned Idx) { 260 if (!TPL || Idx >= TPL->size() || Policy.AlwaysIncludeTypeForTemplateArgument) 261 return true; 262 const NamedDecl *TemplParam = TPL->getParam(Idx); 263 if (const auto *ParamValueDecl = 264 dyn_cast<NonTypeTemplateParmDecl>(TemplParam)) 265 if (ParamValueDecl->getType()->getContainedDeducedType()) 266 return true; 267 return false; 268 } 269 270 namespace clang { 271 272 void *allocateDefaultArgStorageChain(const ASTContext &C) { 273 return new (C) char[sizeof(void*) * 2]; 274 } 275 276 } // namespace clang 277 278 //===----------------------------------------------------------------------===// 279 // TemplateDecl Implementation 280 //===----------------------------------------------------------------------===// 281 282 TemplateDecl::TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, 283 DeclarationName Name, TemplateParameterList *Params, 284 NamedDecl *Decl) 285 : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(Params) {} 286 287 void TemplateDecl::anchor() {} 288 289 void TemplateDecl::getAssociatedConstraints( 290 llvm::SmallVectorImpl<AssociatedConstraint> &ACs) const { 291 TemplateParams->getAssociatedConstraints(ACs); 292 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl())) 293 if (const AssociatedConstraint &TRC = FD->getTrailingRequiresClause()) 294 ACs.emplace_back(TRC); 295 } 296 297 bool TemplateDecl::hasAssociatedConstraints() const { 298 if (TemplateParams->hasAssociatedConstraints()) 299 return true; 300 if (auto *FD = dyn_cast_or_null<FunctionDecl>(getTemplatedDecl())) 301 return static_cast<bool>(FD->getTrailingRequiresClause()); 302 return false; 303 } 304 305 bool TemplateDecl::isTypeAlias() const { 306 switch (getKind()) { 307 case TemplateDecl::TypeAliasTemplate: 308 case TemplateDecl::BuiltinTemplate: 309 return true; 310 default: 311 return false; 312 }; 313 } 314 315 //===----------------------------------------------------------------------===// 316 // RedeclarableTemplateDecl Implementation 317 //===----------------------------------------------------------------------===// 318 319 void RedeclarableTemplateDecl::anchor() {} 320 321 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const { 322 if (Common) 323 return Common; 324 325 // Walk the previous-declaration chain until we either find a declaration 326 // with a common pointer or we run out of previous declarations. 327 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls; 328 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; 329 Prev = Prev->getPreviousDecl()) { 330 if (Prev->Common) { 331 Common = Prev->Common; 332 break; 333 } 334 335 PrevDecls.push_back(Prev); 336 } 337 338 // If we never found a common pointer, allocate one now. 339 if (!Common) { 340 // FIXME: If any of the declarations is from an AST file, we probably 341 // need an update record to add the common data. 342 343 Common = newCommon(getASTContext()); 344 } 345 346 // Update any previous declarations we saw with the common pointer. 347 for (const RedeclarableTemplateDecl *Prev : PrevDecls) 348 Prev->Common = Common; 349 350 return Common; 351 } 352 353 void RedeclarableTemplateDecl::loadLazySpecializationsImpl( 354 bool OnlyPartial /*=false*/) const { 355 auto *ExternalSource = getASTContext().getExternalSource(); 356 if (!ExternalSource) 357 return; 358 359 ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), 360 OnlyPartial); 361 } 362 363 bool RedeclarableTemplateDecl::loadLazySpecializationsImpl( 364 ArrayRef<TemplateArgument> Args, TemplateParameterList *TPL) const { 365 auto *ExternalSource = getASTContext().getExternalSource(); 366 if (!ExternalSource) 367 return false; 368 369 // If TPL is not null, it implies that we're loading specializations for 370 // partial templates. We need to load all specializations in such cases. 371 if (TPL) 372 return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), 373 /*OnlyPartial=*/false); 374 375 return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), 376 Args); 377 } 378 379 template <class EntryType, typename... ProfileArguments> 380 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * 381 RedeclarableTemplateDecl::findSpecializationLocally( 382 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos, 383 ProfileArguments... ProfileArgs) { 384 using SETraits = RedeclarableTemplateDecl::SpecEntryTraits<EntryType>; 385 386 llvm::FoldingSetNodeID ID; 387 EntryType::Profile(ID, ProfileArgs..., getASTContext()); 388 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 389 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr; 390 } 391 392 template <class EntryType, typename... ProfileArguments> 393 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * 394 RedeclarableTemplateDecl::findSpecializationImpl( 395 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos, 396 ProfileArguments... ProfileArgs) { 397 398 if (auto *Found = findSpecializationLocally(Specs, InsertPos, ProfileArgs...)) 399 return Found; 400 401 if (!loadLazySpecializationsImpl(ProfileArgs...)) 402 return nullptr; 403 404 return findSpecializationLocally(Specs, InsertPos, ProfileArgs...); 405 } 406 407 template<class Derived, class EntryType> 408 void RedeclarableTemplateDecl::addSpecializationImpl( 409 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry, 410 void *InsertPos) { 411 using SETraits = SpecEntryTraits<EntryType>; 412 413 if (InsertPos) { 414 #ifndef NDEBUG 415 auto Args = SETraits::getTemplateArgs(Entry); 416 // Due to hash collisions, it can happen that we load another template 417 // specialization with the same hash. This is fine, as long as the next 418 // call to findSpecializationImpl does not find a matching Decl for the 419 // template arguments. 420 loadLazySpecializationsImpl(Args); 421 void *CorrectInsertPos; 422 assert(!findSpecializationImpl(Specializations, CorrectInsertPos, Args) && 423 InsertPos == CorrectInsertPos && 424 "given incorrect InsertPos for specialization"); 425 #endif 426 Specializations.InsertNode(Entry, InsertPos); 427 } else { 428 EntryType *Existing = Specializations.GetOrInsertNode(Entry); 429 (void)Existing; 430 assert(SETraits::getDecl(Existing)->isCanonicalDecl() && 431 "non-canonical specialization?"); 432 } 433 434 if (ASTMutationListener *L = getASTMutationListener()) 435 L->AddedCXXTemplateSpecialization(cast<Derived>(this), 436 SETraits::getDecl(Entry)); 437 } 438 439 //===----------------------------------------------------------------------===// 440 // FunctionTemplateDecl Implementation 441 //===----------------------------------------------------------------------===// 442 443 FunctionTemplateDecl * 444 FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 445 DeclarationName Name, 446 TemplateParameterList *Params, NamedDecl *Decl) { 447 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 448 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl); 449 if (Invalid) 450 TD->setInvalidDecl(); 451 return TD; 452 } 453 454 FunctionTemplateDecl * 455 FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 456 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), 457 DeclarationName(), nullptr, nullptr); 458 } 459 460 RedeclarableTemplateDecl::CommonBase * 461 FunctionTemplateDecl::newCommon(ASTContext &C) const { 462 auto *CommonPtr = new (C) Common; 463 C.addDestruction(CommonPtr); 464 return CommonPtr; 465 } 466 467 void FunctionTemplateDecl::LoadLazySpecializations() const { 468 loadLazySpecializationsImpl(); 469 } 470 471 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & 472 FunctionTemplateDecl::getSpecializations() const { 473 LoadLazySpecializations(); 474 return getCommonPtr()->Specializations; 475 } 476 477 FunctionDecl * 478 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 479 void *&InsertPos) { 480 auto *Common = getCommonPtr(); 481 return findSpecializationImpl(Common->Specializations, InsertPos, Args); 482 } 483 484 void FunctionTemplateDecl::addSpecialization( 485 FunctionTemplateSpecializationInfo *Info, void *InsertPos) { 486 auto *Common = getCommonPtr(); 487 addSpecializationImpl<FunctionTemplateDecl>(Common->Specializations, Info, 488 InsertPos); 489 } 490 491 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) { 492 using Base = RedeclarableTemplateDecl; 493 494 // If we haven't created a common pointer yet, then it can just be created 495 // with the usual method. 496 if (!Base::Common) 497 return; 498 499 Common *ThisCommon = static_cast<Common *>(Base::Common); 500 Common *PrevCommon = nullptr; 501 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls; 502 for (; Prev; Prev = Prev->getPreviousDecl()) { 503 if (Prev->Base::Common) { 504 PrevCommon = static_cast<Common *>(Prev->Base::Common); 505 break; 506 } 507 PreviousDecls.push_back(Prev); 508 } 509 510 // If the previous redecl chain hasn't created a common pointer yet, then just 511 // use this common pointer. 512 if (!PrevCommon) { 513 for (auto *D : PreviousDecls) 514 D->Base::Common = ThisCommon; 515 return; 516 } 517 518 // Ensure we don't leak any important state. 519 assert(ThisCommon->Specializations.size() == 0 && 520 "Can't merge incompatible declarations!"); 521 522 Base::Common = PrevCommon; 523 } 524 525 //===----------------------------------------------------------------------===// 526 // ClassTemplateDecl Implementation 527 //===----------------------------------------------------------------------===// 528 529 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, 530 SourceLocation L, 531 DeclarationName Name, 532 TemplateParameterList *Params, 533 NamedDecl *Decl) { 534 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 535 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl); 536 if (Invalid) 537 TD->setInvalidDecl(); 538 return TD; 539 } 540 541 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 542 GlobalDeclID ID) { 543 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), 544 DeclarationName(), nullptr, nullptr); 545 } 546 547 void ClassTemplateDecl::LoadLazySpecializations( 548 bool OnlyPartial /*=false*/) const { 549 loadLazySpecializationsImpl(OnlyPartial); 550 } 551 552 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 553 ClassTemplateDecl::getSpecializations() const { 554 LoadLazySpecializations(); 555 return getCommonPtr()->Specializations; 556 } 557 558 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 559 ClassTemplateDecl::getPartialSpecializations() const { 560 LoadLazySpecializations(/*PartialOnly = */ true); 561 return getCommonPtr()->PartialSpecializations; 562 } 563 564 RedeclarableTemplateDecl::CommonBase * 565 ClassTemplateDecl::newCommon(ASTContext &C) const { 566 auto *CommonPtr = new (C) Common; 567 C.addDestruction(CommonPtr); 568 return CommonPtr; 569 } 570 571 ClassTemplateSpecializationDecl * 572 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 573 void *&InsertPos) { 574 auto *Common = getCommonPtr(); 575 return findSpecializationImpl(Common->Specializations, InsertPos, Args); 576 } 577 578 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 579 void *InsertPos) { 580 auto *Common = getCommonPtr(); 581 addSpecializationImpl<ClassTemplateDecl>(Common->Specializations, D, 582 InsertPos); 583 } 584 585 ClassTemplatePartialSpecializationDecl * 586 ClassTemplateDecl::findPartialSpecialization( 587 ArrayRef<TemplateArgument> Args, 588 TemplateParameterList *TPL, void *&InsertPos) { 589 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args, 590 TPL); 591 } 592 593 void ClassTemplatePartialSpecializationDecl::Profile( 594 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, 595 TemplateParameterList *TPL, const ASTContext &Context) { 596 ID.AddInteger(TemplateArgs.size()); 597 for (const TemplateArgument &TemplateArg : TemplateArgs) 598 TemplateArg.Profile(ID, Context); 599 TPL->Profile(ID, Context); 600 } 601 602 void ClassTemplateDecl::AddPartialSpecialization( 603 ClassTemplatePartialSpecializationDecl *D, 604 void *InsertPos) { 605 if (InsertPos) 606 getPartialSpecializations().InsertNode(D, InsertPos); 607 else { 608 ClassTemplatePartialSpecializationDecl *Existing 609 = getPartialSpecializations().GetOrInsertNode(D); 610 (void)Existing; 611 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 612 } 613 614 if (ASTMutationListener *L = getASTMutationListener()) 615 L->AddedCXXTemplateSpecialization(this, D); 616 } 617 618 void ClassTemplateDecl::getPartialSpecializations( 619 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) const { 620 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs 621 = getPartialSpecializations(); 622 PS.clear(); 623 PS.reserve(PartialSpecs.size()); 624 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs) 625 PS.push_back(P.getMostRecentDecl()); 626 } 627 628 ClassTemplatePartialSpecializationDecl * 629 ClassTemplateDecl::findPartialSpecialization(QualType T) { 630 ASTContext &Context = getASTContext(); 631 for (ClassTemplatePartialSpecializationDecl &P : 632 getPartialSpecializations()) { 633 if (Context.hasSameType(P.getInjectedSpecializationType(), T)) 634 return P.getMostRecentDecl(); 635 } 636 637 return nullptr; 638 } 639 640 ClassTemplatePartialSpecializationDecl * 641 ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 642 ClassTemplatePartialSpecializationDecl *D) { 643 Decl *DCanon = D->getCanonicalDecl(); 644 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 645 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 646 return P.getMostRecentDecl(); 647 } 648 649 return nullptr; 650 } 651 652 QualType 653 ClassTemplateDecl::getInjectedClassNameSpecialization() { 654 Common *CommonPtr = getCommonPtr(); 655 if (!CommonPtr->InjectedClassNameType.isNull()) 656 return CommonPtr->InjectedClassNameType; 657 658 // C++0x [temp.dep.type]p2: 659 // The template argument list of a primary template is a template argument 660 // list in which the nth template argument has the value of the nth template 661 // parameter of the class template. If the nth template parameter is a 662 // template parameter pack (14.5.3), the nth template argument is a pack 663 // expansion (14.5.3) whose pattern is the name of the template parameter 664 // pack. 665 ASTContext &Context = getASTContext(); 666 TemplateName Name = Context.getQualifiedTemplateName( 667 /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this)); 668 auto TemplateArgs = getTemplateParameters()->getInjectedTemplateArgs(Context); 669 CommonPtr->InjectedClassNameType = 670 Context.getTemplateSpecializationType(Name, 671 /*SpecifiedArgs=*/TemplateArgs, 672 /*CanonicalArgs=*/{}); 673 return CommonPtr->InjectedClassNameType; 674 } 675 676 //===----------------------------------------------------------------------===// 677 // TemplateTypeParm Allocation/Deallocation Method Implementations 678 //===----------------------------------------------------------------------===// 679 680 TemplateTypeParmDecl *TemplateTypeParmDecl::Create( 681 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, 682 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, 683 bool Typename, bool ParameterPack, bool HasTypeConstraint, 684 UnsignedOrNone NumExpanded) { 685 auto *TTPDecl = 686 new (C, DC, 687 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0)) 688 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename, 689 HasTypeConstraint, NumExpanded); 690 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 691 TTPDecl->setTypeForDecl(TTPType.getTypePtr()); 692 return TTPDecl; 693 } 694 695 TemplateTypeParmDecl * 696 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) { 697 return new (C, ID) 698 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, 699 false, false, std::nullopt); 700 } 701 702 TemplateTypeParmDecl * 703 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID, 704 bool HasTypeConstraint) { 705 return new (C, ID, 706 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0)) 707 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, 708 false, HasTypeConstraint, std::nullopt); 709 } 710 711 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 712 return hasDefaultArgument() ? getDefaultArgument().getLocation() 713 : SourceLocation(); 714 } 715 716 SourceRange TemplateTypeParmDecl::getSourceRange() const { 717 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 718 return SourceRange(getBeginLoc(), 719 getDefaultArgument().getSourceRange().getEnd()); 720 // TypeDecl::getSourceRange returns a range containing name location, which is 721 // wrong for unnamed template parameters. e.g: 722 // it will return <[[typename>]] instead of <[[typename]]> 723 if (getDeclName().isEmpty()) 724 return SourceRange(getBeginLoc()); 725 return TypeDecl::getSourceRange(); 726 } 727 728 void TemplateTypeParmDecl::setDefaultArgument( 729 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 730 if (DefArg.getArgument().isNull()) 731 DefaultArgument.set(nullptr); 732 else 733 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 734 } 735 736 unsigned TemplateTypeParmDecl::getDepth() const { 737 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth(); 738 } 739 740 unsigned TemplateTypeParmDecl::getIndex() const { 741 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex(); 742 } 743 744 bool TemplateTypeParmDecl::isParameterPack() const { 745 return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack(); 746 } 747 748 void TemplateTypeParmDecl::setTypeConstraint( 749 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint, 750 UnsignedOrNone ArgPackSubstIndex) { 751 assert(HasTypeConstraint && 752 "HasTypeConstraint=true must be passed at construction in order to " 753 "call setTypeConstraint"); 754 assert(!TypeConstraintInitialized && 755 "TypeConstraint was already initialized!"); 756 new (getTrailingObjects()) 757 TypeConstraint(Loc, ImmediatelyDeclaredConstraint, ArgPackSubstIndex); 758 TypeConstraintInitialized = true; 759 } 760 761 //===----------------------------------------------------------------------===// 762 // NonTypeTemplateParmDecl Method Implementations 763 //===----------------------------------------------------------------------===// 764 765 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( 766 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, 767 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, 768 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) 769 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 770 TemplateParmPosition(D, P), ParameterPack(true), 771 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) { 772 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) { 773 auto TypesAndInfos = 774 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); 775 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 776 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]); 777 TypesAndInfos[I].second = ExpandedTInfos[I]; 778 } 779 } 780 } 781 782 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( 783 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 784 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, 785 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) { 786 AutoType *AT = 787 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr; 788 const bool HasConstraint = AT && AT->isConstrained(); 789 auto *NTTP = 790 new (C, DC, 791 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>( 792 0, HasConstraint ? 1 : 0)) 793 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, 794 ParameterPack, TInfo); 795 if (HasConstraint) 796 NTTP->setPlaceholderTypeConstraint(nullptr); 797 return NTTP; 798 } 799 800 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( 801 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 802 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, 803 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, 804 ArrayRef<TypeSourceInfo *> ExpandedTInfos) { 805 AutoType *AT = TInfo->getType()->getContainedAutoType(); 806 const bool HasConstraint = AT && AT->isConstrained(); 807 auto *NTTP = 808 new (C, DC, 809 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>( 810 ExpandedTypes.size(), HasConstraint ? 1 : 0)) 811 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 812 ExpandedTypes, ExpandedTInfos); 813 if (HasConstraint) 814 NTTP->setPlaceholderTypeConstraint(nullptr); 815 return NTTP; 816 } 817 818 NonTypeTemplateParmDecl * 819 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, 820 bool HasTypeConstraint) { 821 auto *NTTP = 822 new (C, ID, 823 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>( 824 0, HasTypeConstraint ? 1 : 0)) 825 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 826 0, 0, nullptr, QualType(), false, nullptr); 827 if (HasTypeConstraint) 828 NTTP->setPlaceholderTypeConstraint(nullptr); 829 return NTTP; 830 } 831 832 NonTypeTemplateParmDecl * 833 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, 834 unsigned NumExpandedTypes, 835 bool HasTypeConstraint) { 836 auto *NTTP = 837 new (C, ID, 838 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>( 839 NumExpandedTypes, HasTypeConstraint ? 1 : 0)) 840 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 841 0, 0, nullptr, QualType(), nullptr, {}, {}); 842 NTTP->NumExpandedTypes = NumExpandedTypes; 843 if (HasTypeConstraint) 844 NTTP->setPlaceholderTypeConstraint(nullptr); 845 return NTTP; 846 } 847 848 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 849 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 850 return SourceRange(getOuterLocStart(), 851 getDefaultArgument().getSourceRange().getEnd()); 852 return DeclaratorDecl::getSourceRange(); 853 } 854 855 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 856 return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin() 857 : SourceLocation(); 858 } 859 860 void NonTypeTemplateParmDecl::setDefaultArgument( 861 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 862 if (DefArg.getArgument().isNull()) 863 DefaultArgument.set(nullptr); 864 else 865 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 866 } 867 868 //===----------------------------------------------------------------------===// 869 // TemplateTemplateParmDecl Method Implementations 870 //===----------------------------------------------------------------------===// 871 872 void TemplateTemplateParmDecl::anchor() {} 873 874 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 875 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 876 IdentifierInfo *Id, bool Typename, TemplateParameterList *Params, 877 ArrayRef<TemplateParameterList *> Expansions) 878 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 879 TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true), 880 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) { 881 llvm::uninitialized_copy(Expansions, getTrailingObjects()); 882 } 883 884 TemplateTemplateParmDecl * 885 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 886 SourceLocation L, unsigned D, unsigned P, 887 bool ParameterPack, IdentifierInfo *Id, 888 bool Typename, TemplateParameterList *Params) { 889 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 890 Typename, Params); 891 } 892 893 TemplateTemplateParmDecl * 894 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 895 SourceLocation L, unsigned D, unsigned P, 896 IdentifierInfo *Id, bool Typename, 897 TemplateParameterList *Params, 898 ArrayRef<TemplateParameterList *> Expansions) { 899 return new (C, DC, 900 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size())) 901 TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions); 902 } 903 904 TemplateTemplateParmDecl * 905 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 906 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 907 false, nullptr, false, nullptr); 908 } 909 910 TemplateTemplateParmDecl * 911 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, 912 unsigned NumExpansions) { 913 auto *TTP = 914 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) 915 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 916 false, nullptr, {}); 917 TTP->NumExpandedParams = NumExpansions; 918 return TTP; 919 } 920 921 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 922 return hasDefaultArgument() ? getDefaultArgument().getLocation() 923 : SourceLocation(); 924 } 925 926 void TemplateTemplateParmDecl::setDefaultArgument( 927 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 928 if (DefArg.getArgument().isNull()) 929 DefaultArgument.set(nullptr); 930 else 931 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 932 } 933 934 //===----------------------------------------------------------------------===// 935 // TemplateArgumentList Implementation 936 //===----------------------------------------------------------------------===// 937 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args) 938 : NumArguments(Args.size()) { 939 llvm::uninitialized_copy(Args, getTrailingObjects()); 940 } 941 942 TemplateArgumentList * 943 TemplateArgumentList::CreateCopy(ASTContext &Context, 944 ArrayRef<TemplateArgument> Args) { 945 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size())); 946 return new (Mem) TemplateArgumentList(Args); 947 } 948 949 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create( 950 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, 951 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, 952 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, 953 MemberSpecializationInfo *MSInfo) { 954 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 955 if (TemplateArgsAsWritten) 956 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 957 *TemplateArgsAsWritten); 958 959 void *Mem = 960 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0)); 961 return new (Mem) FunctionTemplateSpecializationInfo( 962 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo); 963 } 964 965 //===----------------------------------------------------------------------===// 966 // ClassTemplateSpecializationDecl Implementation 967 //===----------------------------------------------------------------------===// 968 969 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl( 970 ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, 971 SourceLocation StartLoc, SourceLocation IdLoc, 972 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, 973 bool StrictPackMatch, ClassTemplateSpecializationDecl *PrevDecl) 974 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 975 SpecializedTemplate->getIdentifier(), PrevDecl), 976 SpecializedTemplate(SpecializedTemplate), 977 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 978 SpecializationKind(TSK_Undeclared), StrictPackMatch(StrictPackMatch) { 979 assert(DK == Kind::ClassTemplateSpecialization || StrictPackMatch == false); 980 } 981 982 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 983 Kind DK) 984 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(), 985 SourceLocation(), nullptr, nullptr), 986 SpecializationKind(TSK_Undeclared) {} 987 988 ClassTemplateSpecializationDecl *ClassTemplateSpecializationDecl::Create( 989 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, 990 SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, 991 ArrayRef<TemplateArgument> Args, bool StrictPackMatch, 992 ClassTemplateSpecializationDecl *PrevDecl) { 993 auto *Result = new (Context, DC) ClassTemplateSpecializationDecl( 994 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 995 SpecializedTemplate, Args, StrictPackMatch, PrevDecl); 996 Result->setMayHaveOutOfDateDef(false); 997 998 // If the template decl is incomplete, copy the external lexical storage from 999 // the base template. This allows instantiations of incomplete types to 1000 // complete using the external AST if the template's declaration came from an 1001 // external AST. 1002 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition()) 1003 Result->setHasExternalLexicalStorage( 1004 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage()); 1005 1006 Context.getTypeDeclType(Result, PrevDecl); 1007 return Result; 1008 } 1009 1010 ClassTemplateSpecializationDecl * 1011 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 1012 GlobalDeclID ID) { 1013 auto *Result = 1014 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 1015 Result->setMayHaveOutOfDateDef(false); 1016 return Result; 1017 } 1018 1019 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 1020 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1021 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1022 1023 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this); 1024 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 1025 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 1026 printTemplateArgumentList( 1027 OS, ArgsAsWritten->arguments(), Policy, 1028 getSpecializedTemplate()->getTemplateParameters()); 1029 } else { 1030 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1031 printTemplateArgumentList( 1032 OS, TemplateArgs.asArray(), Policy, 1033 getSpecializedTemplate()->getTemplateParameters()); 1034 } 1035 } 1036 1037 ClassTemplateDecl * 1038 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 1039 if (const auto *PartialSpec = 1040 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 1041 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1042 return cast<ClassTemplateDecl *>(SpecializedTemplate); 1043 } 1044 1045 SourceRange 1046 ClassTemplateSpecializationDecl::getSourceRange() const { 1047 switch (getSpecializationKind()) { 1048 case TSK_Undeclared: 1049 case TSK_ImplicitInstantiation: { 1050 llvm::PointerUnion<ClassTemplateDecl *, 1051 ClassTemplatePartialSpecializationDecl *> 1052 Pattern = getSpecializedTemplateOrPartial(); 1053 assert(!Pattern.isNull() && 1054 "Class template specialization without pattern?"); 1055 if (const auto *CTPSD = 1056 dyn_cast<ClassTemplatePartialSpecializationDecl *>(Pattern)) 1057 return CTPSD->getSourceRange(); 1058 return cast<ClassTemplateDecl *>(Pattern)->getSourceRange(); 1059 } 1060 case TSK_ExplicitSpecialization: { 1061 SourceRange Range = CXXRecordDecl::getSourceRange(); 1062 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten(); 1063 !isThisDeclarationADefinition() && Args) 1064 Range.setEnd(Args->getRAngleLoc()); 1065 return Range; 1066 } 1067 case TSK_ExplicitInstantiationDeclaration: 1068 case TSK_ExplicitInstantiationDefinition: { 1069 SourceRange Range = CXXRecordDecl::getSourceRange(); 1070 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid()) 1071 Range.setBegin(ExternKW); 1072 else if (SourceLocation TemplateKW = getTemplateKeywordLoc(); 1073 TemplateKW.isValid()) 1074 Range.setBegin(TemplateKW); 1075 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten()) 1076 Range.setEnd(Args->getRAngleLoc()); 1077 return Range; 1078 } 1079 } 1080 llvm_unreachable("unhandled template specialization kind"); 1081 } 1082 1083 void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { 1084 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo); 1085 if (!Info) { 1086 // Don't allocate if the location is invalid. 1087 if (Loc.isInvalid()) 1088 return; 1089 Info = new (getASTContext()) ExplicitInstantiationInfo; 1090 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); 1091 ExplicitInfo = Info; 1092 } 1093 Info->ExternKeywordLoc = Loc; 1094 } 1095 1096 void ClassTemplateSpecializationDecl::setTemplateKeywordLoc( 1097 SourceLocation Loc) { 1098 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo); 1099 if (!Info) { 1100 // Don't allocate if the location is invalid. 1101 if (Loc.isInvalid()) 1102 return; 1103 Info = new (getASTContext()) ExplicitInstantiationInfo; 1104 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); 1105 ExplicitInfo = Info; 1106 } 1107 Info->TemplateKeywordLoc = Loc; 1108 } 1109 1110 //===----------------------------------------------------------------------===// 1111 // ConceptDecl Implementation 1112 //===----------------------------------------------------------------------===// 1113 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, 1114 SourceLocation L, DeclarationName Name, 1115 TemplateParameterList *Params, 1116 Expr *ConstraintExpr) { 1117 bool Invalid = AdoptTemplateParameterList(Params, DC); 1118 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr); 1119 if (Invalid) 1120 TD->setInvalidDecl(); 1121 return TD; 1122 } 1123 1124 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 1125 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), 1126 DeclarationName(), 1127 nullptr, nullptr); 1128 1129 return Result; 1130 } 1131 1132 //===----------------------------------------------------------------------===// 1133 // ImplicitConceptSpecializationDecl Implementation 1134 //===----------------------------------------------------------------------===// 1135 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl( 1136 DeclContext *DC, SourceLocation SL, 1137 ArrayRef<TemplateArgument> ConvertedArgs) 1138 : Decl(ImplicitConceptSpecialization, DC, SL), 1139 NumTemplateArgs(ConvertedArgs.size()) { 1140 setTemplateArguments(ConvertedArgs); 1141 } 1142 1143 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl( 1144 EmptyShell Empty, unsigned NumTemplateArgs) 1145 : Decl(ImplicitConceptSpecialization, Empty), 1146 NumTemplateArgs(NumTemplateArgs) {} 1147 1148 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( 1149 const ASTContext &C, DeclContext *DC, SourceLocation SL, 1150 ArrayRef<TemplateArgument> ConvertedArgs) { 1151 return new (C, DC, 1152 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size())) 1153 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs); 1154 } 1155 1156 ImplicitConceptSpecializationDecl * 1157 ImplicitConceptSpecializationDecl::CreateDeserialized( 1158 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) { 1159 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs)) 1160 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); 1161 } 1162 1163 void ImplicitConceptSpecializationDecl::setTemplateArguments( 1164 ArrayRef<TemplateArgument> Converted) { 1165 assert(Converted.size() == NumTemplateArgs); 1166 llvm::uninitialized_copy(Converted, getTrailingObjects()); 1167 } 1168 1169 //===----------------------------------------------------------------------===// 1170 // ClassTemplatePartialSpecializationDecl Implementation 1171 //===----------------------------------------------------------------------===// 1172 void ClassTemplatePartialSpecializationDecl::anchor() {} 1173 1174 ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl( 1175 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, 1176 SourceLocation IdLoc, TemplateParameterList *Params, 1177 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, 1178 ClassTemplatePartialSpecializationDecl *PrevDecl) 1179 : ClassTemplateSpecializationDecl( 1180 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc, 1181 // Tracking StrictPackMatch for Partial 1182 // Specializations is not needed. 1183 SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl), 1184 TemplateParams(Params), InstantiatedFromMember(nullptr, false) { 1185 if (AdoptTemplateParameterList(Params, this)) 1186 setInvalidDecl(); 1187 } 1188 1189 ClassTemplatePartialSpecializationDecl * 1190 ClassTemplatePartialSpecializationDecl::Create( 1191 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, 1192 SourceLocation IdLoc, TemplateParameterList *Params, 1193 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, 1194 QualType CanonInjectedType, 1195 ClassTemplatePartialSpecializationDecl *PrevDecl) { 1196 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl( 1197 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args, 1198 PrevDecl); 1199 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1200 Result->setMayHaveOutOfDateDef(false); 1201 1202 Context.getInjectedClassNameType(Result, CanonInjectedType); 1203 return Result; 1204 } 1205 1206 ClassTemplatePartialSpecializationDecl * 1207 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1208 GlobalDeclID ID) { 1209 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); 1210 Result->setMayHaveOutOfDateDef(false); 1211 return Result; 1212 } 1213 1214 SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const { 1215 if (const ClassTemplatePartialSpecializationDecl *MT = 1216 getInstantiatedFromMember(); 1217 MT && !isMemberSpecialization()) 1218 return MT->getSourceRange(); 1219 SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange(); 1220 if (const TemplateParameterList *TPL = getTemplateParameters(); 1221 TPL && !getNumTemplateParameterLists()) 1222 Range.setBegin(TPL->getTemplateLoc()); 1223 return Range; 1224 } 1225 1226 //===----------------------------------------------------------------------===// 1227 // FriendTemplateDecl Implementation 1228 //===----------------------------------------------------------------------===// 1229 1230 void FriendTemplateDecl::anchor() {} 1231 1232 FriendTemplateDecl * 1233 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, 1234 SourceLocation L, 1235 MutableArrayRef<TemplateParameterList *> Params, 1236 FriendUnion Friend, SourceLocation FLoc) { 1237 TemplateParameterList **TPL = nullptr; 1238 if (!Params.empty()) { 1239 TPL = new (Context) TemplateParameterList *[Params.size()]; 1240 llvm::copy(Params, TPL); 1241 } 1242 return new (Context, DC) 1243 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc); 1244 } 1245 1246 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 1247 GlobalDeclID ID) { 1248 return new (C, ID) FriendTemplateDecl(EmptyShell()); 1249 } 1250 1251 //===----------------------------------------------------------------------===// 1252 // TypeAliasTemplateDecl Implementation 1253 //===----------------------------------------------------------------------===// 1254 1255 TypeAliasTemplateDecl * 1256 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 1257 DeclarationName Name, 1258 TemplateParameterList *Params, NamedDecl *Decl) { 1259 bool Invalid = AdoptTemplateParameterList(Params, DC); 1260 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 1261 if (Invalid) 1262 TD->setInvalidDecl(); 1263 return TD; 1264 } 1265 1266 TypeAliasTemplateDecl * 1267 TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 1268 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 1269 DeclarationName(), nullptr, nullptr); 1270 } 1271 1272 RedeclarableTemplateDecl::CommonBase * 1273 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 1274 auto *CommonPtr = new (C) Common; 1275 C.addDestruction(CommonPtr); 1276 return CommonPtr; 1277 } 1278 1279 //===----------------------------------------------------------------------===// 1280 // VarTemplateDecl Implementation 1281 //===----------------------------------------------------------------------===// 1282 1283 VarTemplateDecl *VarTemplateDecl::getDefinition() { 1284 VarTemplateDecl *CurD = this; 1285 while (CurD) { 1286 if (CurD->isThisDeclarationADefinition()) 1287 return CurD; 1288 CurD = CurD->getPreviousDecl(); 1289 } 1290 return nullptr; 1291 } 1292 1293 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 1294 SourceLocation L, DeclarationName Name, 1295 TemplateParameterList *Params, 1296 VarDecl *Decl) { 1297 bool Invalid = AdoptTemplateParameterList(Params, DC); 1298 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 1299 if (Invalid) 1300 TD->setInvalidDecl(); 1301 return TD; 1302 } 1303 1304 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 1305 GlobalDeclID ID) { 1306 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 1307 DeclarationName(), nullptr, nullptr); 1308 } 1309 1310 void VarTemplateDecl::LoadLazySpecializations( 1311 bool OnlyPartial /*=false*/) const { 1312 loadLazySpecializationsImpl(OnlyPartial); 1313 } 1314 1315 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 1316 VarTemplateDecl::getSpecializations() const { 1317 LoadLazySpecializations(); 1318 return getCommonPtr()->Specializations; 1319 } 1320 1321 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 1322 VarTemplateDecl::getPartialSpecializations() const { 1323 LoadLazySpecializations(/*PartialOnly = */ true); 1324 return getCommonPtr()->PartialSpecializations; 1325 } 1326 1327 RedeclarableTemplateDecl::CommonBase * 1328 VarTemplateDecl::newCommon(ASTContext &C) const { 1329 auto *CommonPtr = new (C) Common; 1330 C.addDestruction(CommonPtr); 1331 return CommonPtr; 1332 } 1333 1334 VarTemplateSpecializationDecl * 1335 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 1336 void *&InsertPos) { 1337 auto *Common = getCommonPtr(); 1338 return findSpecializationImpl(Common->Specializations, InsertPos, Args); 1339 } 1340 1341 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 1342 void *InsertPos) { 1343 auto *Common = getCommonPtr(); 1344 addSpecializationImpl<VarTemplateDecl>(Common->Specializations, D, InsertPos); 1345 } 1346 1347 VarTemplatePartialSpecializationDecl * 1348 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 1349 TemplateParameterList *TPL, void *&InsertPos) { 1350 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args, 1351 TPL); 1352 } 1353 1354 void VarTemplatePartialSpecializationDecl::Profile( 1355 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, 1356 TemplateParameterList *TPL, const ASTContext &Context) { 1357 ID.AddInteger(TemplateArgs.size()); 1358 for (const TemplateArgument &TemplateArg : TemplateArgs) 1359 TemplateArg.Profile(ID, Context); 1360 TPL->Profile(ID, Context); 1361 } 1362 1363 void VarTemplateDecl::AddPartialSpecialization( 1364 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1365 if (InsertPos) 1366 getPartialSpecializations().InsertNode(D, InsertPos); 1367 else { 1368 VarTemplatePartialSpecializationDecl *Existing = 1369 getPartialSpecializations().GetOrInsertNode(D); 1370 (void)Existing; 1371 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1372 } 1373 1374 if (ASTMutationListener *L = getASTMutationListener()) 1375 L->AddedCXXTemplateSpecialization(this, D); 1376 } 1377 1378 void VarTemplateDecl::getPartialSpecializations( 1379 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const { 1380 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1381 getPartialSpecializations(); 1382 PS.clear(); 1383 PS.reserve(PartialSpecs.size()); 1384 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs) 1385 PS.push_back(P.getMostRecentDecl()); 1386 } 1387 1388 VarTemplatePartialSpecializationDecl * 1389 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1390 VarTemplatePartialSpecializationDecl *D) { 1391 Decl *DCanon = D->getCanonicalDecl(); 1392 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 1393 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1394 return P.getMostRecentDecl(); 1395 } 1396 1397 return nullptr; 1398 } 1399 1400 //===----------------------------------------------------------------------===// 1401 // VarTemplateSpecializationDecl Implementation 1402 //===----------------------------------------------------------------------===// 1403 1404 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1405 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1406 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1407 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) 1408 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 1409 SpecializedTemplate->getIdentifier(), T, TInfo, S), 1410 SpecializedTemplate(SpecializedTemplate), 1411 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 1412 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1413 1414 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 1415 ASTContext &C) 1416 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 1417 QualType(), nullptr, SC_None), 1418 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1419 1420 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1421 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1422 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1423 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) { 1424 return new (Context, DC) VarTemplateSpecializationDecl( 1425 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 1426 SpecializedTemplate, T, TInfo, S, Args); 1427 } 1428 1429 VarTemplateSpecializationDecl * 1430 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 1431 GlobalDeclID ID) { 1432 return new (C, ID) 1433 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 1434 } 1435 1436 void VarTemplateSpecializationDecl::getNameForDiagnostic( 1437 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1438 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1439 1440 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this); 1441 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 1442 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 1443 printTemplateArgumentList( 1444 OS, ArgsAsWritten->arguments(), Policy, 1445 getSpecializedTemplate()->getTemplateParameters()); 1446 } else { 1447 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1448 printTemplateArgumentList( 1449 OS, TemplateArgs.asArray(), Policy, 1450 getSpecializedTemplate()->getTemplateParameters()); 1451 } 1452 } 1453 1454 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1455 if (const auto *PartialSpec = 1456 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1457 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1458 return cast<VarTemplateDecl *>(SpecializedTemplate); 1459 } 1460 1461 SourceRange VarTemplateSpecializationDecl::getSourceRange() const { 1462 switch (getSpecializationKind()) { 1463 case TSK_Undeclared: 1464 case TSK_ImplicitInstantiation: { 1465 llvm::PointerUnion<VarTemplateDecl *, 1466 VarTemplatePartialSpecializationDecl *> 1467 Pattern = getSpecializedTemplateOrPartial(); 1468 assert(!Pattern.isNull() && 1469 "Variable template specialization without pattern?"); 1470 if (const auto *VTPSD = 1471 dyn_cast<VarTemplatePartialSpecializationDecl *>(Pattern)) 1472 return VTPSD->getSourceRange(); 1473 VarTemplateDecl *VTD = cast<VarTemplateDecl *>(Pattern); 1474 if (hasInit()) { 1475 if (VarTemplateDecl *Definition = VTD->getDefinition()) 1476 return Definition->getSourceRange(); 1477 } 1478 return VTD->getCanonicalDecl()->getSourceRange(); 1479 } 1480 case TSK_ExplicitSpecialization: { 1481 SourceRange Range = VarDecl::getSourceRange(); 1482 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten(); 1483 !hasInit() && Args) 1484 Range.setEnd(Args->getRAngleLoc()); 1485 return Range; 1486 } 1487 case TSK_ExplicitInstantiationDeclaration: 1488 case TSK_ExplicitInstantiationDefinition: { 1489 SourceRange Range = VarDecl::getSourceRange(); 1490 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid()) 1491 Range.setBegin(ExternKW); 1492 else if (SourceLocation TemplateKW = getTemplateKeywordLoc(); 1493 TemplateKW.isValid()) 1494 Range.setBegin(TemplateKW); 1495 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten()) 1496 Range.setEnd(Args->getRAngleLoc()); 1497 return Range; 1498 } 1499 } 1500 llvm_unreachable("unhandled template specialization kind"); 1501 } 1502 1503 void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { 1504 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo); 1505 if (!Info) { 1506 // Don't allocate if the location is invalid. 1507 if (Loc.isInvalid()) 1508 return; 1509 Info = new (getASTContext()) ExplicitInstantiationInfo; 1510 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); 1511 ExplicitInfo = Info; 1512 } 1513 Info->ExternKeywordLoc = Loc; 1514 } 1515 1516 void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) { 1517 auto *Info = dyn_cast_if_present<ExplicitInstantiationInfo *>(ExplicitInfo); 1518 if (!Info) { 1519 // Don't allocate if the location is invalid. 1520 if (Loc.isInvalid()) 1521 return; 1522 Info = new (getASTContext()) ExplicitInstantiationInfo; 1523 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); 1524 ExplicitInfo = Info; 1525 } 1526 Info->TemplateKeywordLoc = Loc; 1527 } 1528 1529 //===----------------------------------------------------------------------===// 1530 // VarTemplatePartialSpecializationDecl Implementation 1531 //===----------------------------------------------------------------------===// 1532 1533 void VarTemplatePartialSpecializationDecl::anchor() {} 1534 1535 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1536 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1537 SourceLocation IdLoc, TemplateParameterList *Params, 1538 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1539 StorageClass S, ArrayRef<TemplateArgument> Args) 1540 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 1541 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1542 TInfo, S, Args), 1543 TemplateParams(Params), InstantiatedFromMember(nullptr, false) { 1544 if (AdoptTemplateParameterList(Params, DC)) 1545 setInvalidDecl(); 1546 } 1547 1548 VarTemplatePartialSpecializationDecl * 1549 VarTemplatePartialSpecializationDecl::Create( 1550 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1551 SourceLocation IdLoc, TemplateParameterList *Params, 1552 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1553 StorageClass S, ArrayRef<TemplateArgument> Args) { 1554 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl( 1555 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S, 1556 Args); 1557 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1558 return Result; 1559 } 1560 1561 VarTemplatePartialSpecializationDecl * 1562 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1563 GlobalDeclID ID) { 1564 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 1565 } 1566 1567 SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const { 1568 if (const VarTemplatePartialSpecializationDecl *MT = 1569 getInstantiatedFromMember(); 1570 MT && !isMemberSpecialization()) 1571 return MT->getSourceRange(); 1572 SourceRange Range = VarTemplateSpecializationDecl::getSourceRange(); 1573 if (const TemplateParameterList *TPL = getTemplateParameters(); 1574 TPL && !getNumTemplateParameterLists()) 1575 Range.setBegin(TPL->getTemplateLoc()); 1576 return Range; 1577 } 1578 1579 static TemplateParameterList *createBuiltinTemplateParameterList( 1580 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) { 1581 switch (BTK) { 1582 #define CREATE_BUILTIN_TEMPLATE_PARAMETER_LIST 1583 #include "clang/Basic/BuiltinTemplates.inc" 1584 } 1585 1586 llvm_unreachable("unhandled BuiltinTemplateKind!"); 1587 } 1588 1589 void BuiltinTemplateDecl::anchor() {} 1590 1591 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, 1592 DeclarationName Name, 1593 BuiltinTemplateKind BTK) 1594 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name, 1595 createBuiltinTemplateParameterList(C, DC, BTK)), 1596 BTK(BTK) {} 1597 1598 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, 1599 QualType T, 1600 const APValue &V) { 1601 DeclContext *DC = C.getTranslationUnitDecl(); 1602 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V); 1603 C.addDestruction(&TPOD->Value); 1604 return TPOD; 1605 } 1606 1607 TemplateParamObjectDecl * 1608 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 1609 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); 1610 C.addDestruction(&TPOD->Value); 1611 return TPOD; 1612 } 1613 1614 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS, 1615 const PrintingPolicy &Policy) const { 1616 OS << "<template param "; 1617 printAsExpr(OS, Policy); 1618 OS << ">"; 1619 } 1620 1621 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const { 1622 printAsExpr(OS, getASTContext().getPrintingPolicy()); 1623 } 1624 1625 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS, 1626 const PrintingPolicy &Policy) const { 1627 getType().getUnqualifiedType().print(OS, Policy); 1628 printAsInit(OS, Policy); 1629 } 1630 1631 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const { 1632 printAsInit(OS, getASTContext().getPrintingPolicy()); 1633 } 1634 1635 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS, 1636 const PrintingPolicy &Policy) const { 1637 getValue().printPretty(OS, Policy, getType(), &getASTContext()); 1638 } 1639 1640 TemplateParameterList *clang::getReplacedTemplateParameterList(const Decl *D) { 1641 switch (D->getKind()) { 1642 case Decl::Kind::CXXRecord: 1643 return cast<CXXRecordDecl>(D) 1644 ->getDescribedTemplate() 1645 ->getTemplateParameters(); 1646 case Decl::Kind::ClassTemplate: 1647 return cast<ClassTemplateDecl>(D)->getTemplateParameters(); 1648 case Decl::Kind::ClassTemplateSpecialization: { 1649 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D); 1650 auto P = CTSD->getSpecializedTemplateOrPartial(); 1651 if (const auto *CTPSD = 1652 dyn_cast<ClassTemplatePartialSpecializationDecl *>(P)) 1653 return CTPSD->getTemplateParameters(); 1654 return cast<ClassTemplateDecl *>(P)->getTemplateParameters(); 1655 } 1656 case Decl::Kind::ClassTemplatePartialSpecialization: 1657 return cast<ClassTemplatePartialSpecializationDecl>(D) 1658 ->getTemplateParameters(); 1659 case Decl::Kind::TypeAliasTemplate: 1660 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters(); 1661 case Decl::Kind::BuiltinTemplate: 1662 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters(); 1663 case Decl::Kind::CXXDeductionGuide: 1664 case Decl::Kind::CXXConversion: 1665 case Decl::Kind::CXXConstructor: 1666 case Decl::Kind::CXXDestructor: 1667 case Decl::Kind::CXXMethod: 1668 case Decl::Kind::Function: 1669 return cast<FunctionDecl>(D) 1670 ->getTemplateSpecializationInfo() 1671 ->getTemplate() 1672 ->getTemplateParameters(); 1673 case Decl::Kind::FunctionTemplate: 1674 return cast<FunctionTemplateDecl>(D)->getTemplateParameters(); 1675 case Decl::Kind::VarTemplate: 1676 return cast<VarTemplateDecl>(D)->getTemplateParameters(); 1677 case Decl::Kind::VarTemplateSpecialization: { 1678 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D); 1679 auto P = VTSD->getSpecializedTemplateOrPartial(); 1680 if (const auto *VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl *>(P)) 1681 return VTPSD->getTemplateParameters(); 1682 return cast<VarTemplateDecl *>(P)->getTemplateParameters(); 1683 } 1684 case Decl::Kind::VarTemplatePartialSpecialization: 1685 return cast<VarTemplatePartialSpecializationDecl>(D) 1686 ->getTemplateParameters(); 1687 case Decl::Kind::TemplateTemplateParm: 1688 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters(); 1689 case Decl::Kind::Concept: 1690 return cast<ConceptDecl>(D)->getTemplateParameters(); 1691 default: 1692 llvm_unreachable("Unhandled templated declaration kind"); 1693 } 1694 } 1695