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