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 //===----------------------------------------------------------------------===// 304 // ClassTemplateDecl Implementation 305 //===----------------------------------------------------------------------===// 306 307 ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, 308 DeclContext *DC, 309 SourceLocation L, 310 DeclarationName Name, 311 TemplateParameterList *Params, 312 NamedDecl *Decl, 313 Expr *AssociatedConstraints) { 314 AdoptTemplateParameterList(Params, cast<DeclContext>(Decl)); 315 316 if (!AssociatedConstraints) { 317 return new (C, DC) ClassTemplateDecl(C, DC, L, Name, Params, Decl); 318 } 319 320 auto *const CTDI = new (C) ConstrainedTemplateDeclInfo; 321 auto *const New = 322 new (C, DC) ClassTemplateDecl(CTDI, C, DC, L, Name, Params, Decl); 323 New->setAssociatedConstraints(AssociatedConstraints); 324 return New; 325 } 326 327 ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, 328 unsigned ID) { 329 return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), 330 DeclarationName(), nullptr, nullptr); 331 } 332 333 void ClassTemplateDecl::LoadLazySpecializations() const { 334 loadLazySpecializationsImpl(); 335 } 336 337 llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & 338 ClassTemplateDecl::getSpecializations() const { 339 LoadLazySpecializations(); 340 return getCommonPtr()->Specializations; 341 } 342 343 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> & 344 ClassTemplateDecl::getPartialSpecializations() { 345 LoadLazySpecializations(); 346 return getCommonPtr()->PartialSpecializations; 347 } 348 349 RedeclarableTemplateDecl::CommonBase * 350 ClassTemplateDecl::newCommon(ASTContext &C) const { 351 auto *CommonPtr = new (C) Common; 352 C.addDestruction(CommonPtr); 353 return CommonPtr; 354 } 355 356 ClassTemplateSpecializationDecl * 357 ClassTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 358 void *&InsertPos) { 359 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 360 } 361 362 void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, 363 void *InsertPos) { 364 addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos); 365 } 366 367 ClassTemplatePartialSpecializationDecl * 368 ClassTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 369 void *&InsertPos) { 370 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 371 } 372 373 void ClassTemplateDecl::AddPartialSpecialization( 374 ClassTemplatePartialSpecializationDecl *D, 375 void *InsertPos) { 376 if (InsertPos) 377 getPartialSpecializations().InsertNode(D, InsertPos); 378 else { 379 ClassTemplatePartialSpecializationDecl *Existing 380 = getPartialSpecializations().GetOrInsertNode(D); 381 (void)Existing; 382 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 383 } 384 385 if (ASTMutationListener *L = getASTMutationListener()) 386 L->AddedCXXTemplateSpecialization(this, D); 387 } 388 389 void ClassTemplateDecl::getPartialSpecializations( 390 SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) { 391 llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &PartialSpecs 392 = getPartialSpecializations(); 393 PS.clear(); 394 PS.reserve(PartialSpecs.size()); 395 for (ClassTemplatePartialSpecializationDecl &P : PartialSpecs) 396 PS.push_back(P.getMostRecentDecl()); 397 } 398 399 ClassTemplatePartialSpecializationDecl * 400 ClassTemplateDecl::findPartialSpecialization(QualType T) { 401 ASTContext &Context = getASTContext(); 402 for (ClassTemplatePartialSpecializationDecl &P : 403 getPartialSpecializations()) { 404 if (Context.hasSameType(P.getInjectedSpecializationType(), T)) 405 return P.getMostRecentDecl(); 406 } 407 408 return nullptr; 409 } 410 411 ClassTemplatePartialSpecializationDecl * 412 ClassTemplateDecl::findPartialSpecInstantiatedFromMember( 413 ClassTemplatePartialSpecializationDecl *D) { 414 Decl *DCanon = D->getCanonicalDecl(); 415 for (ClassTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 416 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 417 return P.getMostRecentDecl(); 418 } 419 420 return nullptr; 421 } 422 423 QualType 424 ClassTemplateDecl::getInjectedClassNameSpecialization() { 425 Common *CommonPtr = getCommonPtr(); 426 if (!CommonPtr->InjectedClassNameType.isNull()) 427 return CommonPtr->InjectedClassNameType; 428 429 // C++0x [temp.dep.type]p2: 430 // The template argument list of a primary template is a template argument 431 // list in which the nth template argument has the value of the nth template 432 // parameter of the class template. If the nth template parameter is a 433 // template parameter pack (14.5.3), the nth template argument is a pack 434 // expansion (14.5.3) whose pattern is the name of the template parameter 435 // pack. 436 ASTContext &Context = getASTContext(); 437 TemplateParameterList *Params = getTemplateParameters(); 438 SmallVector<TemplateArgument, 16> TemplateArgs; 439 Context.getInjectedTemplateArgs(Params, TemplateArgs); 440 CommonPtr->InjectedClassNameType 441 = Context.getTemplateSpecializationType(TemplateName(this), 442 TemplateArgs); 443 return CommonPtr->InjectedClassNameType; 444 } 445 446 //===----------------------------------------------------------------------===// 447 // TemplateTypeParm Allocation/Deallocation Method Implementations 448 //===----------------------------------------------------------------------===// 449 450 TemplateTypeParmDecl * 451 TemplateTypeParmDecl::Create(const ASTContext &C, DeclContext *DC, 452 SourceLocation KeyLoc, SourceLocation NameLoc, 453 unsigned D, unsigned P, IdentifierInfo *Id, 454 bool Typename, bool ParameterPack) { 455 auto *TTPDecl = 456 new (C, DC) TemplateTypeParmDecl(DC, KeyLoc, NameLoc, Id, Typename); 457 QualType TTPType = C.getTemplateTypeParmType(D, P, ParameterPack, TTPDecl); 458 TTPDecl->setTypeForDecl(TTPType.getTypePtr()); 459 return TTPDecl; 460 } 461 462 TemplateTypeParmDecl * 463 TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, unsigned ID) { 464 return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), 465 SourceLocation(), nullptr, false); 466 } 467 468 SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { 469 return hasDefaultArgument() 470 ? getDefaultArgumentInfo()->getTypeLoc().getBeginLoc() 471 : SourceLocation(); 472 } 473 474 SourceRange TemplateTypeParmDecl::getSourceRange() const { 475 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 476 return SourceRange(getLocStart(), 477 getDefaultArgumentInfo()->getTypeLoc().getEndLoc()); 478 else 479 return TypeDecl::getSourceRange(); 480 } 481 482 unsigned TemplateTypeParmDecl::getDepth() const { 483 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getDepth(); 484 } 485 486 unsigned TemplateTypeParmDecl::getIndex() const { 487 return getTypeForDecl()->getAs<TemplateTypeParmType>()->getIndex(); 488 } 489 490 bool TemplateTypeParmDecl::isParameterPack() const { 491 return getTypeForDecl()->getAs<TemplateTypeParmType>()->isParameterPack(); 492 } 493 494 //===----------------------------------------------------------------------===// 495 // NonTypeTemplateParmDecl Method Implementations 496 //===----------------------------------------------------------------------===// 497 498 NonTypeTemplateParmDecl::NonTypeTemplateParmDecl( 499 DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, 500 unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, 501 ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos) 502 : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), 503 TemplateParmPosition(D, P), ParameterPack(true), 504 ExpandedParameterPack(true), NumExpandedTypes(ExpandedTypes.size()) { 505 if (!ExpandedTypes.empty() && !ExpandedTInfos.empty()) { 506 auto TypesAndInfos = 507 getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); 508 for (unsigned I = 0; I != NumExpandedTypes; ++I) { 509 new (&TypesAndInfos[I].first) QualType(ExpandedTypes[I]); 510 TypesAndInfos[I].second = ExpandedTInfos[I]; 511 } 512 } 513 } 514 515 NonTypeTemplateParmDecl * 516 NonTypeTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 517 SourceLocation StartLoc, SourceLocation IdLoc, 518 unsigned D, unsigned P, IdentifierInfo *Id, 519 QualType T, bool ParameterPack, 520 TypeSourceInfo *TInfo) { 521 return new (C, DC) NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, 522 T, ParameterPack, TInfo); 523 } 524 525 NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( 526 const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, 527 SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, 528 QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, 529 ArrayRef<TypeSourceInfo *> ExpandedTInfos) { 530 return new (C, DC, 531 additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( 532 ExpandedTypes.size())) 533 NonTypeTemplateParmDecl(DC, StartLoc, IdLoc, D, P, Id, T, TInfo, 534 ExpandedTypes, ExpandedTInfos); 535 } 536 537 NonTypeTemplateParmDecl * 538 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 539 return new (C, ID) NonTypeTemplateParmDecl(nullptr, SourceLocation(), 540 SourceLocation(), 0, 0, nullptr, 541 QualType(), false, nullptr); 542 } 543 544 NonTypeTemplateParmDecl * 545 NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 546 unsigned NumExpandedTypes) { 547 auto *NTTP = 548 new (C, ID, additionalSizeToAlloc<std::pair<QualType, TypeSourceInfo *>>( 549 NumExpandedTypes)) 550 NonTypeTemplateParmDecl(nullptr, SourceLocation(), SourceLocation(), 551 0, 0, nullptr, QualType(), nullptr, None, 552 None); 553 NTTP->NumExpandedTypes = NumExpandedTypes; 554 return NTTP; 555 } 556 557 SourceRange NonTypeTemplateParmDecl::getSourceRange() const { 558 if (hasDefaultArgument() && !defaultArgumentWasInherited()) 559 return SourceRange(getOuterLocStart(), 560 getDefaultArgument()->getSourceRange().getEnd()); 561 return DeclaratorDecl::getSourceRange(); 562 } 563 564 SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const { 565 return hasDefaultArgument() 566 ? getDefaultArgument()->getSourceRange().getBegin() 567 : SourceLocation(); 568 } 569 570 //===----------------------------------------------------------------------===// 571 // TemplateTemplateParmDecl Method Implementations 572 //===----------------------------------------------------------------------===// 573 574 void TemplateTemplateParmDecl::anchor() {} 575 576 TemplateTemplateParmDecl::TemplateTemplateParmDecl( 577 DeclContext *DC, SourceLocation L, unsigned D, unsigned P, 578 IdentifierInfo *Id, TemplateParameterList *Params, 579 ArrayRef<TemplateParameterList *> Expansions) 580 : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), 581 TemplateParmPosition(D, P), ParameterPack(true), 582 ExpandedParameterPack(true), NumExpandedParams(Expansions.size()) { 583 if (!Expansions.empty()) 584 std::uninitialized_copy(Expansions.begin(), Expansions.end(), 585 getTrailingObjects<TemplateParameterList *>()); 586 } 587 588 TemplateTemplateParmDecl * 589 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 590 SourceLocation L, unsigned D, unsigned P, 591 bool ParameterPack, IdentifierInfo *Id, 592 TemplateParameterList *Params) { 593 return new (C, DC) TemplateTemplateParmDecl(DC, L, D, P, ParameterPack, Id, 594 Params); 595 } 596 597 TemplateTemplateParmDecl * 598 TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, 599 SourceLocation L, unsigned D, unsigned P, 600 IdentifierInfo *Id, 601 TemplateParameterList *Params, 602 ArrayRef<TemplateParameterList *> Expansions) { 603 return new (C, DC, 604 additionalSizeToAlloc<TemplateParameterList *>(Expansions.size())) 605 TemplateTemplateParmDecl(DC, L, D, P, Id, Params, Expansions); 606 } 607 608 TemplateTemplateParmDecl * 609 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 610 return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, 611 false, nullptr, nullptr); 612 } 613 614 TemplateTemplateParmDecl * 615 TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, unsigned ID, 616 unsigned NumExpansions) { 617 auto *TTP = 618 new (C, ID, additionalSizeToAlloc<TemplateParameterList *>(NumExpansions)) 619 TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, nullptr, 620 nullptr, None); 621 TTP->NumExpandedParams = NumExpansions; 622 return TTP; 623 } 624 625 SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const { 626 return hasDefaultArgument() ? getDefaultArgument().getLocation() 627 : SourceLocation(); 628 } 629 630 void TemplateTemplateParmDecl::setDefaultArgument( 631 const ASTContext &C, const TemplateArgumentLoc &DefArg) { 632 if (DefArg.getArgument().isNull()) 633 DefaultArgument.set(nullptr); 634 else 635 DefaultArgument.set(new (C) TemplateArgumentLoc(DefArg)); 636 } 637 638 //===----------------------------------------------------------------------===// 639 // TemplateArgumentList Implementation 640 //===----------------------------------------------------------------------===// 641 TemplateArgumentList::TemplateArgumentList(ArrayRef<TemplateArgument> Args) 642 : Arguments(getTrailingObjects<TemplateArgument>()), 643 NumArguments(Args.size()) { 644 std::uninitialized_copy(Args.begin(), Args.end(), 645 getTrailingObjects<TemplateArgument>()); 646 } 647 648 TemplateArgumentList * 649 TemplateArgumentList::CreateCopy(ASTContext &Context, 650 ArrayRef<TemplateArgument> Args) { 651 void *Mem = Context.Allocate(totalSizeToAlloc<TemplateArgument>(Args.size())); 652 return new (Mem) TemplateArgumentList(Args); 653 } 654 655 FunctionTemplateSpecializationInfo * 656 FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD, 657 FunctionTemplateDecl *Template, 658 TemplateSpecializationKind TSK, 659 const TemplateArgumentList *TemplateArgs, 660 const TemplateArgumentListInfo *TemplateArgsAsWritten, 661 SourceLocation POI) { 662 const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; 663 if (TemplateArgsAsWritten) 664 ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C, 665 *TemplateArgsAsWritten); 666 667 return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK, 668 TemplateArgs, 669 ArgsAsWritten, 670 POI); 671 } 672 673 //===----------------------------------------------------------------------===// 674 // TemplateDecl Implementation 675 //===----------------------------------------------------------------------===// 676 677 void TemplateDecl::anchor() {} 678 679 //===----------------------------------------------------------------------===// 680 // ClassTemplateSpecializationDecl Implementation 681 //===----------------------------------------------------------------------===// 682 683 ClassTemplateSpecializationDecl:: 684 ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, 685 DeclContext *DC, SourceLocation StartLoc, 686 SourceLocation IdLoc, 687 ClassTemplateDecl *SpecializedTemplate, 688 ArrayRef<TemplateArgument> Args, 689 ClassTemplateSpecializationDecl *PrevDecl) 690 : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc, 691 SpecializedTemplate->getIdentifier(), PrevDecl), 692 SpecializedTemplate(SpecializedTemplate), 693 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 694 SpecializationKind(TSK_Undeclared) { 695 } 696 697 ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C, 698 Kind DK) 699 : CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(), 700 SourceLocation(), nullptr, nullptr), 701 SpecializationKind(TSK_Undeclared) {} 702 703 ClassTemplateSpecializationDecl * 704 ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, 705 DeclContext *DC, 706 SourceLocation StartLoc, 707 SourceLocation IdLoc, 708 ClassTemplateDecl *SpecializedTemplate, 709 ArrayRef<TemplateArgument> Args, 710 ClassTemplateSpecializationDecl *PrevDecl) { 711 auto *Result = 712 new (Context, DC) ClassTemplateSpecializationDecl( 713 Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, 714 SpecializedTemplate, Args, PrevDecl); 715 Result->MayHaveOutOfDateDef = false; 716 717 Context.getTypeDeclType(Result, PrevDecl); 718 return Result; 719 } 720 721 ClassTemplateSpecializationDecl * 722 ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, 723 unsigned ID) { 724 auto *Result = 725 new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); 726 Result->MayHaveOutOfDateDef = false; 727 return Result; 728 } 729 730 void ClassTemplateSpecializationDecl::getNameForDiagnostic( 731 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 732 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 733 734 const auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this); 735 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 736 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 737 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy); 738 } else { 739 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 740 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy); 741 } 742 } 743 744 ClassTemplateDecl * 745 ClassTemplateSpecializationDecl::getSpecializedTemplate() const { 746 if (const auto *PartialSpec = 747 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>()) 748 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 749 return SpecializedTemplate.get<ClassTemplateDecl*>(); 750 } 751 752 SourceRange 753 ClassTemplateSpecializationDecl::getSourceRange() const { 754 if (ExplicitInfo) { 755 SourceLocation Begin = getTemplateKeywordLoc(); 756 if (Begin.isValid()) { 757 // Here we have an explicit (partial) specialization or instantiation. 758 assert(getSpecializationKind() == TSK_ExplicitSpecialization || 759 getSpecializationKind() == TSK_ExplicitInstantiationDeclaration || 760 getSpecializationKind() == TSK_ExplicitInstantiationDefinition); 761 if (getExternLoc().isValid()) 762 Begin = getExternLoc(); 763 SourceLocation End = getBraceRange().getEnd(); 764 if (End.isInvalid()) 765 End = getTypeAsWritten()->getTypeLoc().getEndLoc(); 766 return SourceRange(Begin, End); 767 } 768 // An implicit instantiation of a class template partial specialization 769 // uses ExplicitInfo to record the TypeAsWritten, but the source 770 // locations should be retrieved from the instantiation pattern. 771 using CTPSDecl = ClassTemplatePartialSpecializationDecl; 772 auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this)); 773 CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember(); 774 assert(inst_from != nullptr); 775 return inst_from->getSourceRange(); 776 } 777 else { 778 // No explicit info available. 779 llvm::PointerUnion<ClassTemplateDecl *, 780 ClassTemplatePartialSpecializationDecl *> 781 inst_from = getInstantiatedFrom(); 782 if (inst_from.isNull()) 783 return getSpecializedTemplate()->getSourceRange(); 784 if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>()) 785 return ctd->getSourceRange(); 786 return inst_from.get<ClassTemplatePartialSpecializationDecl *>() 787 ->getSourceRange(); 788 } 789 } 790 791 //===----------------------------------------------------------------------===// 792 // ClassTemplatePartialSpecializationDecl Implementation 793 //===----------------------------------------------------------------------===// 794 void ClassTemplatePartialSpecializationDecl::anchor() {} 795 796 ClassTemplatePartialSpecializationDecl:: 797 ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, 798 DeclContext *DC, 799 SourceLocation StartLoc, 800 SourceLocation IdLoc, 801 TemplateParameterList *Params, 802 ClassTemplateDecl *SpecializedTemplate, 803 ArrayRef<TemplateArgument> Args, 804 const ASTTemplateArgumentListInfo *ArgInfos, 805 ClassTemplatePartialSpecializationDecl *PrevDecl) 806 : ClassTemplateSpecializationDecl(Context, 807 ClassTemplatePartialSpecialization, 808 TK, DC, StartLoc, IdLoc, 809 SpecializedTemplate, Args, PrevDecl), 810 TemplateParams(Params), ArgsAsWritten(ArgInfos), 811 InstantiatedFromMember(nullptr, false) { 812 AdoptTemplateParameterList(Params, this); 813 } 814 815 ClassTemplatePartialSpecializationDecl * 816 ClassTemplatePartialSpecializationDecl:: 817 Create(ASTContext &Context, TagKind TK,DeclContext *DC, 818 SourceLocation StartLoc, SourceLocation IdLoc, 819 TemplateParameterList *Params, 820 ClassTemplateDecl *SpecializedTemplate, 821 ArrayRef<TemplateArgument> Args, 822 const TemplateArgumentListInfo &ArgInfos, 823 QualType CanonInjectedType, 824 ClassTemplatePartialSpecializationDecl *PrevDecl) { 825 const ASTTemplateArgumentListInfo *ASTArgInfos = 826 ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 827 828 auto *Result = new (Context, DC) 829 ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc, 830 Params, SpecializedTemplate, Args, 831 ASTArgInfos, PrevDecl); 832 Result->setSpecializationKind(TSK_ExplicitSpecialization); 833 Result->MayHaveOutOfDateDef = false; 834 835 Context.getInjectedClassNameType(Result, CanonInjectedType); 836 return Result; 837 } 838 839 ClassTemplatePartialSpecializationDecl * 840 ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 841 unsigned ID) { 842 auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); 843 Result->MayHaveOutOfDateDef = false; 844 return Result; 845 } 846 847 //===----------------------------------------------------------------------===// 848 // FriendTemplateDecl Implementation 849 //===----------------------------------------------------------------------===// 850 851 void FriendTemplateDecl::anchor() {} 852 853 FriendTemplateDecl * 854 FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, 855 SourceLocation L, 856 MutableArrayRef<TemplateParameterList *> Params, 857 FriendUnion Friend, SourceLocation FLoc) { 858 return new (Context, DC) FriendTemplateDecl(DC, L, Params, Friend, FLoc); 859 } 860 861 FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, 862 unsigned ID) { 863 return new (C, ID) FriendTemplateDecl(EmptyShell()); 864 } 865 866 //===----------------------------------------------------------------------===// 867 // TypeAliasTemplateDecl Implementation 868 //===----------------------------------------------------------------------===// 869 870 TypeAliasTemplateDecl *TypeAliasTemplateDecl::Create(ASTContext &C, 871 DeclContext *DC, 872 SourceLocation L, 873 DeclarationName Name, 874 TemplateParameterList *Params, 875 NamedDecl *Decl) { 876 AdoptTemplateParameterList(Params, DC); 877 return new (C, DC) TypeAliasTemplateDecl(C, DC, L, Name, Params, Decl); 878 } 879 880 TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, 881 unsigned ID) { 882 return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), 883 DeclarationName(), nullptr, nullptr); 884 } 885 886 RedeclarableTemplateDecl::CommonBase * 887 TypeAliasTemplateDecl::newCommon(ASTContext &C) const { 888 auto *CommonPtr = new (C) Common; 889 C.addDestruction(CommonPtr); 890 return CommonPtr; 891 } 892 893 //===----------------------------------------------------------------------===// 894 // ClassScopeFunctionSpecializationDecl Implementation 895 //===----------------------------------------------------------------------===// 896 897 void ClassScopeFunctionSpecializationDecl::anchor() {} 898 899 ClassScopeFunctionSpecializationDecl * 900 ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C, 901 unsigned ID) { 902 return new (C, ID) ClassScopeFunctionSpecializationDecl( 903 nullptr, SourceLocation(), nullptr, false, TemplateArgumentListInfo()); 904 } 905 906 //===----------------------------------------------------------------------===// 907 // VarTemplateDecl Implementation 908 //===----------------------------------------------------------------------===// 909 910 VarTemplateDecl *VarTemplateDecl::getDefinition() { 911 VarTemplateDecl *CurD = this; 912 while (CurD) { 913 if (CurD->isThisDeclarationADefinition()) 914 return CurD; 915 CurD = CurD->getPreviousDecl(); 916 } 917 return nullptr; 918 } 919 920 VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, 921 SourceLocation L, DeclarationName Name, 922 TemplateParameterList *Params, 923 VarDecl *Decl) { 924 return new (C, DC) VarTemplateDecl(C, DC, L, Name, Params, Decl); 925 } 926 927 VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, 928 unsigned ID) { 929 return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), 930 DeclarationName(), nullptr, nullptr); 931 } 932 933 void VarTemplateDecl::LoadLazySpecializations() const { 934 loadLazySpecializationsImpl(); 935 } 936 937 llvm::FoldingSetVector<VarTemplateSpecializationDecl> & 938 VarTemplateDecl::getSpecializations() const { 939 LoadLazySpecializations(); 940 return getCommonPtr()->Specializations; 941 } 942 943 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> & 944 VarTemplateDecl::getPartialSpecializations() { 945 LoadLazySpecializations(); 946 return getCommonPtr()->PartialSpecializations; 947 } 948 949 RedeclarableTemplateDecl::CommonBase * 950 VarTemplateDecl::newCommon(ASTContext &C) const { 951 auto *CommonPtr = new (C) Common; 952 C.addDestruction(CommonPtr); 953 return CommonPtr; 954 } 955 956 VarTemplateSpecializationDecl * 957 VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args, 958 void *&InsertPos) { 959 return findSpecializationImpl(getSpecializations(), Args, InsertPos); 960 } 961 962 void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, 963 void *InsertPos) { 964 addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos); 965 } 966 967 VarTemplatePartialSpecializationDecl * 968 VarTemplateDecl::findPartialSpecialization(ArrayRef<TemplateArgument> Args, 969 void *&InsertPos) { 970 return findSpecializationImpl(getPartialSpecializations(), Args, InsertPos); 971 } 972 973 void VarTemplateDecl::AddPartialSpecialization( 974 VarTemplatePartialSpecializationDecl *D, void *InsertPos) { 975 if (InsertPos) 976 getPartialSpecializations().InsertNode(D, InsertPos); 977 else { 978 VarTemplatePartialSpecializationDecl *Existing = 979 getPartialSpecializations().GetOrInsertNode(D); 980 (void)Existing; 981 assert(Existing->isCanonicalDecl() && "Non-canonical specialization?"); 982 } 983 984 if (ASTMutationListener *L = getASTMutationListener()) 985 L->AddedCXXTemplateSpecialization(this, D); 986 } 987 988 void VarTemplateDecl::getPartialSpecializations( 989 SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS) { 990 llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &PartialSpecs = 991 getPartialSpecializations(); 992 PS.clear(); 993 PS.reserve(PartialSpecs.size()); 994 for (VarTemplatePartialSpecializationDecl &P : PartialSpecs) 995 PS.push_back(P.getMostRecentDecl()); 996 } 997 998 VarTemplatePartialSpecializationDecl * 999 VarTemplateDecl::findPartialSpecInstantiatedFromMember( 1000 VarTemplatePartialSpecializationDecl *D) { 1001 Decl *DCanon = D->getCanonicalDecl(); 1002 for (VarTemplatePartialSpecializationDecl &P : getPartialSpecializations()) { 1003 if (P.getInstantiatedFromMember()->getCanonicalDecl() == DCanon) 1004 return P.getMostRecentDecl(); 1005 } 1006 1007 return nullptr; 1008 } 1009 1010 //===----------------------------------------------------------------------===// 1011 // VarTemplateSpecializationDecl Implementation 1012 //===----------------------------------------------------------------------===// 1013 1014 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl( 1015 Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1016 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1017 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) 1018 : VarDecl(DK, Context, DC, StartLoc, IdLoc, 1019 SpecializedTemplate->getIdentifier(), T, TInfo, S), 1020 SpecializedTemplate(SpecializedTemplate), 1021 TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)), 1022 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1023 1024 VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK, 1025 ASTContext &C) 1026 : VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr, 1027 QualType(), nullptr, SC_None), 1028 SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {} 1029 1030 VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( 1031 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1032 SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, 1033 TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args) { 1034 return new (Context, DC) VarTemplateSpecializationDecl( 1035 VarTemplateSpecialization, Context, DC, StartLoc, IdLoc, 1036 SpecializedTemplate, T, TInfo, S, Args); 1037 } 1038 1039 VarTemplateSpecializationDecl * 1040 VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { 1041 return new (C, ID) 1042 VarTemplateSpecializationDecl(VarTemplateSpecialization, C); 1043 } 1044 1045 void VarTemplateSpecializationDecl::getNameForDiagnostic( 1046 raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { 1047 NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); 1048 1049 const auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this); 1050 if (const ASTTemplateArgumentListInfo *ArgsAsWritten = 1051 PS ? PS->getTemplateArgsAsWritten() : nullptr) { 1052 printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy); 1053 } else { 1054 const TemplateArgumentList &TemplateArgs = getTemplateArgs(); 1055 printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy); 1056 } 1057 } 1058 1059 VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const { 1060 if (const auto *PartialSpec = 1061 SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) 1062 return PartialSpec->PartialSpecialization->getSpecializedTemplate(); 1063 return SpecializedTemplate.get<VarTemplateDecl *>(); 1064 } 1065 1066 void VarTemplateSpecializationDecl::setTemplateArgsInfo( 1067 const TemplateArgumentListInfo &ArgsInfo) { 1068 TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc()); 1069 TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc()); 1070 for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments()) 1071 TemplateArgsInfo.addArgument(Loc); 1072 } 1073 1074 //===----------------------------------------------------------------------===// 1075 // VarTemplatePartialSpecializationDecl Implementation 1076 //===----------------------------------------------------------------------===// 1077 1078 void VarTemplatePartialSpecializationDecl::anchor() {} 1079 1080 VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl( 1081 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1082 SourceLocation IdLoc, TemplateParameterList *Params, 1083 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1084 StorageClass S, ArrayRef<TemplateArgument> Args, 1085 const ASTTemplateArgumentListInfo *ArgInfos) 1086 : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context, 1087 DC, StartLoc, IdLoc, SpecializedTemplate, T, 1088 TInfo, S, Args), 1089 TemplateParams(Params), ArgsAsWritten(ArgInfos), 1090 InstantiatedFromMember(nullptr, false) { 1091 // TODO: The template parameters should be in DC by now. Verify. 1092 // AdoptTemplateParameterList(Params, DC); 1093 } 1094 1095 VarTemplatePartialSpecializationDecl * 1096 VarTemplatePartialSpecializationDecl::Create( 1097 ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, 1098 SourceLocation IdLoc, TemplateParameterList *Params, 1099 VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, 1100 StorageClass S, ArrayRef<TemplateArgument> Args, 1101 const TemplateArgumentListInfo &ArgInfos) { 1102 const ASTTemplateArgumentListInfo *ASTArgInfos 1103 = ASTTemplateArgumentListInfo::Create(Context, ArgInfos); 1104 1105 auto *Result = 1106 new (Context, DC) VarTemplatePartialSpecializationDecl( 1107 Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, 1108 S, Args, ASTArgInfos); 1109 Result->setSpecializationKind(TSK_ExplicitSpecialization); 1110 return Result; 1111 } 1112 1113 VarTemplatePartialSpecializationDecl * 1114 VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, 1115 unsigned ID) { 1116 return new (C, ID) VarTemplatePartialSpecializationDecl(C); 1117 } 1118 1119 static TemplateParameterList * 1120 createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) { 1121 // typename T 1122 auto *T = TemplateTypeParmDecl::Create( 1123 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/1, /*Position=*/0, 1124 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); 1125 T->setImplicit(true); 1126 1127 // T ...Ints 1128 TypeSourceInfo *TI = 1129 C.getTrivialTypeSourceInfo(QualType(T->getTypeForDecl(), 0)); 1130 auto *N = NonTypeTemplateParmDecl::Create( 1131 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1132 /*Id=*/nullptr, TI->getType(), /*ParameterPack=*/true, TI); 1133 N->setImplicit(true); 1134 1135 // <typename T, T ...Ints> 1136 NamedDecl *P[2] = {T, N}; 1137 auto *TPL = TemplateParameterList::Create( 1138 C, SourceLocation(), SourceLocation(), P, SourceLocation(), nullptr); 1139 1140 // template <typename T, ...Ints> class IntSeq 1141 auto *TemplateTemplateParm = TemplateTemplateParmDecl::Create( 1142 C, DC, SourceLocation(), /*Depth=*/0, /*Position=*/0, 1143 /*ParameterPack=*/false, /*Id=*/nullptr, TPL); 1144 TemplateTemplateParm->setImplicit(true); 1145 1146 // typename T 1147 auto *TemplateTypeParm = TemplateTypeParmDecl::Create( 1148 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1149 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/false); 1150 TemplateTypeParm->setImplicit(true); 1151 1152 // T N 1153 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo( 1154 QualType(TemplateTypeParm->getTypeForDecl(), 0)); 1155 auto *NonTypeTemplateParm = NonTypeTemplateParmDecl::Create( 1156 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/2, 1157 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1158 NamedDecl *Params[] = {TemplateTemplateParm, TemplateTypeParm, 1159 NonTypeTemplateParm}; 1160 1161 // template <template <typename T, T ...Ints> class IntSeq, typename T, T N> 1162 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1163 Params, SourceLocation(), nullptr); 1164 } 1165 1166 static TemplateParameterList * 1167 createTypePackElementParameterList(const ASTContext &C, DeclContext *DC) { 1168 // std::size_t Index 1169 TypeSourceInfo *TInfo = C.getTrivialTypeSourceInfo(C.getSizeType()); 1170 auto *Index = NonTypeTemplateParmDecl::Create( 1171 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/0, 1172 /*Id=*/nullptr, TInfo->getType(), /*ParameterPack=*/false, TInfo); 1173 1174 // typename ...T 1175 auto *Ts = TemplateTypeParmDecl::Create( 1176 C, DC, SourceLocation(), SourceLocation(), /*Depth=*/0, /*Position=*/1, 1177 /*Id=*/nullptr, /*Typename=*/true, /*ParameterPack=*/true); 1178 Ts->setImplicit(true); 1179 1180 // template <std::size_t Index, typename ...T> 1181 NamedDecl *Params[] = {Index, Ts}; 1182 return TemplateParameterList::Create(C, SourceLocation(), SourceLocation(), 1183 llvm::makeArrayRef(Params), 1184 SourceLocation(), nullptr); 1185 } 1186 1187 static TemplateParameterList *createBuiltinTemplateParameterList( 1188 const ASTContext &C, DeclContext *DC, BuiltinTemplateKind BTK) { 1189 switch (BTK) { 1190 case BTK__make_integer_seq: 1191 return createMakeIntegerSeqParameterList(C, DC); 1192 case BTK__type_pack_element: 1193 return createTypePackElementParameterList(C, DC); 1194 } 1195 1196 llvm_unreachable("unhandled BuiltinTemplateKind!"); 1197 } 1198 1199 void BuiltinTemplateDecl::anchor() {} 1200 1201 BuiltinTemplateDecl::BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, 1202 DeclarationName Name, 1203 BuiltinTemplateKind BTK) 1204 : TemplateDecl(BuiltinTemplate, DC, SourceLocation(), Name, 1205 createBuiltinTemplateParameterList(C, DC, BTK)), 1206 BTK(BTK) {} 1207