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