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