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