1 //===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the C++ related Decl classes for templates. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/DeclTemplate.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/DeclCXX.h" 18 #include "clang/AST/DeclarationName.h" 19 #include "clang/AST/Expr.h" 20 #include "clang/AST/ExternalASTSource.h" 21 #include "clang/AST/TemplateBase.h" 22 #include "clang/AST/TemplateName.h" 23 #include "clang/AST/Type.h" 24 #include "clang/AST/TypeLoc.h" 25 #include "clang/Basic/Builtins.h" 26 #include "clang/Basic/LLVM.h" 27 #include "clang/Basic/SourceLocation.h" 28 #include "llvm/ADT/ArrayRef.h" 29 #include "llvm/ADT/FoldingSet.h" 30 #include "llvm/ADT/None.h" 31 #include "llvm/ADT/PointerUnion.h" 32 #include "llvm/ADT/SmallVector.h" 33 #include "llvm/Support/Casting.h" 34 #include "llvm/Support/ErrorHandling.h" 35 #include <algorithm> 36 #include <cassert> 37 #include <cstdint> 38 #include <memory> 39 #include <utility> 40 41 using namespace clang; 42 43 //===----------------------------------------------------------------------===// 44 // TemplateParameterList Implementation 45 //===----------------------------------------------------------------------===// 46 47 TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc, 48 SourceLocation LAngleLoc, 49 ArrayRef<NamedDecl *> Params, 50 SourceLocation RAngleLoc, 51 Expr *RequiresClause) 52 : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), 53 NumParams(Params.size()), ContainsUnexpandedParameterPack(false), 54 HasRequiresClause(static_cast<bool>(RequiresClause)) { 55 for (unsigned Idx = 0; Idx < NumParams; ++Idx) { 56 NamedDecl *P = Params[Idx]; 57 begin()[Idx] = P; 58 59 if (!P->isTemplateParameterPack()) { 60 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) 61 if (NTTP->getType()->containsUnexpandedParameterPack()) 62 ContainsUnexpandedParameterPack = true; 63 64 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) 65 if (TTP->getTemplateParameters()->containsUnexpandedParameterPack()) 66 ContainsUnexpandedParameterPack = true; 67 68 // FIXME: If a default argument contains an unexpanded parameter pack, the 69 // template parameter list does too. 70 } 71 } 72 if (RequiresClause) { 73 *getTrailingObjects<Expr *>() = RequiresClause; 74 } 75 } 76 77 TemplateParameterList * 78 TemplateParameterList::Create(const ASTContext &C, SourceLocation TemplateLoc, 79 SourceLocation LAngleLoc, 80 ArrayRef<NamedDecl *> Params, 81 SourceLocation RAngleLoc, Expr *RequiresClause) { 82 void *Mem = C.Allocate(totalSizeToAlloc<NamedDecl *, Expr *>( 83 Params.size(), RequiresClause ? 1u : 0u), 84 alignof(TemplateParameterList)); 85 return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params, 86 RAngleLoc, RequiresClause); 87 } 88 89 unsigned TemplateParameterList::getMinRequiredArguments() const { 90 unsigned NumRequiredArgs = 0; 91 for (const NamedDecl *P : asArray()) { 92 if (P->isTemplateParameterPack()) { 93 if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) 94 if (NTTP->isExpandedParameterPack()) { 95 NumRequiredArgs += NTTP->getNumExpansionTypes(); 96 continue; 97 } 98 99 break; 100 } 101 102 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(P)) { 103 if (TTP->hasDefaultArgument()) 104 break; 105 } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) { 106 if (NTTP->hasDefaultArgument()) 107 break; 108 } else if (cast<TemplateTemplateParmDecl>(P)->hasDefaultArgument()) 109 break; 110 111 ++NumRequiredArgs; 112 } 113 114 return NumRequiredArgs; 115 } 116 117 unsigned TemplateParameterList::getDepth() const { 118 if (size() == 0) 119 return 0; 120 121 const NamedDecl *FirstParm = getParam(0); 122 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(FirstParm)) 123 return TTP->getDepth(); 124 else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(FirstParm)) 125 return NTTP->getDepth(); 126 else 127 return cast<TemplateTemplateParmDecl>(FirstParm)->getDepth(); 128 } 129 130 static void AdoptTemplateParameterList(TemplateParameterList *Params, 131 DeclContext *Owner) { 132 for (NamedDecl *P : *Params) { 133 P->setDeclContext(Owner); 134 135 if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(P)) 136 AdoptTemplateParameterList(TTP->getTemplateParameters(), Owner); 137 } 138 } 139 140 namespace clang { 141 142 void *allocateDefaultArgStorageChain(const ASTContext &C) { 143 return new (C) char[sizeof(void*) * 2]; 144 } 145 146 } // namespace clang 147 148 //===----------------------------------------------------------------------===// 149 // RedeclarableTemplateDecl Implementation 150 //===----------------------------------------------------------------------===// 151 152 RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const { 153 if (Common) 154 return Common; 155 156 // Walk the previous-declaration chain until we either find a declaration 157 // with a common pointer or we run out of previous declarations. 158 SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls; 159 for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; 160 Prev = Prev->getPreviousDecl()) { 161 if (Prev->Common) { 162 Common = Prev->Common; 163 break; 164 } 165 166 PrevDecls.push_back(Prev); 167 } 168 169 // If we never found a common pointer, allocate one now. 170 if (!Common) { 171 // FIXME: If any of the declarations is from an AST file, we probably 172 // need an update record to add the common data. 173 174 Common = newCommon(getASTContext()); 175 } 176 177 // Update any previous declarations we saw with the common pointer. 178 for (const RedeclarableTemplateDecl *Prev : PrevDecls) 179 Prev->Common = Common; 180 181 return Common; 182 } 183 184 void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { 185 // Grab the most recent declaration to ensure we've loaded any lazy 186 // redeclarations of this template. 187 CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); 188 if (CommonBasePtr->LazySpecializations) { 189 ASTContext &Context = getASTContext(); 190 uint32_t *Specs = CommonBasePtr->LazySpecializations; 191 CommonBasePtr->LazySpecializations = nullptr; 192 for (uint32_t I = 0, N = *Specs++; I != N; ++I) 193 (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); 194 } 195 } 196 197 template<class EntryType> 198 typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType * 199 RedeclarableTemplateDecl::findSpecializationImpl( 200 llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args, 201 void *&InsertPos) { 202 using SETraits = SpecEntryTraits<EntryType>; 203 204 llvm::FoldingSetNodeID ID; 205 EntryType::Profile(ID, Args, getASTContext()); 206 EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); 207 return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr; 208 } 209 210 template<class Derived, class EntryType> 211 void RedeclarableTemplateDecl::addSpecializationImpl( 212 llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry, 213 void *InsertPos) { 214 using SETraits = SpecEntryTraits<EntryType>; 215 216 if (InsertPos) { 217 #ifndef NDEBUG 218 void *CorrectInsertPos; 219 assert(!findSpecializationImpl(Specializations, 220 SETraits::getTemplateArgs(Entry), 221 CorrectInsertPos) && 222 InsertPos == CorrectInsertPos && 223 "given incorrect InsertPos for specialization"); 224 #endif 225 Specializations.InsertNode(Entry, InsertPos); 226 } else { 227 EntryType *Existing = Specializations.GetOrInsertNode(Entry); 228 (void)Existing; 229 assert(SETraits::getDecl(Existing)->isCanonicalDecl() && 230 "non-canonical specialization?"); 231 } 232 233 if (ASTMutationListener *L = getASTMutationListener()) 234 L->AddedCXXTemplateSpecialization(cast<Derived>(this), 235 SETraits::getDecl(Entry)); 236 } 237 238 //===----------------------------------------------------------------------===// 239 // FunctionTemplateDecl Implementation 240 //===----------------------------------------------------------------------===// 241 242 FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C, 243 DeclContext *DC, 244 SourceLocation L, 245 DeclarationName Name, 246 TemplateParameterList *Params, 247 NamedDecl *Decl) { 248 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 249 return new (C, DC) FunctionTemplateDecl(C, DC, L, Name, Params, Decl); 250 } 251 252 FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, 253 unsigned ID) { 254 return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), 255 DeclarationName(), nullptr, nullptr); 256 } 257 258 RedeclarableTemplateDecl::CommonBase * 259 FunctionTemplateDecl::newCommon(ASTContext &C) const { 260 auto *CommonPtr = new (C) Common; 261 C.addDestruction(CommonPtr); 262 return CommonPtr; 263 } 264 265 void FunctionTemplateDecl::LoadLazySpecializations() const { 266 loadLazySpecializationsImpl(); 267 } 268 269 llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & 270 FunctionTemplateDecl::getSpecializations() const { 271 LoadLazySpecializations(); 272 return getCommonPtr()->Specializations; 273 } 274 275 FunctionDecl * 276 FunctionTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 277 void *&InsertPos) { 278 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 279 } 280 281 void FunctionTemplateDecl::addSpecialization( 282 FunctionTemplateSpecializationInfo *Info, void *InsertPos) { 283 addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info, 284 InsertPos); 285 } 286 287 ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() { 288 TemplateParameterList *Params = getTemplateParameters(); 289 Common *CommonPtr = getCommonPtr(); 290 if (!CommonPtr->InjectedArgs) { 291 auto &Context = getASTContext(); 292 SmallVector<TemplateArgument, 16> TemplateArgs; 293 Context.getInjectedTemplateArgs(Params, TemplateArgs); 294 CommonPtr->InjectedArgs = 295 new (Context) TemplateArgument[TemplateArgs.size()]; 296 std::copy(TemplateArgs.begin(), TemplateArgs.end(), 297 CommonPtr->InjectedArgs); 298 } 299 300 return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size()); 301 } 302 303 void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) { 304 using Base = RedeclarableTemplateDecl; 305 306 // If we haven't created a common pointer yet, then it can just be created 307 // with the usual method. 308 if (!Base::Common) 309 return; 310 311 Common *ThisCommon = static_cast<Common *>(Base::Common); 312 Common *PrevCommon = nullptr; 313 SmallVector<FunctionTemplateDecl *, 8> PreviousDecls; 314 for (; Prev; Prev = Prev->getPreviousDecl()) { 315 if (Prev->Base::Common) { 316 PrevCommon = static_cast<Common *>(Prev->Base::Common); 317 break; 318 } 319 PreviousDecls.push_back(Prev); 320 } 321 322 // If the previous redecl chain hasn't created a common pointer yet, then just 323 // use this common pointer. 324 if (!PrevCommon) { 325 for (auto *D : PreviousDecls) 326 D->Base::Common = ThisCommon; 327 return; 328 } 329 330 // Ensure we don't leak any important state. 331 assert(ThisCommon->Specializations.size() == 0 && 332 !ThisCommon->InstantiatedFromMember.getPointer() && 333 !ThisCommon->InstantiatedFromMember.getInt() && 334 "Can't merge incompatible declarations!"); 335 336 Base::Common = PrevCommon; 337 } 338 339 //===----------------------------------------------------------------------===// 340 // ClassTemplateDecl Implementation 341 //===----------------------------------------------------------------------===// 342 343 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 344 DeclContext *DC, 345 SourceLocation L, 346 DeclarationName Name, 347 TemplateParameterList *Params, 348 NamedDecl *Decl, 349 Expr *AssociatedConstraints) { 350 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 351 352 if (!AssociatedConstraints) { 353 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl); 354 } 355 356 auto *const CTDI = new (C) ConstrainedTemplateDeclInfo; 357 auto *const New = 358 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl); 359 New->setAssociatedConstraints(AssociatedConstraints); 360 return New; 361 } 362 363 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 364 unsigned ID) { 365 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), 366 DeclarationName(), nullptr, nullptr); 367 } 368 369 void ClassTemplateDecl::LoadLazySpecializations() const { 370 loadLazySpecializationsImpl(); 371 } 372 373 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 374 ClassTemplateDecl::getSpecializations() const { 375 LoadLazySpecializations(); 376 return getCommonPtr()->Specializations; 377 } 378 379 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 380 ClassTemplateDecl::getPartialSpecializations() { 381 LoadLazySpecializations(); 382 return getCommonPtr()->PartialSpecializations; 383 } 384 385 RedeclarableTemplateDecl::CommonBase * 386 ClassTemplateDecl::newCommon(ASTContext &C) const { 387 auto *CommonPtr = new (C) Common; 388 C.addDestruction(CommonPtr); 389 return CommonPtr; 390 } 391 392 ClassTemplateSpecializationDecl * 393 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 394 void *&InsertPos) { 395 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 396 } 397 398 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 399 void *InsertPos) { 400 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos); 401 } 402 403 ClassTemplatePartialSpecializationDecl * 404 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 405 void *&InsertPos) { 406 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 407 } 408 409 void ClassTemplateDecl::AddPartialSpecialization( 410 ClassTemplatePartialSpecializationDecl *D, 411 void *InsertPos) { 412 if (InsertPos) 413 getPartialSpecializations().InsertNode(D, InsertPos); 414 else { 415 ClassTemplatePartialSpecializationDecl *Existing 416 = getPartialSpecializations().GetOrInsertNode(D); 417 (void)Existing; 418 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 419 } 420 421 if (ASTMutationListener *L = getASTMutationListener()) 422 L->AddedCXXTemplateSpecialization(this, D); 423 } 424 425 void ClassTemplateDecl::getPartialSpecializations( 426 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 427 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs 428 = getPartialSpecializations(); 429 PS.clear(); 430 PS.reserve(PartialSpecs.size()); 431 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs) 432 PS.push_back(P.getMostRecentDecl()); 433 } 434 435 ClassTemplatePartialSpecializationDecl * 436 ClassTemplateDecl::findPartialSpecialization(QualType T) { 437 ASTContext &Context = getASTContext(); 438 for (ClassTemplatePartialSpecializationDecl &P : 439 getPartialSpecializations()) { 440 if (Context.hasSameType(P.getInjectedSpecializationType(), T)) 441 return P.getMostRecentDecl(); 442 } 443 444 return nullptr; 445 } 446 447 ClassTemplatePartialSpecializationDecl * 448 ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 449 ClassTemplatePartialSpecializationDecl *D) { 450 Decl *DCanon = D->getCanonicalDecl(); 451 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 452 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 453 return P.getMostRecentDecl(); 454 } 455 456 return nullptr; 457 } 458 459 QualType 460 ClassTemplateDecl::getInjectedClassNameSpecialization() { 461 Common *CommonPtr = getCommonPtr(); 462 if (!CommonPtr->InjectedClassNameType.isNull()) 463 return CommonPtr->InjectedClassNameType; 464 465 // C++0x [temp.dep.type]p2: 466 // The template argument list of a primary template is a template argument 467 // list in which the nth template argument has the value of the nth template 468 // parameter of the class template. If the nth template parameter is a 469 // template parameter pack (14.5.3), the nth template argument is a pack 470 // expansion (14.5.3) whose pattern is the name of the template parameter 471 // pack. 472 ASTContext &Context = getASTContext(); 473 TemplateParameterList *Params = getTemplateParameters(); 474 SmallVector<TemplateArgument, 16> TemplateArgs; 475 Context.getInjectedTemplateArgs(Params, TemplateArgs); 476 CommonPtr->InjectedClassNameType 477 = Context.getTemplateSpecializationType(TemplateName(this), 478 TemplateArgs); 479 return CommonPtr->InjectedClassNameType; 480 } 481 482 //===----------------------------------------------------------------------===// 483 // TemplateTypeParm Allocation/Deallocation Method Implementations 484 //===----------------------------------------------------------------------===// 485 486 TemplateTypeParmDecl * 487 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 488 SourceLocation KeyLoc, SourceLocation NameLoc, 489 unsigned D, unsigned P, IdentifierInfo *Id, 490 bool Typename, bool ParameterPack) { 491 auto *TTPDecl = 492 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename); 493 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 494 TTPDecl->setTypeForDecl(TTPType.getTypePtr()); 495 return TTPDecl; 496 } 497 498 TemplateTypeParmDecl * 499 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 500 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), 501 SourceLocation(), nullptr, false); 502 } 503 504 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 505 return hasDefaultArgument() 506 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc() 507 : SourceLocation(); 508 } 509 510 SourceRange TemplateTypeParmDecl::getSourceRange() const { 511 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 512 return SourceRange(getBeginLoc(), 513 getDefaultArgumentInfo()->getTypeLoc().getEndLoc()); 514 else 515 return TypeDecl::getSourceRange(); 516 } 517 518 unsigned TemplateTypeParmDecl::getDepth() const { 519 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth(); 520 } 521 522 unsigned TemplateTypeParmDecl::getIndex() const { 523 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex(); 524 } 525 526 bool TemplateTypeParmDecl::isParameterPack() const { 527 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack(); 528 } 529 530 //===----------------------------------------------------------------------===// 531 // NonTypeTemplateParmDecl Method Implementations 532 //===----------------------------------------------------------------------===// 533 534 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( 535 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, 536 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, 537 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) 538 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 539 TemplateParmPosition(D, P), ParameterPack(true), 540 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) { 541 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) { 542 auto TypesAndInfos = 543 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); 544 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 545 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]); 546 TypesAndInfos[I].second = ExpandedTInfos[I]; 547 } 548 } 549 } 550 551 NonTypeTemplateParmDecl * 552 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 553 SourceLocation StartLoc, SourceLocation IdLoc, 554 unsigned D, unsigned P, IdentifierInfo *Id, 555 QualType T, bool ParameterPack, 556 TypeSourceInfo *TInfo) { 557 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 558 T, ParameterPack, TInfo); 559 } 560 561 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( 562 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 563 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, 564 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, 565 ArrayRef<TypeSourceInfo *> ExpandedTInfos) { 566 return new (C, DC, 567 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( 568 ExpandedTypes.size())) 569 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 570 ExpandedTypes, ExpandedTInfos); 571 } 572 573 NonTypeTemplateParmDecl * 574 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 575 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(), 576 SourceLocation(), 0, 0, nullptr, 577 QualType(), false, nullptr); 578 } 579 580 NonTypeTemplateParmDecl * 581 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 582 unsigned NumExpandedTypes) { 583 auto *NTTP = 584 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( 585 NumExpandedTypes)) 586 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 587 0, 0, nullptr, QualType(), nullptr, None, 588 None); 589 NTTP->NumExpandedTypes = NumExpandedTypes; 590 return NTTP; 591 } 592 593 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 594 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 595 return SourceRange(getOuterLocStart(), 596 getDefaultArgument()->getSourceRange().getEnd()); 597 return DeclaratorDecl::getSourceRange(); 598 } 599 600 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 601 return hasDefaultArgument() 602 ? getDefaultArgument()->getSourceRange().getBegin() 603 : SourceLocation(); 604 } 605 606 //===----------------------------------------------------------------------===// 607 // TemplateTemplateParmDecl Method Implementations 608 //===----------------------------------------------------------------------===// 609 610 void TemplateTemplateParmDecl::anchor() {} 611 612 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 613 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 614 IdentifierInfo *Id, TemplateParameterList *Params, 615 ArrayRef<TemplateParameterList *> Expansions) 616 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 617 TemplateParmPosition(D, P), ParameterPack(true), 618 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) { 619 if (!Expansions.empty()) 620 std::uninitialized_copy(Expansions.begin(), Expansions.end(), 621 getTrailingObjects<TemplateParameterList *>()); 622 } 623 624 TemplateTemplateParmDecl * 625 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 626 SourceLocation L, unsigned D, unsigned P, 627 bool ParameterPack, IdentifierInfo *Id, 628 TemplateParameterList *Params) { 629 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 630 Params); 631 } 632 633 TemplateTemplateParmDecl * 634 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 635 SourceLocation L, unsigned D, unsigned P, 636 IdentifierInfo *Id, 637 TemplateParameterList *Params, 638 ArrayRef<TemplateParameterList *> Expansions) { 639 return new (C, DC, 640 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size())) 641 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions); 642 } 643 644 TemplateTemplateParmDecl * 645 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 646 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 647 false, nullptr, nullptr); 648 } 649 650 TemplateTemplateParmDecl * 651 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 652 unsigned NumExpansions) { 653 auto *TTP = 654 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) 655 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 656 nullptr, None); 657 TTP->NumExpandedParams = NumExpansions; 658 return TTP; 659 } 660 661 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 662 return hasDefaultArgument() ? getDefaultArgument().getLocation() 663 : SourceLocation(); 664 } 665 666 void TemplateTemplateParmDecl::setDefaultArgument( 667 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 668 if (DefArg.getArgument().isNull()) 669 DefaultArgument.set(nullptr); 670 else 671 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 672 } 673 674 //===----------------------------------------------------------------------===// 675 // TemplateArgumentList Implementation 676 //===----------------------------------------------------------------------===// 677 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args) 678 : Arguments(getTrailingObjects<TemplateArgument>()), 679 NumArguments(Args.size()) { 680 std::uninitialized_copy(Args.begin(), Args.end(), 681 getTrailingObjects<TemplateArgument>()); 682 } 683 684 TemplateArgumentList * 685 TemplateArgumentList::CreateCopy(ASTContext &Context, 686 ArrayRef<TemplateArgument> Args) { 687 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size())); 688 return new (Mem) TemplateArgumentList(Args); 689 } 690 691 FunctionTemplateSpecializationInfo * 692 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 693 FunctionTemplateDecl *Template, 694 TemplateSpecializationKind TSK, 695 const TemplateArgumentList *TemplateArgs, 696 const TemplateArgumentListInfo *TemplateArgsAsWritten, 697 SourceLocation POI) { 698 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 699 if (TemplateArgsAsWritten) 700 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 701 *TemplateArgsAsWritten); 702 703 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 704 TemplateArgs, 705 ArgsAsWritten, 706 POI); 707 } 708 709 //===----------------------------------------------------------------------===// 710 // TemplateDecl Implementation 711 //===----------------------------------------------------------------------===// 712 713 void TemplateDecl::anchor() {} 714 715 //===----------------------------------------------------------------------===// 716 // ClassTemplateSpecializationDecl Implementation 717 //===----------------------------------------------------------------------===// 718 719 ClassTemplateSpecializationDecl:: 720 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 721 DeclContext *DC, SourceLocation StartLoc, 722 SourceLocation IdLoc, 723 ClassTemplateDecl *SpecializedTemplate, 724 ArrayRef<TemplateArgument> Args, 725 ClassTemplateSpecializationDecl *PrevDecl) 726 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 727 SpecializedTemplate->getIdentifier(), PrevDecl), 728 SpecializedTemplate(SpecializedTemplate), 729 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 730 SpecializationKind(TSK_Undeclared) { 731 } 732 733 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 734 Kind DK) 735 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(), 736 SourceLocation(), nullptr, nullptr), 737 SpecializationKind(TSK_Undeclared) {} 738 739 ClassTemplateSpecializationDecl * 740 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 741 DeclContext *DC, 742 SourceLocation StartLoc, 743 SourceLocation IdLoc, 744 ClassTemplateDecl *SpecializedTemplate, 745 ArrayRef<TemplateArgument> Args, 746 ClassTemplateSpecializationDecl *PrevDecl) { 747 auto *Result = 748 new (Context, DC) ClassTemplateSpecializationDecl( 749 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 750 SpecializedTemplate, Args, PrevDecl); 751 Result->setMayHaveOutOfDateDef(false); 752 753 Context.getTypeDeclType(Result, PrevDecl); 754 return Result; 755 } 756 757 ClassTemplateSpecializationDecl * 758 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 759 unsigned ID) { 760 auto *Result = 761 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 762 Result->setMayHaveOutOfDateDef(false); 763 return Result; 764 } 765 766 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 767 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 768 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 769 770 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this); 771 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 772 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 773 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy); 774 } else { 775 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 776 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy); 777 } 778 } 779 780 ClassTemplateDecl * 781 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 782 if (const auto *PartialSpec = 783 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 784 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 785 return SpecializedTemplate.get<ClassTemplateDecl*>(); 786 } 787 788 SourceRange 789 ClassTemplateSpecializationDecl::getSourceRange() const { 790 if (ExplicitInfo) { 791 SourceLocation Begin = getTemplateKeywordLoc(); 792 if (Begin.isValid()) { 793 // Here we have an explicit (partial) specialization or instantiation. 794 assert(getSpecializationKind() == TSK_ExplicitSpecialization || 795 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 796 getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 797 if (getExternLoc().isValid()) 798 Begin = getExternLoc(); 799 SourceLocation End = getBraceRange().getEnd(); 800 if (End.isInvalid()) 801 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 802 return SourceRange(Begin, End); 803 } 804 // An implicit instantiation of a class template partial specialization 805 // uses ExplicitInfo to record the TypeAsWritten, but the source 806 // locations should be retrieved from the instantiation pattern. 807 using CTPSDecl = ClassTemplatePartialSpecializationDecl; 808 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this)); 809 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 810 assert(inst_from != nullptr); 811 return inst_from->getSourceRange(); 812 } 813 else { 814 // No explicit info available. 815 llvm::PointerUnion<ClassTemplateDecl *, 816 ClassTemplatePartialSpecializationDecl *> 817 inst_from = getInstantiatedFrom(); 818 if (inst_from.isNull()) 819 return getSpecializedTemplate()->getSourceRange(); 820 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>()) 821 return ctd->getSourceRange(); 822 return inst_from.get<ClassTemplatePartialSpecializationDecl *>() 823 ->getSourceRange(); 824 } 825 } 826 827 //===----------------------------------------------------------------------===// 828 // ClassTemplatePartialSpecializationDecl Implementation 829 //===----------------------------------------------------------------------===// 830 void ClassTemplatePartialSpecializationDecl::anchor() {} 831 832 ClassTemplatePartialSpecializationDecl:: 833 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 834 DeclContext *DC, 835 SourceLocation StartLoc, 836 SourceLocation IdLoc, 837 TemplateParameterList *Params, 838 ClassTemplateDecl *SpecializedTemplate, 839 ArrayRef<TemplateArgument> Args, 840 const ASTTemplateArgumentListInfo *ArgInfos, 841 ClassTemplatePartialSpecializationDecl *PrevDecl) 842 : ClassTemplateSpecializationDecl(Context, 843 ClassTemplatePartialSpecialization, 844 TK, DC, StartLoc, IdLoc, 845 SpecializedTemplate, Args, PrevDecl), 846 TemplateParams(Params), ArgsAsWritten(ArgInfos), 847 InstantiatedFromMember(nullptr, false) { 848 AdoptTemplateParameterList(Params, this); 849 } 850 851 ClassTemplatePartialSpecializationDecl * 852 ClassTemplatePartialSpecializationDecl:: 853 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 854 SourceLocation StartLoc, SourceLocation IdLoc, 855 TemplateParameterList *Params, 856 ClassTemplateDecl *SpecializedTemplate, 857 ArrayRef<TemplateArgument> Args, 858 const TemplateArgumentListInfo &ArgInfos, 859 QualType CanonInjectedType, 860 ClassTemplatePartialSpecializationDecl *PrevDecl) { 861 const ASTTemplateArgumentListInfo *ASTArgInfos = 862 ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 863 864 auto *Result = new (Context, DC) 865 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, 866 Params, SpecializedTemplate, Args, 867 ASTArgInfos, PrevDecl); 868 Result->setSpecializationKind(TSK_ExplicitSpecialization); 869 Result->setMayHaveOutOfDateDef(false); 870 871 Context.getInjectedClassNameType(Result, CanonInjectedType); 872 return Result; 873 } 874 875 ClassTemplatePartialSpecializationDecl * 876 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 877 unsigned ID) { 878 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); 879 Result->setMayHaveOutOfDateDef(false); 880 return Result; 881 } 882 883 //===----------------------------------------------------------------------===// 884 // FriendTemplateDecl Implementation 885 //===----------------------------------------------------------------------===// 886 887 void FriendTemplateDecl::anchor() {} 888 889 FriendTemplateDecl * 890 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, 891 SourceLocation L, 892 MutableArrayRef<TemplateParameterList *> Params, 893 FriendUnion Friend, SourceLocation FLoc) { 894 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc); 895 } 896 897 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 898 unsigned ID) { 899 return new (C, ID) FriendTemplateDecl(EmptyShell()); 900 } 901 902 //===----------------------------------------------------------------------===// 903 // TypeAliasTemplateDecl Implementation 904 //===----------------------------------------------------------------------===// 905 906 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 907 DeclContext *DC, 908 SourceLocation L, 909 DeclarationName Name, 910 TemplateParameterList *Params, 911 NamedDecl *Decl) { 912 AdoptTemplateParameterList(Params, DC); 913 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 914 } 915 916 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 917 unsigned ID) { 918 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 919 DeclarationName(), nullptr, nullptr); 920 } 921 922 RedeclarableTemplateDecl::CommonBase * 923 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 924 auto *CommonPtr = new (C) Common; 925 C.addDestruction(CommonPtr); 926 return CommonPtr; 927 } 928 929 //===----------------------------------------------------------------------===// 930 // ClassScopeFunctionSpecializationDecl Implementation 931 //===----------------------------------------------------------------------===// 932 933 void ClassScopeFunctionSpecializationDecl::anchor() {} 934 935 ClassScopeFunctionSpecializationDecl * 936 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 937 unsigned ID) { 938 return new (C, ID) ClassScopeFunctionSpecializationDecl( 939 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo()); 940 } 941 942 //===----------------------------------------------------------------------===// 943 // VarTemplateDecl Implementation 944 //===----------------------------------------------------------------------===// 945 946 VarTemplateDecl *VarTemplateDecl::getDefinition() { 947 VarTemplateDecl *CurD = this; 948 while (CurD) { 949 if (CurD->isThisDeclarationADefinition()) 950 return CurD; 951 CurD = CurD->getPreviousDecl(); 952 } 953 return nullptr; 954 } 955 956 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 957 SourceLocation L, DeclarationName Name, 958 TemplateParameterList *Params, 959 VarDecl *Decl) { 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