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 GlobalDeclID *Specs = CommonBasePtr->LazySpecializations; 341 CommonBasePtr->LazySpecializations = nullptr; 342 unsigned SpecSize = (*Specs++).getRawValue(); 343 for (unsigned I = 0; I != SpecSize; ++I) 344 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 345 } 346 } 347 348 template<class EntryType, typename... ProfileArguments> 349 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * 350 RedeclarableTemplateDecl::findSpecializationImpl( 351 llvm::FoldingSetVector<EntryType> &Specs, void *&InsertPos, 352 ProfileArguments&&... ProfileArgs) { 353 using SETraits = SpecEntryTraits<EntryType>; 354 355 llvm::FoldingSetNodeID ID; 356 EntryType::Profile(ID, std::forward<ProfileArguments>(ProfileArgs)..., 357 getASTContext()); 358 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 359 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr; 360 } 361 362 template<class Derived, class EntryType> 363 void RedeclarableTemplateDecl::addSpecializationImpl( 364 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry, 365 void *InsertPos) { 366 using SETraits = SpecEntryTraits<EntryType>; 367 368 if (InsertPos) { 369 #ifndef NDEBUG 370 void *CorrectInsertPos; 371 assert(!findSpecializationImpl(Specializations, 372 CorrectInsertPos, 373 SETraits::getTemplateArgs(Entry)) && 374 InsertPos == CorrectInsertPos && 375 "given incorrect InsertPos for specialization"); 376 #endif 377 Specializations.InsertNode(Entry, InsertPos); 378 } else { 379 EntryType *Existing = Specializations.GetOrInsertNode(Entry); 380 (void)Existing; 381 assert(SETraits::getDecl(Existing)->isCanonicalDecl() && 382 "non-canonical specialization?"); 383 } 384 385 if (ASTMutationListener *L = getASTMutationListener()) 386 L->AddedCXXTemplateSpecialization(cast<Derived>(this), 387 SETraits::getDecl(Entry)); 388 } 389 390 ArrayRef<TemplateArgument> RedeclarableTemplateDecl::getInjectedTemplateArgs() { 391 TemplateParameterList *Params = getTemplateParameters(); 392 auto *CommonPtr = getCommonPtr(); 393 if (!CommonPtr->InjectedArgs) { 394 auto &Context = getASTContext(); 395 SmallVector<TemplateArgument, 16> TemplateArgs; 396 Context.getInjectedTemplateArgs(Params, TemplateArgs); 397 CommonPtr->InjectedArgs = 398 new (Context) TemplateArgument[TemplateArgs.size()]; 399 std::copy(TemplateArgs.begin(), TemplateArgs.end(), 400 CommonPtr->InjectedArgs); 401 } 402 403 return llvm::ArrayRef(CommonPtr->InjectedArgs, Params->size()); 404 } 405 406 //===----------------------------------------------------------------------===// 407 // FunctionTemplateDecl Implementation 408 //===----------------------------------------------------------------------===// 409 410 FunctionTemplateDecl * 411 FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 412 DeclarationName Name, 413 TemplateParameterList *Params, NamedDecl *Decl) { 414 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 415 auto *TD = new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl); 416 if (Invalid) 417 TD->setInvalidDecl(); 418 return TD; 419 } 420 421 FunctionTemplateDecl * 422 FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 423 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), 424 DeclarationName(), nullptr, nullptr); 425 } 426 427 RedeclarableTemplateDecl::CommonBase * 428 FunctionTemplateDecl::newCommon(ASTContext &C) const { 429 auto *CommonPtr = new (C) Common; 430 C.addDestruction(CommonPtr); 431 return CommonPtr; 432 } 433 434 void FunctionTemplateDecl::LoadLazySpecializations() const { 435 loadLazySpecializationsImpl(); 436 } 437 438 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & 439 FunctionTemplateDecl::getSpecializations() const { 440 LoadLazySpecializations(); 441 return getCommonPtr()->Specializations; 442 } 443 444 FunctionDecl * 445 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 446 void *&InsertPos) { 447 return findSpecializationImpl(getSpecializations(), InsertPos, Args); 448 } 449 450 void FunctionTemplateDecl::addSpecialization( 451 FunctionTemplateSpecializationInfo *Info, void *InsertPos) { 452 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info, 453 InsertPos); 454 } 455 456 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) { 457 using Base = RedeclarableTemplateDecl; 458 459 // If we haven't created a common pointer yet, then it can just be created 460 // with the usual method. 461 if (!Base::Common) 462 return; 463 464 Common *ThisCommon = static_cast<Common *>(Base::Common); 465 Common *PrevCommon = nullptr; 466 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls; 467 for (; Prev; Prev = Prev->getPreviousDecl()) { 468 if (Prev->Base::Common) { 469 PrevCommon = static_cast<Common *>(Prev->Base::Common); 470 break; 471 } 472 PreviousDecls.push_back(Prev); 473 } 474 475 // If the previous redecl chain hasn't created a common pointer yet, then just 476 // use this common pointer. 477 if (!PrevCommon) { 478 for (auto *D : PreviousDecls) 479 D->Base::Common = ThisCommon; 480 return; 481 } 482 483 // Ensure we don't leak any important state. 484 assert(ThisCommon->Specializations.size() == 0 && 485 "Can't merge incompatible declarations!"); 486 487 Base::Common = PrevCommon; 488 } 489 490 //===----------------------------------------------------------------------===// 491 // ClassTemplateDecl Implementation 492 //===----------------------------------------------------------------------===// 493 494 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, 495 SourceLocation L, 496 DeclarationName Name, 497 TemplateParameterList *Params, 498 NamedDecl *Decl) { 499 bool Invalid = AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 500 auto *TD = new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl); 501 if (Invalid) 502 TD->setInvalidDecl(); 503 return TD; 504 } 505 506 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 507 GlobalDeclID ID) { 508 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), 509 DeclarationName(), nullptr, nullptr); 510 } 511 512 void ClassTemplateDecl::LoadLazySpecializations() const { 513 loadLazySpecializationsImpl(); 514 } 515 516 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 517 ClassTemplateDecl::getSpecializations() const { 518 LoadLazySpecializations(); 519 return getCommonPtr()->Specializations; 520 } 521 522 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 523 ClassTemplateDecl::getPartialSpecializations() const { 524 LoadLazySpecializations(); 525 return getCommonPtr()->PartialSpecializations; 526 } 527 528 RedeclarableTemplateDecl::CommonBase * 529 ClassTemplateDecl::newCommon(ASTContext &C) const { 530 auto *CommonPtr = new (C) Common; 531 C.addDestruction(CommonPtr); 532 return CommonPtr; 533 } 534 535 ClassTemplateSpecializationDecl * 536 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 537 void *&InsertPos) { 538 return findSpecializationImpl(getSpecializations(), InsertPos, Args); 539 } 540 541 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 542 void *InsertPos) { 543 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos); 544 } 545 546 ClassTemplatePartialSpecializationDecl * 547 ClassTemplateDecl::findPartialSpecialization( 548 ArrayRef<TemplateArgument> Args, 549 TemplateParameterList *TPL, void *&InsertPos) { 550 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args, 551 TPL); 552 } 553 554 void ClassTemplatePartialSpecializationDecl::Profile( 555 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, 556 TemplateParameterList *TPL, const ASTContext &Context) { 557 ID.AddInteger(TemplateArgs.size()); 558 for (const TemplateArgument &TemplateArg : TemplateArgs) 559 TemplateArg.Profile(ID, Context); 560 TPL->Profile(ID, Context); 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 TemplateName Name = Context.getQualifiedTemplateName( 631 /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this)); 632 CommonPtr->InjectedClassNameType = 633 Context.getTemplateSpecializationType(Name, TemplateArgs); 634 return CommonPtr->InjectedClassNameType; 635 } 636 637 //===----------------------------------------------------------------------===// 638 // TemplateTypeParm Allocation/Deallocation Method Implementations 639 //===----------------------------------------------------------------------===// 640 641 TemplateTypeParmDecl *TemplateTypeParmDecl::Create( 642 const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, 643 SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, 644 bool Typename, bool ParameterPack, bool HasTypeConstraint, 645 std::optional<unsigned> NumExpanded) { 646 auto *TTPDecl = 647 new (C, DC, 648 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0)) 649 TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename, 650 HasTypeConstraint, NumExpanded); 651 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 652 TTPDecl->setTypeForDecl(TTPType.getTypePtr()); 653 return TTPDecl; 654 } 655 656 TemplateTypeParmDecl * 657 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) { 658 return new (C, ID) 659 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, 660 false, false, std::nullopt); 661 } 662 663 TemplateTypeParmDecl * 664 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID, 665 bool HasTypeConstraint) { 666 return new (C, ID, 667 additionalSizeToAlloc<TypeConstraint>(HasTypeConstraint ? 1 : 0)) 668 TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, 669 false, HasTypeConstraint, std::nullopt); 670 } 671 672 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 673 return hasDefaultArgument() ? getDefaultArgument().getLocation() 674 : SourceLocation(); 675 } 676 677 SourceRange TemplateTypeParmDecl::getSourceRange() const { 678 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 679 return SourceRange(getBeginLoc(), 680 getDefaultArgument().getSourceRange().getEnd()); 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 if (getDeclName().isEmpty()) 685 return SourceRange(getBeginLoc()); 686 return TypeDecl::getSourceRange(); 687 } 688 689 void TemplateTypeParmDecl::setDefaultArgument( 690 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 691 if (DefArg.getArgument().isNull()) 692 DefaultArgument.set(nullptr); 693 else 694 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 695 } 696 697 unsigned TemplateTypeParmDecl::getDepth() const { 698 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getDepth(); 699 } 700 701 unsigned TemplateTypeParmDecl::getIndex() const { 702 return getTypeForDecl()->castAs<TemplateTypeParmType>()->getIndex(); 703 } 704 705 bool TemplateTypeParmDecl::isParameterPack() const { 706 return getTypeForDecl()->castAs<TemplateTypeParmType>()->isParameterPack(); 707 } 708 709 void TemplateTypeParmDecl::setTypeConstraint( 710 ConceptReference *Loc, Expr *ImmediatelyDeclaredConstraint) { 711 assert(HasTypeConstraint && 712 "HasTypeConstraint=true must be passed at construction in order to " 713 "call setTypeConstraint"); 714 assert(!TypeConstraintInitialized && 715 "TypeConstraint was already initialized!"); 716 new (getTrailingObjects<TypeConstraint>()) 717 TypeConstraint(Loc, ImmediatelyDeclaredConstraint); 718 TypeConstraintInitialized = true; 719 } 720 721 //===----------------------------------------------------------------------===// 722 // NonTypeTemplateParmDecl Method Implementations 723 //===----------------------------------------------------------------------===// 724 725 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( 726 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, 727 unsigned P, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, 728 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) 729 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 730 TemplateParmPosition(D, P), ParameterPack(true), 731 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) { 732 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) { 733 auto TypesAndInfos = 734 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); 735 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 736 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]); 737 TypesAndInfos[I].second = ExpandedTInfos[I]; 738 } 739 } 740 } 741 742 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( 743 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 744 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, 745 QualType T, bool ParameterPack, TypeSourceInfo *TInfo) { 746 AutoType *AT = 747 C.getLangOpts().CPlusPlus20 ? T->getContainedAutoType() : nullptr; 748 return new (C, DC, 749 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, 750 Expr *>(0, 751 AT && AT->isConstrained() ? 1 : 0)) 752 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, ParameterPack, 753 TInfo); 754 } 755 756 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( 757 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 758 SourceLocation IdLoc, unsigned D, unsigned P, const IdentifierInfo *Id, 759 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, 760 ArrayRef<TypeSourceInfo *> ExpandedTInfos) { 761 AutoType *AT = TInfo->getType()->getContainedAutoType(); 762 return new (C, DC, 763 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, 764 Expr *>( 765 ExpandedTypes.size(), AT && AT->isConstrained() ? 1 : 0)) 766 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 767 ExpandedTypes, ExpandedTInfos); 768 } 769 770 NonTypeTemplateParmDecl * 771 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, 772 bool HasTypeConstraint) { 773 return new (C, ID, additionalSizeToAlloc<std::pair<QualType, 774 TypeSourceInfo *>, 775 Expr *>(0, 776 HasTypeConstraint ? 1 : 0)) 777 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 778 0, 0, nullptr, QualType(), false, nullptr); 779 } 780 781 NonTypeTemplateParmDecl * 782 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, 783 unsigned NumExpandedTypes, 784 bool HasTypeConstraint) { 785 auto *NTTP = 786 new (C, ID, 787 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>, Expr *>( 788 NumExpandedTypes, HasTypeConstraint ? 1 : 0)) 789 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 790 0, 0, nullptr, QualType(), nullptr, 791 std::nullopt, std::nullopt); 792 NTTP->NumExpandedTypes = NumExpandedTypes; 793 return NTTP; 794 } 795 796 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 797 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 798 return SourceRange(getOuterLocStart(), 799 getDefaultArgument().getSourceRange().getEnd()); 800 return DeclaratorDecl::getSourceRange(); 801 } 802 803 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 804 return hasDefaultArgument() ? getDefaultArgument().getSourceRange().getBegin() 805 : SourceLocation(); 806 } 807 808 void NonTypeTemplateParmDecl::setDefaultArgument( 809 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 810 if (DefArg.getArgument().isNull()) 811 DefaultArgument.set(nullptr); 812 else 813 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 814 } 815 816 //===----------------------------------------------------------------------===// 817 // TemplateTemplateParmDecl Method Implementations 818 //===----------------------------------------------------------------------===// 819 820 void TemplateTemplateParmDecl::anchor() {} 821 822 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 823 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 824 IdentifierInfo *Id, bool Typename, TemplateParameterList *Params, 825 ArrayRef<TemplateParameterList *> Expansions) 826 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 827 TemplateParmPosition(D, P), Typename(Typename), ParameterPack(true), 828 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) { 829 if (!Expansions.empty()) 830 std::uninitialized_copy(Expansions.begin(), Expansions.end(), 831 getTrailingObjects<TemplateParameterList *>()); 832 } 833 834 TemplateTemplateParmDecl * 835 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 836 SourceLocation L, unsigned D, unsigned P, 837 bool ParameterPack, IdentifierInfo *Id, 838 bool Typename, TemplateParameterList *Params) { 839 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 840 Typename, Params); 841 } 842 843 TemplateTemplateParmDecl * 844 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 845 SourceLocation L, unsigned D, unsigned P, 846 IdentifierInfo *Id, bool Typename, 847 TemplateParameterList *Params, 848 ArrayRef<TemplateParameterList *> Expansions) { 849 return new (C, DC, 850 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size())) 851 TemplateTemplateParmDecl(DC, L, D, P, Id, Typename, Params, Expansions); 852 } 853 854 TemplateTemplateParmDecl * 855 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 856 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 857 false, nullptr, false, nullptr); 858 } 859 860 TemplateTemplateParmDecl * 861 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, 862 unsigned NumExpansions) { 863 auto *TTP = 864 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) 865 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 866 false, nullptr, std::nullopt); 867 TTP->NumExpandedParams = NumExpansions; 868 return TTP; 869 } 870 871 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 872 return hasDefaultArgument() ? getDefaultArgument().getLocation() 873 : SourceLocation(); 874 } 875 876 void TemplateTemplateParmDecl::setDefaultArgument( 877 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 878 if (DefArg.getArgument().isNull()) 879 DefaultArgument.set(nullptr); 880 else 881 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 882 } 883 884 //===----------------------------------------------------------------------===// 885 // TemplateArgumentList Implementation 886 //===----------------------------------------------------------------------===// 887 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args) 888 : NumArguments(Args.size()) { 889 std::uninitialized_copy(Args.begin(), Args.end(), 890 getTrailingObjects<TemplateArgument>()); 891 } 892 893 TemplateArgumentList * 894 TemplateArgumentList::CreateCopy(ASTContext &Context, 895 ArrayRef<TemplateArgument> Args) { 896 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size())); 897 return new (Mem) TemplateArgumentList(Args); 898 } 899 900 FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create( 901 ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template, 902 TemplateSpecializationKind TSK, TemplateArgumentList *TemplateArgs, 903 const TemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, 904 MemberSpecializationInfo *MSInfo) { 905 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 906 if (TemplateArgsAsWritten) 907 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 908 *TemplateArgsAsWritten); 909 910 void *Mem = 911 C.Allocate(totalSizeToAlloc<MemberSpecializationInfo *>(MSInfo ? 1 : 0)); 912 return new (Mem) FunctionTemplateSpecializationInfo( 913 FD, Template, TSK, TemplateArgs, ArgsAsWritten, POI, MSInfo); 914 } 915 916 //===----------------------------------------------------------------------===// 917 // ClassTemplateSpecializationDecl Implementation 918 //===----------------------------------------------------------------------===// 919 920 ClassTemplateSpecializationDecl:: 921 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 922 DeclContext *DC, SourceLocation StartLoc, 923 SourceLocation IdLoc, 924 ClassTemplateDecl *SpecializedTemplate, 925 ArrayRef<TemplateArgument> Args, 926 ClassTemplateSpecializationDecl *PrevDecl) 927 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 928 SpecializedTemplate->getIdentifier(), PrevDecl), 929 SpecializedTemplate(SpecializedTemplate), 930 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 931 SpecializationKind(TSK_Undeclared) { 932 } 933 934 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 935 Kind DK) 936 : CXXRecordDecl(DK, TagTypeKind::Struct, C, nullptr, SourceLocation(), 937 SourceLocation(), nullptr, nullptr), 938 SpecializationKind(TSK_Undeclared) {} 939 940 ClassTemplateSpecializationDecl * 941 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 942 DeclContext *DC, 943 SourceLocation StartLoc, 944 SourceLocation IdLoc, 945 ClassTemplateDecl *SpecializedTemplate, 946 ArrayRef<TemplateArgument> Args, 947 ClassTemplateSpecializationDecl *PrevDecl) { 948 auto *Result = 949 new (Context, DC) ClassTemplateSpecializationDecl( 950 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 951 SpecializedTemplate, Args, PrevDecl); 952 Result->setMayHaveOutOfDateDef(false); 953 954 // If the template decl is incomplete, copy the external lexical storage from 955 // the base template. This allows instantiations of incomplete types to 956 // complete using the external AST if the template's declaration came from an 957 // external AST. 958 if (!SpecializedTemplate->getTemplatedDecl()->isCompleteDefinition()) 959 Result->setHasExternalLexicalStorage( 960 SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage()); 961 962 Context.getTypeDeclType(Result, PrevDecl); 963 return Result; 964 } 965 966 ClassTemplateSpecializationDecl * 967 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 968 GlobalDeclID ID) { 969 auto *Result = 970 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 971 Result->setMayHaveOutOfDateDef(false); 972 return Result; 973 } 974 975 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 976 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 977 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 978 979 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this); 980 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 981 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 982 printTemplateArgumentList( 983 OS, ArgsAsWritten->arguments(), Policy, 984 getSpecializedTemplate()->getTemplateParameters()); 985 } else { 986 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 987 printTemplateArgumentList( 988 OS, TemplateArgs.asArray(), Policy, 989 getSpecializedTemplate()->getTemplateParameters()); 990 } 991 } 992 993 ClassTemplateDecl * 994 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 995 if (const auto *PartialSpec = 996 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 997 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 998 return SpecializedTemplate.get<ClassTemplateDecl*>(); 999 } 1000 1001 SourceRange 1002 ClassTemplateSpecializationDecl::getSourceRange() const { 1003 switch (getSpecializationKind()) { 1004 case TSK_Undeclared: 1005 case TSK_ImplicitInstantiation: { 1006 llvm::PointerUnion<ClassTemplateDecl *, 1007 ClassTemplatePartialSpecializationDecl *> 1008 Pattern = getSpecializedTemplateOrPartial(); 1009 assert(!Pattern.isNull() && 1010 "Class template specialization without pattern?"); 1011 if (const auto *CTPSD = 1012 Pattern.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) 1013 return CTPSD->getSourceRange(); 1014 return Pattern.get<ClassTemplateDecl *>()->getSourceRange(); 1015 } 1016 case TSK_ExplicitSpecialization: { 1017 SourceRange Range = CXXRecordDecl::getSourceRange(); 1018 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten(); 1019 !isThisDeclarationADefinition() && Args) 1020 Range.setEnd(Args->getRAngleLoc()); 1021 return Range; 1022 } 1023 case TSK_ExplicitInstantiationDeclaration: 1024 case TSK_ExplicitInstantiationDefinition: { 1025 SourceRange Range = CXXRecordDecl::getSourceRange(); 1026 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid()) 1027 Range.setBegin(ExternKW); 1028 else if (SourceLocation TemplateKW = getTemplateKeywordLoc(); 1029 TemplateKW.isValid()) 1030 Range.setBegin(TemplateKW); 1031 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten()) 1032 Range.setEnd(Args->getRAngleLoc()); 1033 return Range; 1034 } 1035 } 1036 llvm_unreachable("unhandled template specialization kind"); 1037 } 1038 1039 void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { 1040 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>(); 1041 if (!Info) { 1042 // Don't allocate if the location is invalid. 1043 if (Loc.isInvalid()) 1044 return; 1045 Info = new (getASTContext()) ExplicitInstantiationInfo; 1046 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); 1047 ExplicitInfo = Info; 1048 } 1049 Info->ExternKeywordLoc = Loc; 1050 } 1051 1052 void ClassTemplateSpecializationDecl::setTemplateKeywordLoc( 1053 SourceLocation Loc) { 1054 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>(); 1055 if (!Info) { 1056 // Don't allocate if the location is invalid. 1057 if (Loc.isInvalid()) 1058 return; 1059 Info = new (getASTContext()) ExplicitInstantiationInfo; 1060 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); 1061 ExplicitInfo = Info; 1062 } 1063 Info->TemplateKeywordLoc = Loc; 1064 } 1065 1066 //===----------------------------------------------------------------------===// 1067 // ConceptDecl Implementation 1068 //===----------------------------------------------------------------------===// 1069 ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, 1070 SourceLocation L, DeclarationName Name, 1071 TemplateParameterList *Params, 1072 Expr *ConstraintExpr) { 1073 bool Invalid = AdoptTemplateParameterList(Params, DC); 1074 auto *TD = new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr); 1075 if (Invalid) 1076 TD->setInvalidDecl(); 1077 return TD; 1078 } 1079 1080 ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 1081 ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), 1082 DeclarationName(), 1083 nullptr, nullptr); 1084 1085 return Result; 1086 } 1087 1088 //===----------------------------------------------------------------------===// 1089 // ImplicitConceptSpecializationDecl Implementation 1090 //===----------------------------------------------------------------------===// 1091 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl( 1092 DeclContext *DC, SourceLocation SL, 1093 ArrayRef<TemplateArgument> ConvertedArgs) 1094 : Decl(ImplicitConceptSpecialization, DC, SL), 1095 NumTemplateArgs(ConvertedArgs.size()) { 1096 setTemplateArguments(ConvertedArgs); 1097 } 1098 1099 ImplicitConceptSpecializationDecl::ImplicitConceptSpecializationDecl( 1100 EmptyShell Empty, unsigned NumTemplateArgs) 1101 : Decl(ImplicitConceptSpecialization, Empty), 1102 NumTemplateArgs(NumTemplateArgs) {} 1103 1104 ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( 1105 const ASTContext &C, DeclContext *DC, SourceLocation SL, 1106 ArrayRef<TemplateArgument> ConvertedArgs) { 1107 return new (C, DC, 1108 additionalSizeToAlloc<TemplateArgument>(ConvertedArgs.size())) 1109 ImplicitConceptSpecializationDecl(DC, SL, ConvertedArgs); 1110 } 1111 1112 ImplicitConceptSpecializationDecl * 1113 ImplicitConceptSpecializationDecl::CreateDeserialized( 1114 const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) { 1115 return new (C, ID, additionalSizeToAlloc<TemplateArgument>(NumTemplateArgs)) 1116 ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); 1117 } 1118 1119 void ImplicitConceptSpecializationDecl::setTemplateArguments( 1120 ArrayRef<TemplateArgument> Converted) { 1121 assert(Converted.size() == NumTemplateArgs); 1122 std::uninitialized_copy(Converted.begin(), Converted.end(), 1123 getTrailingObjects<TemplateArgument>()); 1124 } 1125 1126 //===----------------------------------------------------------------------===// 1127 // ClassTemplatePartialSpecializationDecl Implementation 1128 //===----------------------------------------------------------------------===// 1129 void ClassTemplatePartialSpecializationDecl::anchor() {} 1130 1131 ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl( 1132 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, 1133 SourceLocation IdLoc, TemplateParameterList *Params, 1134 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, 1135 ClassTemplatePartialSpecializationDecl *PrevDecl) 1136 : ClassTemplateSpecializationDecl( 1137 Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc, 1138 SpecializedTemplate, Args, PrevDecl), 1139 TemplateParams(Params), InstantiatedFromMember(nullptr, false) { 1140 if (AdoptTemplateParameterList(Params, this)) 1141 setInvalidDecl(); 1142 } 1143 1144 ClassTemplatePartialSpecializationDecl * 1145 ClassTemplatePartialSpecializationDecl::Create( 1146 ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, 1147 SourceLocation IdLoc, TemplateParameterList *Params, 1148 ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, 1149 QualType CanonInjectedType, 1150 ClassTemplatePartialSpecializationDecl *PrevDecl) { 1151 auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl( 1152 Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args, 1153 PrevDecl); 1154 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1155 Result->setMayHaveOutOfDateDef(false); 1156 1157 Context.getInjectedClassNameType(Result, CanonInjectedType); 1158 return Result; 1159 } 1160 1161 ClassTemplatePartialSpecializationDecl * 1162 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1163 GlobalDeclID ID) { 1164 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); 1165 Result->setMayHaveOutOfDateDef(false); 1166 return Result; 1167 } 1168 1169 SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const { 1170 if (const ClassTemplatePartialSpecializationDecl *MT = 1171 getInstantiatedFromMember(); 1172 MT && !isMemberSpecialization()) 1173 return MT->getSourceRange(); 1174 SourceRange Range = ClassTemplateSpecializationDecl::getSourceRange(); 1175 if (const TemplateParameterList *TPL = getTemplateParameters(); 1176 TPL && !getNumTemplateParameterLists()) 1177 Range.setBegin(TPL->getTemplateLoc()); 1178 return Range; 1179 } 1180 1181 //===----------------------------------------------------------------------===// 1182 // FriendTemplateDecl Implementation 1183 //===----------------------------------------------------------------------===// 1184 1185 void FriendTemplateDecl::anchor() {} 1186 1187 FriendTemplateDecl * 1188 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, 1189 SourceLocation L, 1190 MutableArrayRef<TemplateParameterList *> Params, 1191 FriendUnion Friend, SourceLocation FLoc) { 1192 TemplateParameterList **TPL = nullptr; 1193 if (!Params.empty()) { 1194 TPL = new (Context) TemplateParameterList *[Params.size()]; 1195 llvm::copy(Params, TPL); 1196 } 1197 return new (Context, DC) 1198 FriendTemplateDecl(DC, L, TPL, Params.size(), Friend, FLoc); 1199 } 1200 1201 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 1202 GlobalDeclID ID) { 1203 return new (C, ID) FriendTemplateDecl(EmptyShell()); 1204 } 1205 1206 //===----------------------------------------------------------------------===// 1207 // TypeAliasTemplateDecl Implementation 1208 //===----------------------------------------------------------------------===// 1209 1210 TypeAliasTemplateDecl * 1211 TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, 1212 DeclarationName Name, 1213 TemplateParameterList *Params, NamedDecl *Decl) { 1214 bool Invalid = AdoptTemplateParameterList(Params, DC); 1215 auto *TD = new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 1216 if (Invalid) 1217 TD->setInvalidDecl(); 1218 return TD; 1219 } 1220 1221 TypeAliasTemplateDecl * 1222 TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 1223 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 1224 DeclarationName(), nullptr, nullptr); 1225 } 1226 1227 RedeclarableTemplateDecl::CommonBase * 1228 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 1229 auto *CommonPtr = new (C) Common; 1230 C.addDestruction(CommonPtr); 1231 return CommonPtr; 1232 } 1233 1234 //===----------------------------------------------------------------------===// 1235 // VarTemplateDecl Implementation 1236 //===----------------------------------------------------------------------===// 1237 1238 VarTemplateDecl *VarTemplateDecl::getDefinition() { 1239 VarTemplateDecl *CurD = this; 1240 while (CurD) { 1241 if (CurD->isThisDeclarationADefinition()) 1242 return CurD; 1243 CurD = CurD->getPreviousDecl(); 1244 } 1245 return nullptr; 1246 } 1247 1248 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 1249 SourceLocation L, DeclarationName Name, 1250 TemplateParameterList *Params, 1251 VarDecl *Decl) { 1252 bool Invalid = AdoptTemplateParameterList(Params, DC); 1253 auto *TD = new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 1254 if (Invalid) 1255 TD->setInvalidDecl(); 1256 return TD; 1257 } 1258 1259 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 1260 GlobalDeclID ID) { 1261 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 1262 DeclarationName(), nullptr, nullptr); 1263 } 1264 1265 void VarTemplateDecl::LoadLazySpecializations() const { 1266 loadLazySpecializationsImpl(); 1267 } 1268 1269 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 1270 VarTemplateDecl::getSpecializations() const { 1271 LoadLazySpecializations(); 1272 return getCommonPtr()->Specializations; 1273 } 1274 1275 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 1276 VarTemplateDecl::getPartialSpecializations() const { 1277 LoadLazySpecializations(); 1278 return getCommonPtr()->PartialSpecializations; 1279 } 1280 1281 RedeclarableTemplateDecl::CommonBase * 1282 VarTemplateDecl::newCommon(ASTContext &C) const { 1283 auto *CommonPtr = new (C) Common; 1284 C.addDestruction(CommonPtr); 1285 return CommonPtr; 1286 } 1287 1288 VarTemplateSpecializationDecl * 1289 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 1290 void *&InsertPos) { 1291 return findSpecializationImpl(getSpecializations(), InsertPos, Args); 1292 } 1293 1294 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 1295 void *InsertPos) { 1296 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos); 1297 } 1298 1299 VarTemplatePartialSpecializationDecl * 1300 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 1301 TemplateParameterList *TPL, void *&InsertPos) { 1302 return findSpecializationImpl(getPartialSpecializations(), InsertPos, Args, 1303 TPL); 1304 } 1305 1306 void VarTemplatePartialSpecializationDecl::Profile( 1307 llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, 1308 TemplateParameterList *TPL, const ASTContext &Context) { 1309 ID.AddInteger(TemplateArgs.size()); 1310 for (const TemplateArgument &TemplateArg : TemplateArgs) 1311 TemplateArg.Profile(ID, Context); 1312 TPL->Profile(ID, Context); 1313 } 1314 1315 void VarTemplateDecl::AddPartialSpecialization( 1316 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1317 if (InsertPos) 1318 getPartialSpecializations().InsertNode(D, InsertPos); 1319 else { 1320 VarTemplatePartialSpecializationDecl *Existing = 1321 getPartialSpecializations().GetOrInsertNode(D); 1322 (void)Existing; 1323 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1324 } 1325 1326 if (ASTMutationListener *L = getASTMutationListener()) 1327 L->AddedCXXTemplateSpecialization(this, D); 1328 } 1329 1330 void VarTemplateDecl::getPartialSpecializations( 1331 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) const { 1332 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1333 getPartialSpecializations(); 1334 PS.clear(); 1335 PS.reserve(PartialSpecs.size()); 1336 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs) 1337 PS.push_back(P.getMostRecentDecl()); 1338 } 1339 1340 VarTemplatePartialSpecializationDecl * 1341 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1342 VarTemplatePartialSpecializationDecl *D) { 1343 Decl *DCanon = D->getCanonicalDecl(); 1344 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 1345 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1346 return P.getMostRecentDecl(); 1347 } 1348 1349 return nullptr; 1350 } 1351 1352 //===----------------------------------------------------------------------===// 1353 // VarTemplateSpecializationDecl Implementation 1354 //===----------------------------------------------------------------------===// 1355 1356 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1357 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1358 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1359 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) 1360 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 1361 SpecializedTemplate->getIdentifier(), T, TInfo, S), 1362 SpecializedTemplate(SpecializedTemplate), 1363 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 1364 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1365 1366 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 1367 ASTContext &C) 1368 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 1369 QualType(), nullptr, SC_None), 1370 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1371 1372 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1373 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1374 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1375 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) { 1376 return new (Context, DC) VarTemplateSpecializationDecl( 1377 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 1378 SpecializedTemplate, T, TInfo, S, Args); 1379 } 1380 1381 VarTemplateSpecializationDecl * 1382 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 1383 GlobalDeclID ID) { 1384 return new (C, ID) 1385 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 1386 } 1387 1388 void VarTemplateSpecializationDecl::getNameForDiagnostic( 1389 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1390 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1391 1392 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this); 1393 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 1394 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 1395 printTemplateArgumentList( 1396 OS, ArgsAsWritten->arguments(), Policy, 1397 getSpecializedTemplate()->getTemplateParameters()); 1398 } else { 1399 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1400 printTemplateArgumentList( 1401 OS, TemplateArgs.asArray(), Policy, 1402 getSpecializedTemplate()->getTemplateParameters()); 1403 } 1404 } 1405 1406 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1407 if (const auto *PartialSpec = 1408 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1409 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1410 return SpecializedTemplate.get<VarTemplateDecl *>(); 1411 } 1412 1413 SourceRange VarTemplateSpecializationDecl::getSourceRange() const { 1414 switch (getSpecializationKind()) { 1415 case TSK_Undeclared: 1416 case TSK_ImplicitInstantiation: { 1417 llvm::PointerUnion<VarTemplateDecl *, 1418 VarTemplatePartialSpecializationDecl *> 1419 Pattern = getSpecializedTemplateOrPartial(); 1420 assert(!Pattern.isNull() && 1421 "Variable template specialization without pattern?"); 1422 if (const auto *VTPSD = 1423 Pattern.dyn_cast<VarTemplatePartialSpecializationDecl *>()) 1424 return VTPSD->getSourceRange(); 1425 VarTemplateDecl *VTD = Pattern.get<VarTemplateDecl *>(); 1426 if (hasInit()) { 1427 if (VarTemplateDecl *Definition = VTD->getDefinition()) 1428 return Definition->getSourceRange(); 1429 } 1430 return VTD->getCanonicalDecl()->getSourceRange(); 1431 } 1432 case TSK_ExplicitSpecialization: { 1433 SourceRange Range = VarDecl::getSourceRange(); 1434 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten(); 1435 !hasInit() && Args) 1436 Range.setEnd(Args->getRAngleLoc()); 1437 return Range; 1438 } 1439 case TSK_ExplicitInstantiationDeclaration: 1440 case TSK_ExplicitInstantiationDefinition: { 1441 SourceRange Range = VarDecl::getSourceRange(); 1442 if (SourceLocation ExternKW = getExternKeywordLoc(); ExternKW.isValid()) 1443 Range.setBegin(ExternKW); 1444 else if (SourceLocation TemplateKW = getTemplateKeywordLoc(); 1445 TemplateKW.isValid()) 1446 Range.setBegin(TemplateKW); 1447 if (const ASTTemplateArgumentListInfo *Args = getTemplateArgsAsWritten()) 1448 Range.setEnd(Args->getRAngleLoc()); 1449 return Range; 1450 } 1451 } 1452 llvm_unreachable("unhandled template specialization kind"); 1453 } 1454 1455 void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) { 1456 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>(); 1457 if (!Info) { 1458 // Don't allocate if the location is invalid. 1459 if (Loc.isInvalid()) 1460 return; 1461 Info = new (getASTContext()) ExplicitInstantiationInfo; 1462 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); 1463 ExplicitInfo = Info; 1464 } 1465 Info->ExternKeywordLoc = Loc; 1466 } 1467 1468 void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) { 1469 auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>(); 1470 if (!Info) { 1471 // Don't allocate if the location is invalid. 1472 if (Loc.isInvalid()) 1473 return; 1474 Info = new (getASTContext()) ExplicitInstantiationInfo; 1475 Info->TemplateArgsAsWritten = getTemplateArgsAsWritten(); 1476 ExplicitInfo = Info; 1477 } 1478 Info->TemplateKeywordLoc = Loc; 1479 } 1480 1481 //===----------------------------------------------------------------------===// 1482 // VarTemplatePartialSpecializationDecl Implementation 1483 //===----------------------------------------------------------------------===// 1484 1485 void VarTemplatePartialSpecializationDecl::anchor() {} 1486 1487 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1488 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1489 SourceLocation IdLoc, TemplateParameterList *Params, 1490 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1491 StorageClass S, ArrayRef<TemplateArgument> Args) 1492 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 1493 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1494 TInfo, S, Args), 1495 TemplateParams(Params), InstantiatedFromMember(nullptr, false) { 1496 if (AdoptTemplateParameterList(Params, DC)) 1497 setInvalidDecl(); 1498 } 1499 1500 VarTemplatePartialSpecializationDecl * 1501 VarTemplatePartialSpecializationDecl::Create( 1502 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1503 SourceLocation IdLoc, TemplateParameterList *Params, 1504 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1505 StorageClass S, ArrayRef<TemplateArgument> Args) { 1506 auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl( 1507 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S, 1508 Args); 1509 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1510 return Result; 1511 } 1512 1513 VarTemplatePartialSpecializationDecl * 1514 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1515 GlobalDeclID ID) { 1516 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 1517 } 1518 1519 SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const { 1520 if (const VarTemplatePartialSpecializationDecl *MT = 1521 getInstantiatedFromMember(); 1522 MT && !isMemberSpecialization()) 1523 return MT->getSourceRange(); 1524 SourceRange Range = VarTemplateSpecializationDecl::getSourceRange(); 1525 if (const TemplateParameterList *TPL = getTemplateParameters(); 1526 TPL && !getNumTemplateParameterLists()) 1527 Range.setBegin(TPL->getTemplateLoc()); 1528 return Range; 1529 } 1530 1531 static TemplateParameterList * 1532 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { 1533 // typename T 1534 auto *T = TemplateTypeParmDecl::Create( 1535 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0, 1536 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false, 1537 /*HasTypeConstraint=*/false); 1538 T->setImplicit(true); 1539 1540 // T ...Ints 1541 TypeSourceInfo *TI = 1542 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0)); 1543 auto *N = NonTypeTemplateParmDecl::Create( 1544 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1545 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI); 1546 N->setImplicit(true); 1547 1548 // <typename T, T ...Ints> 1549 NamedDecl *P[2] = {T, N}; 1550 auto *TPL = TemplateParameterList::Create( 1551 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr); 1552 1553 // template <typename T, ...Ints> class IntSeq 1554 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create( 1555 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0, 1556 /*ParameterPack=*/false, /*Id=*/nullptr, /*Typename=*/false, TPL); 1557 TemplateTemplateParm->setImplicit(true); 1558 1559 // typename T 1560 auto *TemplateTypeParm = TemplateTypeParmDecl::Create( 1561 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1562 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false, 1563 /*HasTypeConstraint=*/false); 1564 TemplateTypeParm->setImplicit(true); 1565 1566 // T N 1567 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo( 1568 QualType(TemplateTypeParm->getTypeForDecl(), 0)); 1569 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create( 1570 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2, 1571 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1572 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm, 1573 NonTypeTemplateParm}; 1574 1575 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N> 1576 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1577 Params, SourceLocation(), nullptr); 1578 } 1579 1580 static TemplateParameterList * 1581 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) { 1582 // std::size_t Index 1583 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType()); 1584 auto *Index = NonTypeTemplateParmDecl::Create( 1585 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0, 1586 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1587 1588 // typename ...T 1589 auto *Ts = TemplateTypeParmDecl::Create( 1590 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1591 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true, 1592 /*HasTypeConstraint=*/false); 1593 Ts->setImplicit(true); 1594 1595 // template <std::size_t Index, typename ...T> 1596 NamedDecl *Params[] = {Index, Ts}; 1597 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1598 llvm::ArrayRef(Params), SourceLocation(), 1599 nullptr); 1600 } 1601 1602 static TemplateParameterList *createBuiltinTemplateParameterList( 1603 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) { 1604 switch (BTK) { 1605 case BTK__make_integer_seq: 1606 return createMakeIntegerSeqParameterList(C, DC); 1607 case BTK__type_pack_element: 1608 return createTypePackElementParameterList(C, DC); 1609 } 1610 1611 llvm_unreachable("unhandled BuiltinTemplateKind!"); 1612 } 1613 1614 void BuiltinTemplateDecl::anchor() {} 1615 1616 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, 1617 DeclarationName Name, 1618 BuiltinTemplateKind BTK) 1619 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name, 1620 createBuiltinTemplateParameterList(C, DC, BTK)), 1621 BTK(BTK) {} 1622 1623 TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, 1624 QualType T, 1625 const APValue &V) { 1626 DeclContext *DC = C.getTranslationUnitDecl(); 1627 auto *TPOD = new (C, DC) TemplateParamObjectDecl(DC, T, V); 1628 C.addDestruction(&TPOD->Value); 1629 return TPOD; 1630 } 1631 1632 TemplateParamObjectDecl * 1633 TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { 1634 auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); 1635 C.addDestruction(&TPOD->Value); 1636 return TPOD; 1637 } 1638 1639 void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS, 1640 const PrintingPolicy &Policy) const { 1641 OS << "<template param "; 1642 printAsExpr(OS, Policy); 1643 OS << ">"; 1644 } 1645 1646 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS) const { 1647 printAsExpr(OS, getASTContext().getPrintingPolicy()); 1648 } 1649 1650 void TemplateParamObjectDecl::printAsExpr(llvm::raw_ostream &OS, 1651 const PrintingPolicy &Policy) const { 1652 getType().getUnqualifiedType().print(OS, Policy); 1653 printAsInit(OS, Policy); 1654 } 1655 1656 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS) const { 1657 printAsInit(OS, getASTContext().getPrintingPolicy()); 1658 } 1659 1660 void TemplateParamObjectDecl::printAsInit(llvm::raw_ostream &OS, 1661 const PrintingPolicy &Policy) const { 1662 getValue().printPretty(OS, Policy, getType(), &getASTContext()); 1663 } 1664 1665 TemplateParameterList *clang::getReplacedTemplateParameterList(Decl *D) { 1666 switch (D->getKind()) { 1667 case Decl::Kind::CXXRecord: 1668 return cast<CXXRecordDecl>(D) 1669 ->getDescribedTemplate() 1670 ->getTemplateParameters(); 1671 case Decl::Kind::ClassTemplate: 1672 return cast<ClassTemplateDecl>(D)->getTemplateParameters(); 1673 case Decl::Kind::ClassTemplateSpecialization: { 1674 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(D); 1675 auto P = CTSD->getSpecializedTemplateOrPartial(); 1676 if (const auto *CTPSD = 1677 P.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) 1678 return CTPSD->getTemplateParameters(); 1679 return cast<ClassTemplateDecl *>(P)->getTemplateParameters(); 1680 } 1681 case Decl::Kind::ClassTemplatePartialSpecialization: 1682 return cast<ClassTemplatePartialSpecializationDecl>(D) 1683 ->getTemplateParameters(); 1684 case Decl::Kind::TypeAliasTemplate: 1685 return cast<TypeAliasTemplateDecl>(D)->getTemplateParameters(); 1686 case Decl::Kind::BuiltinTemplate: 1687 return cast<BuiltinTemplateDecl>(D)->getTemplateParameters(); 1688 case Decl::Kind::CXXDeductionGuide: 1689 case Decl::Kind::CXXConversion: 1690 case Decl::Kind::CXXConstructor: 1691 case Decl::Kind::CXXDestructor: 1692 case Decl::Kind::CXXMethod: 1693 case Decl::Kind::Function: 1694 return cast<FunctionDecl>(D) 1695 ->getTemplateSpecializationInfo() 1696 ->getTemplate() 1697 ->getTemplateParameters(); 1698 case Decl::Kind::FunctionTemplate: 1699 return cast<FunctionTemplateDecl>(D)->getTemplateParameters(); 1700 case Decl::Kind::VarTemplate: 1701 return cast<VarTemplateDecl>(D)->getTemplateParameters(); 1702 case Decl::Kind::VarTemplateSpecialization: { 1703 const auto *VTSD = cast<VarTemplateSpecializationDecl>(D); 1704 auto P = VTSD->getSpecializedTemplateOrPartial(); 1705 if (const auto *VTPSD = 1706 P.dyn_cast<VarTemplatePartialSpecializationDecl *>()) 1707 return VTPSD->getTemplateParameters(); 1708 return cast<VarTemplateDecl *>(P)->getTemplateParameters(); 1709 } 1710 case Decl::Kind::VarTemplatePartialSpecialization: 1711 return cast<VarTemplatePartialSpecializationDecl>(D) 1712 ->getTemplateParameters(); 1713 case Decl::Kind::TemplateTemplateParm: 1714 return cast<TemplateTemplateParmDecl>(D)->getTemplateParameters(); 1715 case Decl::Kind::Concept: 1716 return cast<ConceptDecl>(D)->getTemplateParameters(); 1717 default: 1718 llvm_unreachable("Unhandled templated declaration kind"); 1719 } 1720 } 1721