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