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