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