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