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