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 else 514 return TypeDecl::getSourceRange(); 515 } 516 517 unsigned TemplateTypeParmDecl::getDepth() const { 518 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth(); 519 } 520 521 unsigned TemplateTypeParmDecl::getIndex() const { 522 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex(); 523 } 524 525 bool TemplateTypeParmDecl::isParameterPack() const { 526 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack(); 527 } 528 529 //===----------------------------------------------------------------------===// 530 // NonTypeTemplateParmDecl Method Implementations 531 //===----------------------------------------------------------------------===// 532 533 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( 534 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, 535 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, 536 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) 537 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 538 TemplateParmPosition(D, P), ParameterPack(true), 539 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) { 540 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) { 541 auto TypesAndInfos = 542 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); 543 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 544 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]); 545 TypesAndInfos[I].second = ExpandedTInfos[I]; 546 } 547 } 548 } 549 550 NonTypeTemplateParmDecl * 551 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 552 SourceLocation StartLoc, SourceLocation IdLoc, 553 unsigned D, unsigned P, IdentifierInfo *Id, 554 QualType T, bool ParameterPack, 555 TypeSourceInfo *TInfo) { 556 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 557 T, ParameterPack, TInfo); 558 } 559 560 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( 561 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 562 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, 563 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, 564 ArrayRef<TypeSourceInfo *> ExpandedTInfos) { 565 return new (C, DC, 566 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( 567 ExpandedTypes.size())) 568 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 569 ExpandedTypes, ExpandedTInfos); 570 } 571 572 NonTypeTemplateParmDecl * 573 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 574 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(), 575 SourceLocation(), 0, 0, nullptr, 576 QualType(), false, nullptr); 577 } 578 579 NonTypeTemplateParmDecl * 580 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 581 unsigned NumExpandedTypes) { 582 auto *NTTP = 583 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( 584 NumExpandedTypes)) 585 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 586 0, 0, nullptr, QualType(), nullptr, None, 587 None); 588 NTTP->NumExpandedTypes = NumExpandedTypes; 589 return NTTP; 590 } 591 592 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 593 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 594 return SourceRange(getOuterLocStart(), 595 getDefaultArgument()->getSourceRange().getEnd()); 596 return DeclaratorDecl::getSourceRange(); 597 } 598 599 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 600 return hasDefaultArgument() 601 ? getDefaultArgument()->getSourceRange().getBegin() 602 : SourceLocation(); 603 } 604 605 //===----------------------------------------------------------------------===// 606 // TemplateTemplateParmDecl Method Implementations 607 //===----------------------------------------------------------------------===// 608 609 void TemplateTemplateParmDecl::anchor() {} 610 611 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 612 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 613 IdentifierInfo *Id, TemplateParameterList *Params, 614 ArrayRef<TemplateParameterList *> Expansions) 615 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 616 TemplateParmPosition(D, P), ParameterPack(true), 617 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) { 618 if (!Expansions.empty()) 619 std::uninitialized_copy(Expansions.begin(), Expansions.end(), 620 getTrailingObjects<TemplateParameterList *>()); 621 } 622 623 TemplateTemplateParmDecl * 624 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 625 SourceLocation L, unsigned D, unsigned P, 626 bool ParameterPack, IdentifierInfo *Id, 627 TemplateParameterList *Params) { 628 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 629 Params); 630 } 631 632 TemplateTemplateParmDecl * 633 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 634 SourceLocation L, unsigned D, unsigned P, 635 IdentifierInfo *Id, 636 TemplateParameterList *Params, 637 ArrayRef<TemplateParameterList *> Expansions) { 638 return new (C, DC, 639 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size())) 640 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions); 641 } 642 643 TemplateTemplateParmDecl * 644 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 645 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 646 false, nullptr, nullptr); 647 } 648 649 TemplateTemplateParmDecl * 650 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 651 unsigned NumExpansions) { 652 auto *TTP = 653 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) 654 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 655 nullptr, None); 656 TTP->NumExpandedParams = NumExpansions; 657 return TTP; 658 } 659 660 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 661 return hasDefaultArgument() ? getDefaultArgument().getLocation() 662 : SourceLocation(); 663 } 664 665 void TemplateTemplateParmDecl::setDefaultArgument( 666 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 667 if (DefArg.getArgument().isNull()) 668 DefaultArgument.set(nullptr); 669 else 670 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 671 } 672 673 //===----------------------------------------------------------------------===// 674 // TemplateArgumentList Implementation 675 //===----------------------------------------------------------------------===// 676 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args) 677 : Arguments(getTrailingObjects<TemplateArgument>()), 678 NumArguments(Args.size()) { 679 std::uninitialized_copy(Args.begin(), Args.end(), 680 getTrailingObjects<TemplateArgument>()); 681 } 682 683 TemplateArgumentList * 684 TemplateArgumentList::CreateCopy(ASTContext &Context, 685 ArrayRef<TemplateArgument> Args) { 686 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size())); 687 return new (Mem) TemplateArgumentList(Args); 688 } 689 690 FunctionTemplateSpecializationInfo * 691 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 692 FunctionTemplateDecl *Template, 693 TemplateSpecializationKind TSK, 694 const TemplateArgumentList *TemplateArgs, 695 const TemplateArgumentListInfo *TemplateArgsAsWritten, 696 SourceLocation POI) { 697 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 698 if (TemplateArgsAsWritten) 699 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 700 *TemplateArgsAsWritten); 701 702 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 703 TemplateArgs, 704 ArgsAsWritten, 705 POI); 706 } 707 708 //===----------------------------------------------------------------------===// 709 // TemplateDecl Implementation 710 //===----------------------------------------------------------------------===// 711 712 void TemplateDecl::anchor() {} 713 714 //===----------------------------------------------------------------------===// 715 // ClassTemplateSpecializationDecl Implementation 716 //===----------------------------------------------------------------------===// 717 718 ClassTemplateSpecializationDecl:: 719 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 720 DeclContext *DC, SourceLocation StartLoc, 721 SourceLocation IdLoc, 722 ClassTemplateDecl *SpecializedTemplate, 723 ArrayRef<TemplateArgument> Args, 724 ClassTemplateSpecializationDecl *PrevDecl) 725 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 726 SpecializedTemplate->getIdentifier(), PrevDecl), 727 SpecializedTemplate(SpecializedTemplate), 728 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 729 SpecializationKind(TSK_Undeclared) { 730 } 731 732 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 733 Kind DK) 734 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(), 735 SourceLocation(), nullptr, nullptr), 736 SpecializationKind(TSK_Undeclared) {} 737 738 ClassTemplateSpecializationDecl * 739 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 740 DeclContext *DC, 741 SourceLocation StartLoc, 742 SourceLocation IdLoc, 743 ClassTemplateDecl *SpecializedTemplate, 744 ArrayRef<TemplateArgument> Args, 745 ClassTemplateSpecializationDecl *PrevDecl) { 746 auto *Result = 747 new (Context, DC) ClassTemplateSpecializationDecl( 748 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 749 SpecializedTemplate, Args, PrevDecl); 750 Result->setMayHaveOutOfDateDef(false); 751 752 Context.getTypeDeclType(Result, PrevDecl); 753 return Result; 754 } 755 756 ClassTemplateSpecializationDecl * 757 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 758 unsigned ID) { 759 auto *Result = 760 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 761 Result->setMayHaveOutOfDateDef(false); 762 return Result; 763 } 764 765 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 766 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 767 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 768 769 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this); 770 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 771 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 772 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy); 773 } else { 774 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 775 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy); 776 } 777 } 778 779 ClassTemplateDecl * 780 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 781 if (const auto *PartialSpec = 782 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 783 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 784 return SpecializedTemplate.get<ClassTemplateDecl*>(); 785 } 786 787 SourceRange 788 ClassTemplateSpecializationDecl::getSourceRange() const { 789 if (ExplicitInfo) { 790 SourceLocation Begin = getTemplateKeywordLoc(); 791 if (Begin.isValid()) { 792 // Here we have an explicit (partial) specialization or instantiation. 793 assert(getSpecializationKind() == TSK_ExplicitSpecialization || 794 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 795 getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 796 if (getExternLoc().isValid()) 797 Begin = getExternLoc(); 798 SourceLocation End = getBraceRange().getEnd(); 799 if (End.isInvalid()) 800 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 801 return SourceRange(Begin, End); 802 } 803 // An implicit instantiation of a class template partial specialization 804 // uses ExplicitInfo to record the TypeAsWritten, but the source 805 // locations should be retrieved from the instantiation pattern. 806 using CTPSDecl = ClassTemplatePartialSpecializationDecl; 807 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this)); 808 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 809 assert(inst_from != nullptr); 810 return inst_from->getSourceRange(); 811 } 812 else { 813 // No explicit info available. 814 llvm::PointerUnion<ClassTemplateDecl *, 815 ClassTemplatePartialSpecializationDecl *> 816 inst_from = getInstantiatedFrom(); 817 if (inst_from.isNull()) 818 return getSpecializedTemplate()->getSourceRange(); 819 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>()) 820 return ctd->getSourceRange(); 821 return inst_from.get<ClassTemplatePartialSpecializationDecl *>() 822 ->getSourceRange(); 823 } 824 } 825 826 //===----------------------------------------------------------------------===// 827 // ClassTemplatePartialSpecializationDecl Implementation 828 //===----------------------------------------------------------------------===// 829 void ClassTemplatePartialSpecializationDecl::anchor() {} 830 831 ClassTemplatePartialSpecializationDecl:: 832 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 833 DeclContext *DC, 834 SourceLocation StartLoc, 835 SourceLocation IdLoc, 836 TemplateParameterList *Params, 837 ClassTemplateDecl *SpecializedTemplate, 838 ArrayRef<TemplateArgument> Args, 839 const ASTTemplateArgumentListInfo *ArgInfos, 840 ClassTemplatePartialSpecializationDecl *PrevDecl) 841 : ClassTemplateSpecializationDecl(Context, 842 ClassTemplatePartialSpecialization, 843 TK, DC, StartLoc, IdLoc, 844 SpecializedTemplate, Args, PrevDecl), 845 TemplateParams(Params), ArgsAsWritten(ArgInfos), 846 InstantiatedFromMember(nullptr, false) { 847 AdoptTemplateParameterList(Params, this); 848 } 849 850 ClassTemplatePartialSpecializationDecl * 851 ClassTemplatePartialSpecializationDecl:: 852 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 853 SourceLocation StartLoc, SourceLocation IdLoc, 854 TemplateParameterList *Params, 855 ClassTemplateDecl *SpecializedTemplate, 856 ArrayRef<TemplateArgument> Args, 857 const TemplateArgumentListInfo &ArgInfos, 858 QualType CanonInjectedType, 859 ClassTemplatePartialSpecializationDecl *PrevDecl) { 860 const ASTTemplateArgumentListInfo *ASTArgInfos = 861 ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 862 863 auto *Result = new (Context, DC) 864 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, 865 Params, SpecializedTemplate, Args, 866 ASTArgInfos, PrevDecl); 867 Result->setSpecializationKind(TSK_ExplicitSpecialization); 868 Result->setMayHaveOutOfDateDef(false); 869 870 Context.getInjectedClassNameType(Result, CanonInjectedType); 871 return Result; 872 } 873 874 ClassTemplatePartialSpecializationDecl * 875 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 876 unsigned ID) { 877 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); 878 Result->setMayHaveOutOfDateDef(false); 879 return Result; 880 } 881 882 //===----------------------------------------------------------------------===// 883 // FriendTemplateDecl Implementation 884 //===----------------------------------------------------------------------===// 885 886 void FriendTemplateDecl::anchor() {} 887 888 FriendTemplateDecl * 889 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, 890 SourceLocation L, 891 MutableArrayRef<TemplateParameterList *> Params, 892 FriendUnion Friend, SourceLocation FLoc) { 893 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc); 894 } 895 896 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 897 unsigned ID) { 898 return new (C, ID) FriendTemplateDecl(EmptyShell()); 899 } 900 901 //===----------------------------------------------------------------------===// 902 // TypeAliasTemplateDecl Implementation 903 //===----------------------------------------------------------------------===// 904 905 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 906 DeclContext *DC, 907 SourceLocation L, 908 DeclarationName Name, 909 TemplateParameterList *Params, 910 NamedDecl *Decl) { 911 AdoptTemplateParameterList(Params, DC); 912 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 913 } 914 915 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 916 unsigned ID) { 917 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 918 DeclarationName(), nullptr, nullptr); 919 } 920 921 RedeclarableTemplateDecl::CommonBase * 922 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 923 auto *CommonPtr = new (C) Common; 924 C.addDestruction(CommonPtr); 925 return CommonPtr; 926 } 927 928 //===----------------------------------------------------------------------===// 929 // ClassScopeFunctionSpecializationDecl Implementation 930 //===----------------------------------------------------------------------===// 931 932 void ClassScopeFunctionSpecializationDecl::anchor() {} 933 934 ClassScopeFunctionSpecializationDecl * 935 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 936 unsigned ID) { 937 return new (C, ID) ClassScopeFunctionSpecializationDecl( 938 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo()); 939 } 940 941 //===----------------------------------------------------------------------===// 942 // VarTemplateDecl Implementation 943 //===----------------------------------------------------------------------===// 944 945 VarTemplateDecl *VarTemplateDecl::getDefinition() { 946 VarTemplateDecl *CurD = this; 947 while (CurD) { 948 if (CurD->isThisDeclarationADefinition()) 949 return CurD; 950 CurD = CurD->getPreviousDecl(); 951 } 952 return nullptr; 953 } 954 955 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 956 SourceLocation L, DeclarationName Name, 957 TemplateParameterList *Params, 958 VarDecl *Decl) { 959 AdoptTemplateParameterList(Params, DC); 960 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 961 } 962 963 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 964 unsigned ID) { 965 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 966 DeclarationName(), nullptr, nullptr); 967 } 968 969 void VarTemplateDecl::LoadLazySpecializations() const { 970 loadLazySpecializationsImpl(); 971 } 972 973 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 974 VarTemplateDecl::getSpecializations() const { 975 LoadLazySpecializations(); 976 return getCommonPtr()->Specializations; 977 } 978 979 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 980 VarTemplateDecl::getPartialSpecializations() { 981 LoadLazySpecializations(); 982 return getCommonPtr()->PartialSpecializations; 983 } 984 985 RedeclarableTemplateDecl::CommonBase * 986 VarTemplateDecl::newCommon(ASTContext &C) const { 987 auto *CommonPtr = new (C) Common; 988 C.addDestruction(CommonPtr); 989 return CommonPtr; 990 } 991 992 VarTemplateSpecializationDecl * 993 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 994 void *&InsertPos) { 995 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 996 } 997 998 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 999 void *InsertPos) { 1000 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos); 1001 } 1002 1003 VarTemplatePartialSpecializationDecl * 1004 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 1005 void *&InsertPos) { 1006 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 1007 } 1008 1009 void VarTemplateDecl::AddPartialSpecialization( 1010 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1011 if (InsertPos) 1012 getPartialSpecializations().InsertNode(D, InsertPos); 1013 else { 1014 VarTemplatePartialSpecializationDecl *Existing = 1015 getPartialSpecializations().GetOrInsertNode(D); 1016 (void)Existing; 1017 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1018 } 1019 1020 if (ASTMutationListener *L = getASTMutationListener()) 1021 L->AddedCXXTemplateSpecialization(this, D); 1022 } 1023 1024 void VarTemplateDecl::getPartialSpecializations( 1025 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) { 1026 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1027 getPartialSpecializations(); 1028 PS.clear(); 1029 PS.reserve(PartialSpecs.size()); 1030 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs) 1031 PS.push_back(P.getMostRecentDecl()); 1032 } 1033 1034 VarTemplatePartialSpecializationDecl * 1035 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1036 VarTemplatePartialSpecializationDecl *D) { 1037 Decl *DCanon = D->getCanonicalDecl(); 1038 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 1039 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1040 return P.getMostRecentDecl(); 1041 } 1042 1043 return nullptr; 1044 } 1045 1046 //===----------------------------------------------------------------------===// 1047 // VarTemplateSpecializationDecl Implementation 1048 //===----------------------------------------------------------------------===// 1049 1050 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1051 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1052 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1053 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) 1054 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 1055 SpecializedTemplate->getIdentifier(), T, TInfo, S), 1056 SpecializedTemplate(SpecializedTemplate), 1057 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 1058 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1059 1060 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 1061 ASTContext &C) 1062 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 1063 QualType(), nullptr, SC_None), 1064 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1065 1066 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1067 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1068 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1069 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) { 1070 return new (Context, DC) VarTemplateSpecializationDecl( 1071 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 1072 SpecializedTemplate, T, TInfo, S, Args); 1073 } 1074 1075 VarTemplateSpecializationDecl * 1076 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1077 return new (C, ID) 1078 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 1079 } 1080 1081 void VarTemplateSpecializationDecl::getNameForDiagnostic( 1082 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1083 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1084 1085 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this); 1086 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 1087 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 1088 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy); 1089 } else { 1090 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1091 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy); 1092 } 1093 } 1094 1095 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1096 if (const auto *PartialSpec = 1097 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1098 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1099 return SpecializedTemplate.get<VarTemplateDecl *>(); 1100 } 1101 1102 void VarTemplateSpecializationDecl::setTemplateArgsInfo( 1103 const TemplateArgumentListInfo &ArgsInfo) { 1104 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); 1105 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); 1106 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments()) 1107 TemplateArgsInfo.addArgument(Loc); 1108 } 1109 1110 //===----------------------------------------------------------------------===// 1111 // VarTemplatePartialSpecializationDecl Implementation 1112 //===----------------------------------------------------------------------===// 1113 1114 void VarTemplatePartialSpecializationDecl::anchor() {} 1115 1116 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1117 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1118 SourceLocation IdLoc, TemplateParameterList *Params, 1119 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1120 StorageClass S, ArrayRef<TemplateArgument> Args, 1121 const ASTTemplateArgumentListInfo *ArgInfos) 1122 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 1123 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1124 TInfo, S, Args), 1125 TemplateParams(Params), ArgsAsWritten(ArgInfos), 1126 InstantiatedFromMember(nullptr, false) { 1127 // TODO: The template parameters should be in DC by now. Verify. 1128 // AdoptTemplateParameterList(Params, DC); 1129 } 1130 1131 VarTemplatePartialSpecializationDecl * 1132 VarTemplatePartialSpecializationDecl::Create( 1133 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1134 SourceLocation IdLoc, TemplateParameterList *Params, 1135 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1136 StorageClass S, ArrayRef<TemplateArgument> Args, 1137 const TemplateArgumentListInfo &ArgInfos) { 1138 const ASTTemplateArgumentListInfo *ASTArgInfos 1139 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1140 1141 auto *Result = 1142 new (Context, DC) VarTemplatePartialSpecializationDecl( 1143 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 1144 S, Args, ASTArgInfos); 1145 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1146 return Result; 1147 } 1148 1149 VarTemplatePartialSpecializationDecl * 1150 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1151 unsigned ID) { 1152 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 1153 } 1154 1155 static TemplateParameterList * 1156 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { 1157 // typename T 1158 auto *T = TemplateTypeParmDecl::Create( 1159 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0, 1160 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); 1161 T->setImplicit(true); 1162 1163 // T ...Ints 1164 TypeSourceInfo *TI = 1165 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0)); 1166 auto *N = NonTypeTemplateParmDecl::Create( 1167 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1168 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI); 1169 N->setImplicit(true); 1170 1171 // <typename T, T ...Ints> 1172 NamedDecl *P[2] = {T, N}; 1173 auto *TPL = TemplateParameterList::Create( 1174 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr); 1175 1176 // template <typename T, ...Ints> class IntSeq 1177 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create( 1178 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0, 1179 /*ParameterPack=*/false, /*Id=*/nullptr, TPL); 1180 TemplateTemplateParm->setImplicit(true); 1181 1182 // typename T 1183 auto *TemplateTypeParm = TemplateTypeParmDecl::Create( 1184 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1185 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); 1186 TemplateTypeParm->setImplicit(true); 1187 1188 // T N 1189 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo( 1190 QualType(TemplateTypeParm->getTypeForDecl(), 0)); 1191 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create( 1192 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2, 1193 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1194 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm, 1195 NonTypeTemplateParm}; 1196 1197 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N> 1198 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1199 Params, SourceLocation(), nullptr); 1200 } 1201 1202 static TemplateParameterList * 1203 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) { 1204 // std::size_t Index 1205 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType()); 1206 auto *Index = NonTypeTemplateParmDecl::Create( 1207 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0, 1208 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1209 1210 // typename ...T 1211 auto *Ts = TemplateTypeParmDecl::Create( 1212 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1213 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true); 1214 Ts->setImplicit(true); 1215 1216 // template <std::size_t Index, typename ...T> 1217 NamedDecl *Params[] = {Index, Ts}; 1218 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1219 llvm::makeArrayRef(Params), 1220 SourceLocation(), nullptr); 1221 } 1222 1223 static TemplateParameterList *createBuiltinTemplateParameterList( 1224 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) { 1225 switch (BTK) { 1226 case BTK__make_integer_seq: 1227 return createMakeIntegerSeqParameterList(C, DC); 1228 case BTK__type_pack_element: 1229 return createTypePackElementParameterList(C, DC); 1230 } 1231 1232 llvm_unreachable("unhandled BuiltinTemplateKind!"); 1233 } 1234 1235 void BuiltinTemplateDecl::anchor() {} 1236 1237 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, 1238 DeclarationName Name, 1239 BuiltinTemplateKind BTK) 1240 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name, 1241 createBuiltinTemplateParameterList(C, DC, BTK)), 1242 BTK(BTK) {} 1243