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