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