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