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 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 960 } 961 962 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 963 unsigned ID) { 964 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 965 DeclarationName(), nullptr, nullptr); 966 } 967 968 void VarTemplateDecl::LoadLazySpecializations() const { 969 loadLazySpecializationsImpl(); 970 } 971 972 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 973 VarTemplateDecl::getSpecializations() const { 974 LoadLazySpecializations(); 975 return getCommonPtr()->Specializations; 976 } 977 978 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 979 VarTemplateDecl::getPartialSpecializations() { 980 LoadLazySpecializations(); 981 return getCommonPtr()->PartialSpecializations; 982 } 983 984 RedeclarableTemplateDecl::CommonBase * 985 VarTemplateDecl::newCommon(ASTContext &C) const { 986 auto *CommonPtr = new (C) Common; 987 C.addDestruction(CommonPtr); 988 return CommonPtr; 989 } 990 991 VarTemplateSpecializationDecl * 992 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 993 void *&InsertPos) { 994 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 995 } 996 997 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 998 void *InsertPos) { 999 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos); 1000 } 1001 1002 VarTemplatePartialSpecializationDecl * 1003 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 1004 void *&InsertPos) { 1005 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 1006 } 1007 1008 void VarTemplateDecl::AddPartialSpecialization( 1009 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 1010 if (InsertPos) 1011 getPartialSpecializations().InsertNode(D, InsertPos); 1012 else { 1013 VarTemplatePartialSpecializationDecl *Existing = 1014 getPartialSpecializations().GetOrInsertNode(D); 1015 (void)Existing; 1016 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 1017 } 1018 1019 if (ASTMutationListener *L = getASTMutationListener()) 1020 L->AddedCXXTemplateSpecialization(this, D); 1021 } 1022 1023 void VarTemplateDecl::getPartialSpecializations( 1024 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) { 1025 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 1026 getPartialSpecializations(); 1027 PS.clear(); 1028 PS.reserve(PartialSpecs.size()); 1029 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs) 1030 PS.push_back(P.getMostRecentDecl()); 1031 } 1032 1033 VarTemplatePartialSpecializationDecl * 1034 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1035 VarTemplatePartialSpecializationDecl *D) { 1036 Decl *DCanon = D->getCanonicalDecl(); 1037 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 1038 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1039 return P.getMostRecentDecl(); 1040 } 1041 1042 return nullptr; 1043 } 1044 1045 //===----------------------------------------------------------------------===// 1046 // VarTemplateSpecializationDecl Implementation 1047 //===----------------------------------------------------------------------===// 1048 1049 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1050 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1051 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1052 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) 1053 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 1054 SpecializedTemplate->getIdentifier(), T, TInfo, S), 1055 SpecializedTemplate(SpecializedTemplate), 1056 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 1057 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1058 1059 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 1060 ASTContext &C) 1061 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 1062 QualType(), nullptr, SC_None), 1063 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1064 1065 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1066 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1067 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1068 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) { 1069 return new (Context, DC) VarTemplateSpecializationDecl( 1070 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 1071 SpecializedTemplate, T, TInfo, S, Args); 1072 } 1073 1074 VarTemplateSpecializationDecl * 1075 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1076 return new (C, ID) 1077 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 1078 } 1079 1080 void VarTemplateSpecializationDecl::getNameForDiagnostic( 1081 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1082 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1083 1084 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this); 1085 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 1086 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 1087 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy); 1088 } else { 1089 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1090 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy); 1091 } 1092 } 1093 1094 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1095 if (const auto *PartialSpec = 1096 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1097 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1098 return SpecializedTemplate.get<VarTemplateDecl *>(); 1099 } 1100 1101 void VarTemplateSpecializationDecl::setTemplateArgsInfo( 1102 const TemplateArgumentListInfo &ArgsInfo) { 1103 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); 1104 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); 1105 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments()) 1106 TemplateArgsInfo.addArgument(Loc); 1107 } 1108 1109 //===----------------------------------------------------------------------===// 1110 // VarTemplatePartialSpecializationDecl Implementation 1111 //===----------------------------------------------------------------------===// 1112 1113 void VarTemplatePartialSpecializationDecl::anchor() {} 1114 1115 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1116 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1117 SourceLocation IdLoc, TemplateParameterList *Params, 1118 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1119 StorageClass S, ArrayRef<TemplateArgument> Args, 1120 const ASTTemplateArgumentListInfo *ArgInfos) 1121 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 1122 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1123 TInfo, S, Args), 1124 TemplateParams(Params), ArgsAsWritten(ArgInfos), 1125 InstantiatedFromMember(nullptr, false) { 1126 // TODO: The template parameters should be in DC by now. Verify. 1127 // AdoptTemplateParameterList(Params, DC); 1128 } 1129 1130 VarTemplatePartialSpecializationDecl * 1131 VarTemplatePartialSpecializationDecl::Create( 1132 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1133 SourceLocation IdLoc, TemplateParameterList *Params, 1134 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1135 StorageClass S, ArrayRef<TemplateArgument> Args, 1136 const TemplateArgumentListInfo &ArgInfos) { 1137 const ASTTemplateArgumentListInfo *ASTArgInfos 1138 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1139 1140 auto *Result = 1141 new (Context, DC) VarTemplatePartialSpecializationDecl( 1142 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 1143 S, Args, ASTArgInfos); 1144 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1145 return Result; 1146 } 1147 1148 VarTemplatePartialSpecializationDecl * 1149 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1150 unsigned ID) { 1151 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 1152 } 1153 1154 static TemplateParameterList * 1155 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { 1156 // typename T 1157 auto *T = TemplateTypeParmDecl::Create( 1158 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0, 1159 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); 1160 T->setImplicit(true); 1161 1162 // T ...Ints 1163 TypeSourceInfo *TI = 1164 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0)); 1165 auto *N = NonTypeTemplateParmDecl::Create( 1166 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1167 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI); 1168 N->setImplicit(true); 1169 1170 // <typename T, T ...Ints> 1171 NamedDecl *P[2] = {T, N}; 1172 auto *TPL = TemplateParameterList::Create( 1173 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr); 1174 1175 // template <typename T, ...Ints> class IntSeq 1176 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create( 1177 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0, 1178 /*ParameterPack=*/false, /*Id=*/nullptr, TPL); 1179 TemplateTemplateParm->setImplicit(true); 1180 1181 // typename T 1182 auto *TemplateTypeParm = TemplateTypeParmDecl::Create( 1183 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1184 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); 1185 TemplateTypeParm->setImplicit(true); 1186 1187 // T N 1188 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo( 1189 QualType(TemplateTypeParm->getTypeForDecl(), 0)); 1190 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create( 1191 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2, 1192 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1193 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm, 1194 NonTypeTemplateParm}; 1195 1196 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N> 1197 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1198 Params, SourceLocation(), nullptr); 1199 } 1200 1201 static TemplateParameterList * 1202 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) { 1203 // std::size_t Index 1204 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType()); 1205 auto *Index = NonTypeTemplateParmDecl::Create( 1206 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0, 1207 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1208 1209 // typename ...T 1210 auto *Ts = TemplateTypeParmDecl::Create( 1211 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1212 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true); 1213 Ts->setImplicit(true); 1214 1215 // template <std::size_t Index, typename ...T> 1216 NamedDecl *Params[] = {Index, Ts}; 1217 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1218 llvm::makeArrayRef(Params), 1219 SourceLocation(), nullptr); 1220 } 1221 1222 static TemplateParameterList *createBuiltinTemplateParameterList( 1223 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) { 1224 switch (BTK) { 1225 case BTK__make_integer_seq: 1226 return createMakeIntegerSeqParameterList(C, DC); 1227 case BTK__type_pack_element: 1228 return createTypePackElementParameterList(C, DC); 1229 } 1230 1231 llvm_unreachable("unhandled BuiltinTemplateKind!"); 1232 } 1233 1234 void BuiltinTemplateDecl::anchor() {} 1235 1236 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, 1237 DeclarationName Name, 1238 BuiltinTemplateKind BTK) 1239 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name, 1240 createBuiltinTemplateParameterList(C, DC, BTK)), 1241 BTK(BTK) {} 1242