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(NestedNameSpecifierLoc NNS, 701 DeclarationNameInfo NameInfo, NamedDecl *FoundDecl, ConceptDecl *CD, 702 const ASTTemplateArgumentListInfo *ArgsAsWritten, 703 Expr *ImmediatelyDeclaredConstraint) { 704 assert(HasTypeConstraint && 705 "HasTypeConstraint=true must be passed at construction in order to " 706 "call setTypeConstraint"); 707 assert(!TypeConstraintInitialized && 708 "TypeConstraint was already initialized!"); 709 new (getTrailingObjects<TypeConstraint>()) TypeConstraint(NNS, NameInfo, 710 FoundDecl, CD, ArgsAsWritten, ImmediatelyDeclaredConstraint); 711 TypeConstraintInitialized = true; 712 } 713 714 //===----------------------------------------------------------------------===// 715 // NonTypeTemplateParmDecl Method Implementations 716 //===----------------------------------------------------------------------===// 717 718 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( 719 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, 720 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, 721 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) 722 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 723 TemplateParmPosition(D, P), ParameterPack(true), 724 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) { 725 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) { 726 auto TypesAndInfos = 727 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); 728 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 729 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]); 730 TypesAndInfos[I].second = ExpandedTInfos[I]; 731 } 732 } 733 } 734 735 NonTypeTemplateParmDecl * 736 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 737 SourceLocation StartLoc, SourceLocation IdLoc, 738 unsigned D, unsigned P, IdentifierInfo *Id, 739 QualType T, bool ParameterPack, 740 TypeSourceInfo *TInfo) { 741 AutoType *AT = 742 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr; 743 return new (C, DC, 744 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, 745 Expr *>(0, 746 AT && AT->isConstrained() ? 1 : 0)) 747 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack, 748 TInfo); 749 } 750 751 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( 752 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 753 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, 754 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, 755 ArrayRef<TypeSourceInfo *> ExpandedTInfos) { 756 AutoType *AT = TInfo->getType()->getContainedAutoType(); 757 return new (C, DC, 758 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, 759 Expr *>( 760 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0)) 761 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 762 ExpandedTypes, ExpandedTInfos); 763 } 764 765 NonTypeTemplateParmDecl * 766 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 767 bool HasTypeConstraint) { 768 return new (C, ID, additionalSizeToAlloc<std::pair<QualType, 769 TypeSourceInfo *>, 770 Expr *>(0, 771 HasTypeConstraint ? 1 : 0)) 772 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 773 0, 0, nullptr, QualType(), false, nullptr); 774 } 775 776 NonTypeTemplateParmDecl * 777 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 778 unsigned NumExpandedTypes, 779 bool HasTypeConstraint) { 780 auto *NTTP = 781 new (C, ID, 782 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>( 783 NumExpandedTypes, HasTypeConstraint ? 1 : 0)) 784 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 785 0, 0, nullptr, QualType(), nullptr, 786 std::nullopt, std::nullopt); 787 NTTP->NumExpandedTypes = NumExpandedTypes; 788 return NTTP; 789 } 790 791 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 792 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 793 return SourceRange(getOuterLocStart(), 794 getDefaultArgument()->getSourceRange().getEnd()); 795 return DeclaratorDecl::getSourceRange(); 796 } 797 798 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 799 return hasDefaultArgument() 800 ? getDefaultArgument()->getSourceRange().getBegin() 801 : SourceLocation(); 802 } 803 804 //===----------------------------------------------------------------------===// 805 // TemplateTemplateParmDecl Method Implementations 806 //===----------------------------------------------------------------------===// 807 808 void TemplateTemplateParmDecl::anchor() {} 809 810 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 811 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 812 IdentifierInfo *Id, TemplateParameterList *Params, 813 ArrayRef<TemplateParameterList *> Expansions) 814 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 815 TemplateParmPosition(D, P), ParameterPack(true), 816 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) { 817 if (!Expansions.empty()) 818 std::uninitialized_copy(Expansions.begin(), Expansions.end(), 819 getTrailingObjects<TemplateParameterList *>()); 820 } 821 822 TemplateTemplateParmDecl * 823 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 824 SourceLocation L, unsigned D, unsigned P, 825 bool ParameterPack, IdentifierInfo *Id, 826 TemplateParameterList *Params) { 827 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 828 Params); 829 } 830 831 TemplateTemplateParmDecl * 832 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 833 SourceLocation L, unsigned D, unsigned P, 834 IdentifierInfo *Id, 835 TemplateParameterList *Params, 836 ArrayRef<TemplateParameterList *> Expansions) { 837 return new (C, DC, 838 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size())) 839 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions); 840 } 841 842 TemplateTemplateParmDecl * 843 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 844 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 845 false, nullptr, nullptr); 846 } 847 848 TemplateTemplateParmDecl * 849 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 850 unsigned NumExpansions) { 851 auto *TTP = 852 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) 853 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 854 nullptr, std::nullopt); 855 TTP->NumExpandedParams = NumExpansions; 856 return TTP; 857 } 858 859 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 860 return hasDefaultArgument() ? getDefaultArgument().getLocation() 861 : SourceLocation(); 862 } 863 864 void TemplateTemplateParmDecl::setDefaultArgument( 865 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 866 if (DefArg.getArgument().isNull()) 867 DefaultArgument.set(nullptr); 868 else 869 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 870 } 871 872 //===----------------------------------------------------------------------===// 873 // TemplateArgumentList Implementation 874 //===----------------------------------------------------------------------===// 875 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args) 876 : Arguments(getTrailingObjects<TemplateArgument>()), 877 NumArguments(Args.size()) { 878 std::uninitialized_copy(Args.begin(), Args.end(), 879 getTrailingObjects<TemplateArgument>()); 880 } 881 882 TemplateArgumentList * 883 TemplateArgumentList::CreateCopy(ASTContext &Context, 884 ArrayRef<TemplateArgument> Args) { 885 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size())); 886 return new (Mem) TemplateArgumentList(Args); 887 } 888 889 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create( 890 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, 891 TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, 892 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, 893 MemberSpecializationInfo *MSInfo) { 894 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 895 if (TemplateArgsAsWritten) 896 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 897 *TemplateArgsAsWritten); 898 899 void *Mem = 900 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0)); 901 return new (Mem) FunctionTemplateSpecializationInfo( 902 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo); 903 } 904 905 //===----------------------------------------------------------------------===// 906 // ClassTemplateSpecializationDecl Implementation 907 //===----------------------------------------------------------------------===// 908 909 ClassTemplateSpecializationDecl:: 910 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 911 DeclContext *DC, SourceLocation StartLoc, 912 SourceLocation IdLoc, 913 ClassTemplateDecl *SpecializedTemplate, 914 ArrayRef<TemplateArgument> Args, 915 ClassTemplateSpecializationDecl *PrevDecl) 916 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 917 SpecializedTemplate->getIdentifier(), PrevDecl), 918 SpecializedTemplate(SpecializedTemplate), 919 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 920 SpecializationKind(TSK_Undeclared) { 921 } 922 923 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 924 Kind DK) 925 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(), 926 SourceLocation(), nullptr, nullptr), 927 SpecializationKind(TSK_Undeclared) {} 928 929 ClassTemplateSpecializationDecl * 930 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 931 DeclContext *DC, 932 SourceLocation StartLoc, 933 SourceLocation IdLoc, 934 ClassTemplateDecl *SpecializedTemplate, 935 ArrayRef<TemplateArgument> Args, 936 ClassTemplateSpecializationDecl *PrevDecl) { 937 auto *Result = 938 new (Context, DC) ClassTemplateSpecializationDecl( 939 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 940 SpecializedTemplate, Args, PrevDecl); 941 Result->setMayHaveOutOfDateDef(false); 942 943 // If the template decl is incomplete, copy the external lexical storage from 944 // the base template. This allows instantiations of incomplete types to 945 // complete using the external AST if the template's declaration came from an 946 // external AST. 947 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition()) 948 Result->setHasExternalLexicalStorage( 949 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage()); 950 951 Context.getTypeDeclType(Result, PrevDecl); 952 return Result; 953 } 954 955 ClassTemplateSpecializationDecl * 956 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 957 unsigned ID) { 958 auto *Result = 959 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 960 Result->setMayHaveOutOfDateDef(false); 961 return Result; 962 } 963 964 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 965 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 966 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 967 968 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this); 969 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 970 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 971 printTemplateArgumentList( 972 OS, ArgsAsWritten->arguments(), Policy, 973 getSpecializedTemplate()->getTemplateParameters()); 974 } else { 975 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 976 printTemplateArgumentList( 977 OS, TemplateArgs.asArray(), Policy, 978 getSpecializedTemplate()->getTemplateParameters()); 979 } 980 } 981 982 ClassTemplateDecl * 983 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 984 if (const auto *PartialSpec = 985 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 986 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 987 return SpecializedTemplate.get<ClassTemplateDecl*>(); 988 } 989 990 SourceRange 991 ClassTemplateSpecializationDecl::getSourceRange() const { 992 if (ExplicitInfo) { 993 SourceLocation Begin = getTemplateKeywordLoc(); 994 if (Begin.isValid()) { 995 // Here we have an explicit (partial) specialization or instantiation. 996 assert(getSpecializationKind() == TSK_ExplicitSpecialization || 997 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 998 getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 999 if (getExternLoc().isValid()) 1000 Begin = getExternLoc(); 1001 SourceLocation End = getBraceRange().getEnd(); 1002 if (End.isInvalid()) 1003 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 1004 return SourceRange(Begin, End); 1005 } 1006 // An implicit instantiation of a class template partial specialization 1007 // uses ExplicitInfo to record the TypeAsWritten, but the source 1008 // locations should be retrieved from the instantiation pattern. 1009 using CTPSDecl = ClassTemplatePartialSpecializationDecl; 1010 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this)); 1011 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 1012 assert(inst_from != nullptr); 1013 return inst_from->getSourceRange(); 1014 } 1015 else { 1016 // No explicit info available. 1017 llvm::PointerUnion<ClassTemplateDecl *, 1018 ClassTemplatePartialSpecializationDecl *> 1019 inst_from = getInstantiatedFrom(); 1020 if (inst_from.isNull()) 1021 return getSpecializedTemplate()->getSourceRange(); 1022 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>()) 1023 return ctd->getSourceRange(); 1024 return inst_from.get<ClassTemplatePartialSpecializationDecl *>() 1025 ->getSourceRange(); 1026 } 1027 } 1028 1029 //===----------------------------------------------------------------------===// 1030 // ConceptDecl Implementation 1031 //===----------------------------------------------------------------------===// 1032 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, 1033 SourceLocation L, DeclarationName Name, 1034 TemplateParameterList *Params, 1035 Expr *ConstraintExpr) { 1036 bool Invalid = AdoptTemplateParameterList(Params, DC); 1037 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr); 1038 if (Invalid) 1039 TD->setInvalidDecl(); 1040 return TD; 1041 } 1042 1043 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, 1044 unsigned ID) { 1045 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), 1046 DeclarationName(), 1047 nullptr, nullptr); 1048 1049 return Result; 1050 } 1051 1052 //===----------------------------------------------------------------------===// 1053 // ImplicitConceptSpecializationDecl Implementation 1054 //===----------------------------------------------------------------------===// 1055 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl( 1056 DeclContext *DC, SourceLocation SL, 1057 ArrayRef<TemplateArgument> ConvertedArgs) 1058 : Decl(ImplicitConceptSpecialization, DC, SL), 1059 NumTemplateArgs(ConvertedArgs.size()) { 1060 setTemplateArguments(ConvertedArgs); 1061 } 1062 1063 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl( 1064 EmptyShell Empty, unsigned NumTemplateArgs) 1065 : Decl(ImplicitConceptSpecialization, Empty), 1066 NumTemplateArgs(NumTemplateArgs) {} 1067 1068 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( 1069 const ASTContext &C, DeclContext *DC, SourceLocation SL, 1070 ArrayRef<TemplateArgument> ConvertedArgs) { 1071 return new (C, DC, 1072 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size())) 1073 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs); 1074 } 1075 1076 ImplicitConceptSpecializationDecl * 1077 ImplicitConceptSpecializationDecl::CreateDeserialized( 1078 const ASTContext &C, unsigned ID, unsigned NumTemplateArgs) { 1079 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs)) 1080 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); 1081 } 1082 1083 void ImplicitConceptSpecializationDecl::setTemplateArguments( 1084 ArrayRef<TemplateArgument> Converted) { 1085 assert(Converted.size() == NumTemplateArgs); 1086 std::uninitialized_copy(Converted.begin(), Converted.end(), 1087 getTrailingObjects<TemplateArgument>()); 1088 } 1089 1090 //===----------------------------------------------------------------------===// 1091 // ClassTemplatePartialSpecializationDecl Implementation 1092 //===----------------------------------------------------------------------===// 1093 void ClassTemplatePartialSpecializationDecl::anchor() {} 1094 1095 ClassTemplatePartialSpecializationDecl:: 1096 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 1097 DeclContext *DC, 1098 SourceLocation StartLoc, 1099 SourceLocation IdLoc, 1100 TemplateParameterList *Params, 1101 ClassTemplateDecl *SpecializedTemplate, 1102 ArrayRef<TemplateArgument> Args, 1103 const ASTTemplateArgumentListInfo *ArgInfos, 1104 ClassTemplatePartialSpecializationDecl *PrevDecl) 1105 : ClassTemplateSpecializationDecl(Context, 1106 ClassTemplatePartialSpecialization, 1107 TK, DC, StartLoc, IdLoc, 1108 SpecializedTemplate, Args, PrevDecl), 1109 TemplateParams(Params), ArgsAsWritten(ArgInfos), 1110 InstantiatedFromMember(nullptr, false) { 1111 if (AdoptTemplateParameterList(Params, this)) 1112 setInvalidDecl(); 1113 } 1114 1115 ClassTemplatePartialSpecializationDecl * 1116 ClassTemplatePartialSpecializationDecl:: 1117 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 1118 SourceLocation StartLoc, SourceLocation IdLoc, 1119 TemplateParameterList *Params, 1120 ClassTemplateDecl *SpecializedTemplate, 1121 ArrayRef<TemplateArgument> Args, 1122 const TemplateArgumentListInfo &ArgInfos, 1123 QualType CanonInjectedType, 1124 ClassTemplatePartialSpecializationDecl *PrevDecl) { 1125 const ASTTemplateArgumentListInfo *ASTArgInfos = 1126 ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1127 1128 auto *Result = new (Context, DC) 1129 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, 1130 Params, SpecializedTemplate, Args, 1131 ASTArgInfos, PrevDecl); 1132 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1133 Result->setMayHaveOutOfDateDef(false); 1134 1135 Context.getInjectedClassNameType(Result, CanonInjectedType); 1136 return Result; 1137 } 1138 1139 ClassTemplatePartialSpecializationDecl * 1140 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1141 unsigned ID) { 1142 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); 1143 Result->setMayHaveOutOfDateDef(false); 1144 return Result; 1145 } 1146 1147 //===----------------------------------------------------------------------===// 1148 // FriendTemplateDecl Implementation 1149 //===----------------------------------------------------------------------===// 1150 1151 void FriendTemplateDecl::anchor() {} 1152 1153 FriendTemplateDecl * 1154 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, 1155 SourceLocation L, 1156 MutableArrayRef<TemplateParameterList *> Params, 1157 FriendUnion Friend, SourceLocation FLoc) { 1158 TemplateParameterList **TPL = nullptr; 1159 if (!Params.empty()) { 1160 TPL = new (Context) TemplateParameterList *[Params.size()]; 1161 llvm::copy(Params, TPL); 1162 } 1163 return new (Context, DC) 1164 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc); 1165 } 1166 1167 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 1168 unsigned ID) { 1169 return new (C, ID) FriendTemplateDecl(EmptyShell()); 1170 } 1171 1172 //===----------------------------------------------------------------------===// 1173 // TypeAliasTemplateDecl Implementation 1174 //===----------------------------------------------------------------------===// 1175 1176 TypeAliasTemplateDecl * 1177 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 1178 DeclarationName Name, 1179 TemplateParameterList *Params, NamedDecl *Decl) { 1180 bool Invalid = AdoptTemplateParameterList(Params, DC); 1181 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 1182 if (Invalid) 1183 TD->setInvalidDecl(); 1184 return TD; 1185 } 1186 1187 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 1188 unsigned ID) { 1189 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 1190 DeclarationName(), nullptr, nullptr); 1191 } 1192 1193 RedeclarableTemplateDecl::CommonBase * 1194 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 1195 auto *CommonPtr = new (C) Common; 1196 C.addDestruction(CommonPtr); 1197 return CommonPtr; 1198 } 1199 1200 //===----------------------------------------------------------------------===// 1201 // ClassScopeFunctionSpecializationDecl Implementation 1202 //===----------------------------------------------------------------------===// 1203 1204 void ClassScopeFunctionSpecializationDecl::anchor() {} 1205 1206 ClassScopeFunctionSpecializationDecl * 1207 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 1208 unsigned ID) { 1209 return new (C, ID) ClassScopeFunctionSpecializationDecl( 1210 nullptr, SourceLocation(), nullptr, nullptr); 1211 } 1212 1213 //===----------------------------------------------------------------------===// 1214 // VarTemplateDecl Implementation 1215 //===----------------------------------------------------------------------===// 1216 1217 VarTemplateDecl *VarTemplateDecl::getDefinition() { 1218 VarTemplateDecl *CurD = this; 1219 while (CurD) { 1220 if (CurD->isThisDeclarationADefinition()) 1221 return CurD; 1222 CurD = CurD->getPreviousDecl(); 1223 } 1224 return nullptr; 1225 } 1226 1227 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 1228 SourceLocation L, DeclarationName Name, 1229 TemplateParameterList *Params, 1230 VarDecl *Decl) { 1231 bool Invalid = AdoptTemplateParameterList(Params, DC); 1232 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 1233 if (Invalid) 1234 TD->setInvalidDecl(); 1235 return TD; 1236 } 1237 1238 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 1239 unsigned ID) { 1240 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 1241 DeclarationName(), nullptr, nullptr); 1242 } 1243 1244 void VarTemplateDecl::LoadLazySpecializations() const { 1245 loadLazySpecializationsImpl(); 1246 } 1247 1248 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 1249 VarTemplateDecl::getSpecializations() const { 1250 LoadLazySpecializations(); 1251 return getCommonPtr()->Specializations; 1252 } 1253 1254 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 1255 VarTemplateDecl::getPartialSpecializations() const { 1256 LoadLazySpecializations(); 1257 return getCommonPtr()->PartialSpecializations; 1258 } 1259 1260 RedeclarableTemplateDecl::CommonBase * 1261 VarTemplateDecl::newCommon(ASTContext &C) const { 1262 auto *CommonPtr = new (C) Common; 1263 C.addDestruction(CommonPtr); 1264 return CommonPtr; 1265 } 1266 1267 VarTemplateSpecializationDecl * 1268 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 1269 void *&InsertPos) { 1270 return findSpecializationImpl(getSpecializations(), InsertPos, Args); 1271 } 1272 1273 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 1274 void *InsertPos) { 1275 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos); 1276 } 1277 1278 VarTemplatePartialSpecializationDecl * 1279 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 1280 TemplateParameterList *TPL, void *&InsertPos) { 1281 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args, 1282 TPL); 1283 } 1284 1285 void VarTemplatePartialSpecializationDecl::Profile( 1286 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, 1287 TemplateParameterList *TPL, const ASTContext &Context) { 1288 ID.AddInteger(TemplateArgs.size()); 1289 for (const TemplateArgument &TemplateArg : TemplateArgs) 1290 TemplateArg.Profile(ID, Context); 1291 TPL->Profile(ID, Context); 1292 } 1293 1294 void VarTemplateDecl::AddPartialSpecialization( 1295 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1296 if (InsertPos) 1297 getPartialSpecializations().InsertNode(D, InsertPos); 1298 else { 1299 VarTemplatePartialSpecializationDecl *Existing = 1300 getPartialSpecializations().GetOrInsertNode(D); 1301 (void)Existing; 1302 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1303 } 1304 1305 if (ASTMutationListener *L = getASTMutationListener()) 1306 L->AddedCXXTemplateSpecialization(this, D); 1307 } 1308 1309 void VarTemplateDecl::getPartialSpecializations( 1310 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const { 1311 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1312 getPartialSpecializations(); 1313 PS.clear(); 1314 PS.reserve(PartialSpecs.size()); 1315 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs) 1316 PS.push_back(P.getMostRecentDecl()); 1317 } 1318 1319 VarTemplatePartialSpecializationDecl * 1320 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1321 VarTemplatePartialSpecializationDecl *D) { 1322 Decl *DCanon = D->getCanonicalDecl(); 1323 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 1324 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1325 return P.getMostRecentDecl(); 1326 } 1327 1328 return nullptr; 1329 } 1330 1331 //===----------------------------------------------------------------------===// 1332 // VarTemplateSpecializationDecl Implementation 1333 //===----------------------------------------------------------------------===// 1334 1335 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1336 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1337 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1338 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) 1339 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 1340 SpecializedTemplate->getIdentifier(), T, TInfo, S), 1341 SpecializedTemplate(SpecializedTemplate), 1342 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 1343 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1344 1345 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 1346 ASTContext &C) 1347 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 1348 QualType(), nullptr, SC_None), 1349 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1350 1351 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1352 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1353 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1354 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) { 1355 return new (Context, DC) VarTemplateSpecializationDecl( 1356 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 1357 SpecializedTemplate, T, TInfo, S, Args); 1358 } 1359 1360 VarTemplateSpecializationDecl * 1361 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1362 return new (C, ID) 1363 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 1364 } 1365 1366 void VarTemplateSpecializationDecl::getNameForDiagnostic( 1367 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1368 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1369 1370 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this); 1371 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 1372 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 1373 printTemplateArgumentList( 1374 OS, ArgsAsWritten->arguments(), Policy, 1375 getSpecializedTemplate()->getTemplateParameters()); 1376 } else { 1377 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1378 printTemplateArgumentList( 1379 OS, TemplateArgs.asArray(), Policy, 1380 getSpecializedTemplate()->getTemplateParameters()); 1381 } 1382 } 1383 1384 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1385 if (const auto *PartialSpec = 1386 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1387 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1388 return SpecializedTemplate.get<VarTemplateDecl *>(); 1389 } 1390 1391 void VarTemplateSpecializationDecl::setTemplateArgsInfo( 1392 const TemplateArgumentListInfo &ArgsInfo) { 1393 TemplateArgsInfo = 1394 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo); 1395 } 1396 1397 void VarTemplateSpecializationDecl::setTemplateArgsInfo( 1398 const ASTTemplateArgumentListInfo *ArgsInfo) { 1399 TemplateArgsInfo = 1400 ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo); 1401 } 1402 1403 SourceRange VarTemplateSpecializationDecl::getSourceRange() const { 1404 if (isExplicitSpecialization() && !hasInit()) { 1405 if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsInfo()) 1406 return SourceRange(getOuterLocStart(), Info->getRAngleLoc()); 1407 } 1408 return VarDecl::getSourceRange(); 1409 } 1410 1411 1412 //===----------------------------------------------------------------------===// 1413 // VarTemplatePartialSpecializationDecl Implementation 1414 //===----------------------------------------------------------------------===// 1415 1416 void VarTemplatePartialSpecializationDecl::anchor() {} 1417 1418 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1419 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1420 SourceLocation IdLoc, TemplateParameterList *Params, 1421 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1422 StorageClass S, ArrayRef<TemplateArgument> Args, 1423 const ASTTemplateArgumentListInfo *ArgInfos) 1424 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 1425 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1426 TInfo, S, Args), 1427 TemplateParams(Params), ArgsAsWritten(ArgInfos), 1428 InstantiatedFromMember(nullptr, false) { 1429 if (AdoptTemplateParameterList(Params, DC)) 1430 setInvalidDecl(); 1431 } 1432 1433 VarTemplatePartialSpecializationDecl * 1434 VarTemplatePartialSpecializationDecl::Create( 1435 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1436 SourceLocation IdLoc, TemplateParameterList *Params, 1437 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1438 StorageClass S, ArrayRef<TemplateArgument> Args, 1439 const TemplateArgumentListInfo &ArgInfos) { 1440 const ASTTemplateArgumentListInfo *ASTArgInfos 1441 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1442 1443 auto *Result = 1444 new (Context, DC) VarTemplatePartialSpecializationDecl( 1445 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 1446 S, Args, ASTArgInfos); 1447 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1448 return Result; 1449 } 1450 1451 VarTemplatePartialSpecializationDecl * 1452 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1453 unsigned ID) { 1454 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 1455 } 1456 1457 SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const { 1458 if (isExplicitSpecialization() && !hasInit()) { 1459 if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten()) 1460 return SourceRange(getOuterLocStart(), Info->getRAngleLoc()); 1461 } 1462 return VarDecl::getSourceRange(); 1463 } 1464 1465 static TemplateParameterList * 1466 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { 1467 // typename T 1468 auto *T = TemplateTypeParmDecl::Create( 1469 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0, 1470 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false, 1471 /*HasTypeConstraint=*/false); 1472 T->setImplicit(true); 1473 1474 // T ...Ints 1475 TypeSourceInfo *TI = 1476 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0)); 1477 auto *N = NonTypeTemplateParmDecl::Create( 1478 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1479 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI); 1480 N->setImplicit(true); 1481 1482 // <typename T, T ...Ints> 1483 NamedDecl *P[2] = {T, N}; 1484 auto *TPL = TemplateParameterList::Create( 1485 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr); 1486 1487 // template <typename T, ...Ints> class IntSeq 1488 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create( 1489 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0, 1490 /*ParameterPack=*/false, /*Id=*/nullptr, TPL); 1491 TemplateTemplateParm->setImplicit(true); 1492 1493 // typename T 1494 auto *TemplateTypeParm = TemplateTypeParmDecl::Create( 1495 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1496 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false, 1497 /*HasTypeConstraint=*/false); 1498 TemplateTypeParm->setImplicit(true); 1499 1500 // T N 1501 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo( 1502 QualType(TemplateTypeParm->getTypeForDecl(), 0)); 1503 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create( 1504 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2, 1505 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1506 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm, 1507 NonTypeTemplateParm}; 1508 1509 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N> 1510 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1511 Params, SourceLocation(), nullptr); 1512 } 1513 1514 static TemplateParameterList * 1515 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) { 1516 // std::size_t Index 1517 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType()); 1518 auto *Index = NonTypeTemplateParmDecl::Create( 1519 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0, 1520 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1521 1522 // typename ...T 1523 auto *Ts = TemplateTypeParmDecl::Create( 1524 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1525 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true, 1526 /*HasTypeConstraint=*/false); 1527 Ts->setImplicit(true); 1528 1529 // template <std::size_t Index, typename ...T> 1530 NamedDecl *Params[] = {Index, Ts}; 1531 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1532 llvm::ArrayRef(Params), SourceLocation(), 1533 nullptr); 1534 } 1535 1536 static TemplateParameterList *createBuiltinTemplateParameterList( 1537 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) { 1538 switch (BTK) { 1539 case BTK__make_integer_seq: 1540 return createMakeIntegerSeqParameterList(C, DC); 1541 case BTK__type_pack_element: 1542 return createTypePackElementParameterList(C, DC); 1543 } 1544 1545 llvm_unreachable("unhandled BuiltinTemplateKind!"); 1546 } 1547 1548 void BuiltinTemplateDecl::anchor() {} 1549 1550 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, 1551 DeclarationName Name, 1552 BuiltinTemplateKind BTK) 1553 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name, 1554 createBuiltinTemplateParameterList(C, DC, BTK)), 1555 BTK(BTK) {} 1556 1557 void TypeConstraint::print(llvm::raw_ostream &OS, PrintingPolicy Policy) const { 1558 if (NestedNameSpec) 1559 NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy); 1560 ConceptName.printName(OS, Policy); 1561 if (hasExplicitTemplateArgs()) { 1562 OS << "<"; 1563 // FIXME: Find corresponding parameter for argument 1564 for (auto &ArgLoc : ArgsAsWritten->arguments()) 1565 ArgLoc.getArgument().print(Policy, OS, /*IncludeType*/ false); 1566 OS << ">"; 1567 } 1568 } 1569 1570 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, 1571 QualType T, 1572 const APValue &V) { 1573 DeclContext *DC = C.getTranslationUnitDecl(); 1574 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V); 1575 C.addDestruction(&TPOD->Value); 1576 return TPOD; 1577 } 1578 1579 TemplateParamObjectDecl * 1580 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1581 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); 1582 C.addDestruction(&TPOD->Value); 1583 return TPOD; 1584 } 1585 1586 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS, 1587 const PrintingPolicy &Policy) const { 1588 OS << "<template param "; 1589 printAsExpr(OS, Policy); 1590 OS << ">"; 1591 } 1592 1593 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const { 1594 printAsExpr(OS, getASTContext().getPrintingPolicy()); 1595 } 1596 1597 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS, 1598 const PrintingPolicy &Policy) const { 1599 getType().getUnqualifiedType().print(OS, Policy); 1600 printAsInit(OS, Policy); 1601 } 1602 1603 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const { 1604 printAsInit(OS, getASTContext().getPrintingPolicy()); 1605 } 1606 1607 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS, 1608 const PrintingPolicy &Policy) const { 1609 getValue().printPretty(OS, Policy, getType(), &getASTContext()); 1610 } 1611 1612 TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) { 1613 switch (D->getKind()) { 1614 case Decl::Kind::ClassTemplate: 1615 return cast<ClassTemplateDecl>(D)->getTemplateParameters(); 1616 case Decl::Kind::ClassTemplateSpecialization: { 1617 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D); 1618 auto P = CTSD->getSpecializedTemplateOrPartial(); 1619 if (const auto *CTPSD = 1620 P.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) 1621 return CTPSD->getTemplateParameters(); 1622 return cast<ClassTemplateDecl *>(P)->getTemplateParameters(); 1623 } 1624 case Decl::Kind::ClassTemplatePartialSpecialization: 1625 return cast<ClassTemplatePartialSpecializationDecl>(D) 1626 ->getTemplateParameters(); 1627 case Decl::Kind::TypeAliasTemplate: 1628 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters(); 1629 case Decl::Kind::BuiltinTemplate: 1630 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters(); 1631 case Decl::Kind::CXXDeductionGuide: 1632 case Decl::Kind::CXXConversion: 1633 case Decl::Kind::CXXConstructor: 1634 case Decl::Kind::CXXDestructor: 1635 case Decl::Kind::CXXMethod: 1636 case Decl::Kind::Function: 1637 return cast<FunctionDecl>(D) 1638 ->getTemplateSpecializationInfo() 1639 ->getTemplate() 1640 ->getTemplateParameters(); 1641 case Decl::Kind::FunctionTemplate: 1642 return cast<FunctionTemplateDecl>(D)->getTemplateParameters(); 1643 case Decl::Kind::VarTemplate: 1644 return cast<VarTemplateDecl>(D)->getTemplateParameters(); 1645 case Decl::Kind::VarTemplateSpecialization: { 1646 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D); 1647 auto P = VTSD->getSpecializedTemplateOrPartial(); 1648 if (const auto *VTPSD = 1649 P.dyn_cast<VarTemplatePartialSpecializationDecl *>()) 1650 return VTPSD->getTemplateParameters(); 1651 return cast<VarTemplateDecl *>(P)->getTemplateParameters(); 1652 } 1653 case Decl::Kind::VarTemplatePartialSpecialization: 1654 return cast<VarTemplatePartialSpecializationDecl>(D) 1655 ->getTemplateParameters(); 1656 case Decl::Kind::TemplateTemplateParm: 1657 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters(); 1658 case Decl::Kind::Concept: 1659 return cast<ConceptDecl>(D)->getTemplateParameters(); 1660 default: 1661 llvm_unreachable("Unhandled templated declaration kind"); 1662 } 1663 } 1664