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