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