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