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