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