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