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