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