1 //===- SemaTemplate.h - C++ Templates ---------------------------*- C++ -*-===// 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 // This file provides types used in the semantic analysis of C++ templates. 9 // 10 //===----------------------------------------------------------------------===// 11 12 #ifndef LLVM_CLANG_SEMA_TEMPLATE_H 13 #define LLVM_CLANG_SEMA_TEMPLATE_H 14 15 #include "clang/AST/DeclTemplate.h" 16 #include "clang/AST/DeclVisitor.h" 17 #include "clang/AST/TemplateBase.h" 18 #include "clang/AST/Type.h" 19 #include "clang/Basic/LLVM.h" 20 #include "clang/Sema/Sema.h" 21 #include "llvm/ADT/ArrayRef.h" 22 #include "llvm/ADT/DenseMap.h" 23 #include "llvm/ADT/PointerUnion.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include <cassert> 26 #include <optional> 27 #include <utility> 28 29 namespace clang { 30 31 class ASTContext; 32 class BindingDecl; 33 class CXXMethodDecl; 34 class Decl; 35 class DeclaratorDecl; 36 class DeclContext; 37 class EnumDecl; 38 class FunctionDecl; 39 class NamedDecl; 40 class ParmVarDecl; 41 class TagDecl; 42 class TypedefNameDecl; 43 class TypeSourceInfo; 44 class VarDecl; 45 46 /// The kind of template substitution being performed. 47 enum class TemplateSubstitutionKind : char { 48 /// We are substituting template parameters for template arguments in order 49 /// to form a template specialization. 50 Specialization, 51 /// We are substituting template parameters for (typically) other template 52 /// parameters in order to rewrite a declaration as a different declaration 53 /// (for example, when forming a deduction guide from a constructor). 54 Rewrite, 55 }; 56 57 /// Data structure that captures multiple levels of template argument 58 /// lists for use in template instantiation. 59 /// 60 /// Multiple levels of template arguments occur when instantiating the 61 /// definitions of member templates. For example: 62 /// 63 /// \code 64 /// template<typename T> 65 /// struct X { 66 /// template<T Value> 67 /// struct Y { 68 /// void f(); 69 /// }; 70 /// }; 71 /// \endcode 72 /// 73 /// When instantiating X<int>::Y<17>::f, the multi-level template argument 74 /// list will contain a template argument list (int) at depth 0 and a 75 /// template argument list (17) at depth 1. 76 class MultiLevelTemplateArgumentList { 77 /// The template argument list at a certain template depth 78 79 using ArgList = ArrayRef<TemplateArgument>; 80 struct ArgumentListLevel { 81 llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal; 82 ArgList Args; 83 }; 84 using ContainerType = SmallVector<ArgumentListLevel, 4>; 85 86 using ArgListsIterator = ContainerType::iterator; 87 using ConstArgListsIterator = ContainerType::const_iterator; 88 89 /// The template argument lists, stored from the innermost template 90 /// argument list (first) to the outermost template argument list (last). 91 ContainerType TemplateArgumentLists; 92 93 /// The number of outer levels of template arguments that are not 94 /// being substituted. 95 unsigned NumRetainedOuterLevels = 0; 96 97 /// The kind of substitution described by this argument list. 98 TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization; 99 100 public: 101 /// Construct an empty set of template argument lists. 102 MultiLevelTemplateArgumentList() = default; 103 104 /// Construct a single-level template argument list. 105 MultiLevelTemplateArgumentList(Decl *D, ArgList Args, bool Final) { 106 addOuterTemplateArguments(D, Args, Final); 107 } 108 109 void setKind(TemplateSubstitutionKind K) { Kind = K; } 110 111 /// Determine the kind of template substitution being performed. 112 TemplateSubstitutionKind getKind() const { return Kind; } 113 114 /// Determine whether we are rewriting template parameters rather than 115 /// substituting for them. If so, we should not leave references to the 116 /// original template parameters behind. 117 bool isRewrite() const { 118 return Kind == TemplateSubstitutionKind::Rewrite; 119 } 120 121 /// Determine the number of levels in this template argument 122 /// list. 123 unsigned getNumLevels() const { 124 return TemplateArgumentLists.size() + NumRetainedOuterLevels; 125 } 126 127 /// Determine the number of substituted levels in this template 128 /// argument list. 129 unsigned getNumSubstitutedLevels() const { 130 return TemplateArgumentLists.size(); 131 } 132 133 // Determine the number of substituted args at 'Depth'. 134 unsigned getNumSubsitutedArgs(unsigned Depth) const { 135 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 136 return TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size(); 137 } 138 139 unsigned getNumRetainedOuterLevels() const { 140 return NumRetainedOuterLevels; 141 } 142 143 /// Determine how many of the \p OldDepth outermost template parameter 144 /// lists would be removed by substituting these arguments. 145 unsigned getNewDepth(unsigned OldDepth) const { 146 if (OldDepth < NumRetainedOuterLevels) 147 return OldDepth; 148 if (OldDepth < getNumLevels()) 149 return NumRetainedOuterLevels; 150 return OldDepth - TemplateArgumentLists.size(); 151 } 152 153 /// Retrieve the template argument at a given depth and index. 154 const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { 155 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 156 assert(Index < 157 TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()); 158 return TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]; 159 } 160 161 /// A template-like entity which owns the whole pattern being substituted. 162 /// This will usually own a set of template parameters, or in some 163 /// cases might even be a template parameter itself. 164 std::pair<Decl *, bool> getAssociatedDecl(unsigned Depth) const { 165 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 166 auto AD = TemplateArgumentLists[getNumLevels() - Depth - 1] 167 .AssociatedDeclAndFinal; 168 return {AD.getPointer(), AD.getInt()}; 169 } 170 171 /// Determine whether there is a non-NULL template argument at the 172 /// given depth and index. 173 /// 174 /// There must exist a template argument list at the given depth. 175 bool hasTemplateArgument(unsigned Depth, unsigned Index) const { 176 assert(Depth < getNumLevels()); 177 178 if (Depth < NumRetainedOuterLevels) 179 return false; 180 181 if (Index >= 182 TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()) 183 return false; 184 185 return !(*this)(Depth, Index).isNull(); 186 } 187 188 bool isAnyArgInstantiationDependent() const { 189 for (ArgumentListLevel ListLevel : TemplateArgumentLists) 190 for (const TemplateArgument &TA : ListLevel.Args) 191 if (TA.isInstantiationDependent()) 192 return true; 193 return false; 194 } 195 196 /// Clear out a specific template argument. 197 void setArgument(unsigned Depth, unsigned Index, 198 TemplateArgument Arg) { 199 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 200 assert(Index < 201 TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()); 202 const_cast<TemplateArgument &>( 203 TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]) = Arg; 204 } 205 206 /// Add a new outmost level to the multi-level template argument 207 /// list. 208 /// A 'Final' substitution means that Subst* nodes won't be built 209 /// for the replacements. 210 void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args, 211 bool Final) { 212 assert(!NumRetainedOuterLevels && 213 "substituted args outside retained args?"); 214 assert(getKind() == TemplateSubstitutionKind::Specialization); 215 TemplateArgumentLists.push_back( 216 {{AssociatedDecl->getCanonicalDecl(), Final}, Args}); 217 } 218 219 void addOuterTemplateArguments(ArgList Args) { 220 assert(!NumRetainedOuterLevels && 221 "substituted args outside retained args?"); 222 assert(getKind() == TemplateSubstitutionKind::Rewrite); 223 TemplateArgumentLists.push_back({{}, Args}); 224 } 225 226 void addOuterTemplateArguments(std::nullopt_t) { 227 assert(!NumRetainedOuterLevels && 228 "substituted args outside retained args?"); 229 TemplateArgumentLists.push_back({}); 230 } 231 232 /// Replaces the current 'innermost' level with the provided argument list. 233 /// This is useful for type deduction cases where we need to get the entire 234 /// list from the AST, but then add the deduced innermost list. 235 void replaceInnermostTemplateArguments(Decl *AssociatedDecl, ArgList Args) { 236 assert((!TemplateArgumentLists.empty() || NumRetainedOuterLevels) && 237 "Replacing in an empty list?"); 238 239 if (!TemplateArgumentLists.empty()) { 240 assert((TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() || 241 TemplateArgumentLists[0].AssociatedDeclAndFinal.getPointer() == 242 AssociatedDecl) && 243 "Trying to change incorrect declaration?"); 244 TemplateArgumentLists[0].Args = Args; 245 } else { 246 --NumRetainedOuterLevels; 247 TemplateArgumentLists.push_back( 248 {{AssociatedDecl, /*Final=*/false}, Args}); 249 } 250 } 251 252 /// Add an outermost level that we are not substituting. We have no 253 /// arguments at this level, and do not remove it from the depth of inner 254 /// template parameters that we instantiate. 255 void addOuterRetainedLevel() { 256 ++NumRetainedOuterLevels; 257 } 258 void addOuterRetainedLevels(unsigned Num) { 259 NumRetainedOuterLevels += Num; 260 } 261 262 /// Retrieve the innermost template argument list. 263 const ArgList &getInnermost() const { 264 return TemplateArgumentLists.front().Args; 265 } 266 /// Retrieve the outermost template argument list. 267 const ArgList &getOutermost() const { 268 return TemplateArgumentLists.back().Args; 269 } 270 ArgListsIterator begin() { return TemplateArgumentLists.begin(); } 271 ConstArgListsIterator begin() const { 272 return TemplateArgumentLists.begin(); 273 } 274 ArgListsIterator end() { return TemplateArgumentLists.end(); } 275 ConstArgListsIterator end() const { return TemplateArgumentLists.end(); } 276 277 LLVM_DUMP_METHOD void dump() const { 278 LangOptions LO; 279 LO.CPlusPlus = true; 280 LO.Bool = true; 281 PrintingPolicy PP(LO); 282 llvm::errs() << "NumRetainedOuterLevels: " << NumRetainedOuterLevels 283 << "\n"; 284 for (unsigned Depth = NumRetainedOuterLevels; Depth < getNumLevels(); 285 ++Depth) { 286 llvm::errs() << Depth << ": "; 287 printTemplateArgumentList( 288 llvm::errs(), 289 TemplateArgumentLists[getNumLevels() - Depth - 1].Args, PP); 290 llvm::errs() << "\n"; 291 } 292 } 293 }; 294 295 /// The context in which partial ordering of function templates occurs. 296 enum TPOC { 297 /// Partial ordering of function templates for a function call. 298 TPOC_Call, 299 300 /// Partial ordering of function templates for a call to a 301 /// conversion function. 302 TPOC_Conversion, 303 304 /// Partial ordering of function templates in other contexts, e.g., 305 /// taking the address of a function template or matching a function 306 /// template specialization to a function template. 307 TPOC_Other 308 }; 309 310 // This is lame but unavoidable in a world without forward 311 // declarations of enums. The alternatives are to either pollute 312 // Sema.h (by including this file) or sacrifice type safety (by 313 // making Sema.h declare things as enums). 314 class TemplatePartialOrderingContext { 315 TPOC Value; 316 317 public: 318 TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} 319 320 operator TPOC() const { return Value; } 321 }; 322 323 /// Captures a template argument whose value has been deduced 324 /// via c++ template argument deduction. 325 class DeducedTemplateArgument : public TemplateArgument { 326 /// For a non-type template argument, whether the value was 327 /// deduced from an array bound. 328 bool DeducedFromArrayBound = false; 329 330 public: 331 DeducedTemplateArgument() = default; 332 333 DeducedTemplateArgument(const TemplateArgument &Arg, 334 bool DeducedFromArrayBound = false) 335 : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {} 336 337 /// Construct an integral non-type template argument that 338 /// has been deduced, possibly from an array bound. 339 DeducedTemplateArgument(ASTContext &Ctx, 340 const llvm::APSInt &Value, 341 QualType ValueType, 342 bool DeducedFromArrayBound) 343 : TemplateArgument(Ctx, Value, ValueType), 344 DeducedFromArrayBound(DeducedFromArrayBound) {} 345 346 /// For a non-type template argument, determine whether the 347 /// template argument was deduced from an array bound. 348 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } 349 350 /// Specify whether the given non-type template argument 351 /// was deduced from an array bound. 352 void setDeducedFromArrayBound(bool Deduced) { 353 DeducedFromArrayBound = Deduced; 354 } 355 }; 356 357 /// A stack-allocated class that identifies which local 358 /// variable declaration instantiations are present in this scope. 359 /// 360 /// A new instance of this class type will be created whenever we 361 /// instantiate a new function declaration, which will have its own 362 /// set of parameter declarations. 363 class LocalInstantiationScope { 364 public: 365 /// A set of declarations. 366 using DeclArgumentPack = SmallVector<VarDecl *, 4>; 367 368 private: 369 /// Reference to the semantic analysis that is performing 370 /// this template instantiation. 371 Sema &SemaRef; 372 373 using LocalDeclsMap = 374 llvm::SmallDenseMap<const Decl *, 375 llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>; 376 377 /// A mapping from local declarations that occur 378 /// within a template to their instantiations. 379 /// 380 /// This mapping is used during instantiation to keep track of, 381 /// e.g., function parameter and variable declarations. For example, 382 /// given: 383 /// 384 /// \code 385 /// template<typename T> T add(T x, T y) { return x + y; } 386 /// \endcode 387 /// 388 /// when we instantiate add<int>, we will introduce a mapping from 389 /// the ParmVarDecl for 'x' that occurs in the template to the 390 /// instantiated ParmVarDecl for 'x'. 391 /// 392 /// For a parameter pack, the local instantiation scope may contain a 393 /// set of instantiated parameters. This is stored as a DeclArgumentPack 394 /// pointer. 395 LocalDeclsMap LocalDecls; 396 397 /// The set of argument packs we've allocated. 398 SmallVector<DeclArgumentPack *, 1> ArgumentPacks; 399 400 /// The outer scope, which contains local variable 401 /// definitions from some other instantiation (that may not be 402 /// relevant to this particular scope). 403 LocalInstantiationScope *Outer; 404 405 /// Whether we have already exited this scope. 406 bool Exited = false; 407 408 /// Whether to combine this scope with the outer scope, such that 409 /// lookup will search our outer scope. 410 bool CombineWithOuterScope; 411 412 /// If non-NULL, the template parameter pack that has been 413 /// partially substituted per C++0x [temp.arg.explicit]p9. 414 NamedDecl *PartiallySubstitutedPack = nullptr; 415 416 /// If \c PartiallySubstitutedPack is non-null, the set of 417 /// explicitly-specified template arguments in that pack. 418 const TemplateArgument *ArgsInPartiallySubstitutedPack; 419 420 /// If \c PartiallySubstitutedPack, the number of 421 /// explicitly-specified template arguments in 422 /// ArgsInPartiallySubstitutedPack. 423 unsigned NumArgsInPartiallySubstitutedPack; 424 425 public: 426 LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) 427 : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 428 CombineWithOuterScope(CombineWithOuterScope) { 429 SemaRef.CurrentInstantiationScope = this; 430 } 431 432 LocalInstantiationScope(const LocalInstantiationScope &) = delete; 433 LocalInstantiationScope & 434 operator=(const LocalInstantiationScope &) = delete; 435 436 ~LocalInstantiationScope() { 437 Exit(); 438 } 439 440 const Sema &getSema() const { return SemaRef; } 441 442 /// Exit this local instantiation scope early. 443 void Exit() { 444 if (Exited) 445 return; 446 447 for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) 448 delete ArgumentPacks[I]; 449 450 SemaRef.CurrentInstantiationScope = Outer; 451 Exited = true; 452 } 453 454 /// Clone this scope, and all outer scopes, down to the given 455 /// outermost scope. 456 LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) { 457 if (this == Outermost) return this; 458 459 // Save the current scope from SemaRef since the LocalInstantiationScope 460 // will overwrite it on construction 461 LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope; 462 463 LocalInstantiationScope *newScope = 464 new LocalInstantiationScope(SemaRef, CombineWithOuterScope); 465 466 newScope->Outer = nullptr; 467 if (Outer) 468 newScope->Outer = Outer->cloneScopes(Outermost); 469 470 newScope->PartiallySubstitutedPack = PartiallySubstitutedPack; 471 newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack; 472 newScope->NumArgsInPartiallySubstitutedPack = 473 NumArgsInPartiallySubstitutedPack; 474 475 for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end(); 476 I != E; ++I) { 477 const Decl *D = I->first; 478 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = 479 newScope->LocalDecls[D]; 480 if (I->second.is<Decl *>()) { 481 Stored = I->second.get<Decl *>(); 482 } else { 483 DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>(); 484 DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); 485 Stored = NewPack; 486 newScope->ArgumentPacks.push_back(NewPack); 487 } 488 } 489 // Restore the saved scope to SemaRef 490 SemaRef.CurrentInstantiationScope = oldScope; 491 return newScope; 492 } 493 494 /// deletes the given scope, and all outer scopes, down to the 495 /// given outermost scope. 496 static void deleteScopes(LocalInstantiationScope *Scope, 497 LocalInstantiationScope *Outermost) { 498 while (Scope && Scope != Outermost) { 499 LocalInstantiationScope *Out = Scope->Outer; 500 delete Scope; 501 Scope = Out; 502 } 503 } 504 505 /// Find the instantiation of the declaration D within the current 506 /// instantiation scope. 507 /// 508 /// \param D The declaration whose instantiation we are searching for. 509 /// 510 /// \returns A pointer to the declaration or argument pack of declarations 511 /// to which the declaration \c D is instantiated, if found. Otherwise, 512 /// returns NULL. 513 llvm::PointerUnion<Decl *, DeclArgumentPack *> * 514 findInstantiationOf(const Decl *D); 515 516 void InstantiatedLocal(const Decl *D, Decl *Inst); 517 void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst); 518 void MakeInstantiatedLocalArgPack(const Decl *D); 519 520 /// Note that the given parameter pack has been partially substituted 521 /// via explicit specification of template arguments 522 /// (C++0x [temp.arg.explicit]p9). 523 /// 524 /// \param Pack The parameter pack, which will always be a template 525 /// parameter pack. 526 /// 527 /// \param ExplicitArgs The explicitly-specified template arguments provided 528 /// for this parameter pack. 529 /// 530 /// \param NumExplicitArgs The number of explicitly-specified template 531 /// arguments provided for this parameter pack. 532 void SetPartiallySubstitutedPack(NamedDecl *Pack, 533 const TemplateArgument *ExplicitArgs, 534 unsigned NumExplicitArgs); 535 536 /// Reset the partially-substituted pack when it is no longer of 537 /// interest. 538 void ResetPartiallySubstitutedPack() { 539 assert(PartiallySubstitutedPack && "No partially-substituted pack"); 540 PartiallySubstitutedPack = nullptr; 541 ArgsInPartiallySubstitutedPack = nullptr; 542 NumArgsInPartiallySubstitutedPack = 0; 543 } 544 545 /// Retrieve the partially-substitued template parameter pack. 546 /// 547 /// If there is no partially-substituted parameter pack, returns NULL. 548 NamedDecl * 549 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, 550 unsigned *NumExplicitArgs = nullptr) const; 551 552 /// Determine whether D is a pack expansion created in this scope. 553 bool isLocalPackExpansion(const Decl *D); 554 }; 555 556 class TemplateDeclInstantiator 557 : public DeclVisitor<TemplateDeclInstantiator, Decl *> 558 { 559 Sema &SemaRef; 560 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; 561 DeclContext *Owner; 562 const MultiLevelTemplateArgumentList &TemplateArgs; 563 Sema::LateInstantiatedAttrVec* LateAttrs = nullptr; 564 LocalInstantiationScope *StartingScope = nullptr; 565 bool EvaluateConstraints = true; 566 567 /// A list of out-of-line class template partial 568 /// specializations that will need to be instantiated after the 569 /// enclosing class's instantiation is complete. 570 SmallVector<std::pair<ClassTemplateDecl *, 571 ClassTemplatePartialSpecializationDecl *>, 4> 572 OutOfLinePartialSpecs; 573 574 /// A list of out-of-line variable template partial 575 /// specializations that will need to be instantiated after the 576 /// enclosing variable's instantiation is complete. 577 /// FIXME: Verify that this is needed. 578 SmallVector< 579 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> 580 OutOfLineVarPartialSpecs; 581 582 public: 583 TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, 584 const MultiLevelTemplateArgumentList &TemplateArgs) 585 : SemaRef(SemaRef), 586 SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), 587 Owner(Owner), TemplateArgs(TemplateArgs) {} 588 589 void setEvaluateConstraints(bool B) { 590 EvaluateConstraints = B; 591 } 592 bool getEvaluateConstraints() { 593 return EvaluateConstraints; 594 } 595 596 // Define all the decl visitors using DeclNodes.inc 597 #define DECL(DERIVED, BASE) \ 598 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); 599 #define ABSTRACT_DECL(DECL) 600 601 // Decls which never appear inside a class or function. 602 #define OBJCCONTAINER(DERIVED, BASE) 603 #define FILESCOPEASM(DERIVED, BASE) 604 #define TOPLEVELSTMT(DERIVED, BASE) 605 #define IMPORT(DERIVED, BASE) 606 #define EXPORT(DERIVED, BASE) 607 #define LINKAGESPEC(DERIVED, BASE) 608 #define OBJCCOMPATIBLEALIAS(DERIVED, BASE) 609 #define OBJCMETHOD(DERIVED, BASE) 610 #define OBJCTYPEPARAM(DERIVED, BASE) 611 #define OBJCIVAR(DERIVED, BASE) 612 #define OBJCPROPERTY(DERIVED, BASE) 613 #define OBJCPROPERTYIMPL(DERIVED, BASE) 614 #define EMPTY(DERIVED, BASE) 615 #define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE) 616 617 // Decls which use special-case instantiation code. 618 #define BLOCK(DERIVED, BASE) 619 #define CAPTURED(DERIVED, BASE) 620 #define IMPLICITPARAM(DERIVED, BASE) 621 622 #include "clang/AST/DeclNodes.inc" 623 624 enum class RewriteKind { None, RewriteSpaceshipAsEqualEqual }; 625 626 void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, 627 TypeSourceInfo *&TInfo, 628 DeclarationNameInfo &NameInfo); 629 630 // A few supplemental visitor functions. 631 Decl *VisitCXXMethodDecl(CXXMethodDecl *D, 632 TemplateParameterList *TemplateParams, 633 std::optional<const ASTTemplateArgumentListInfo *> 634 ClassScopeSpecializationArgs = std::nullopt, 635 RewriteKind RK = RewriteKind::None); 636 Decl *VisitFunctionDecl(FunctionDecl *D, 637 TemplateParameterList *TemplateParams, 638 RewriteKind RK = RewriteKind::None); 639 Decl *VisitDecl(Decl *D); 640 Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, 641 ArrayRef<BindingDecl *> *Bindings = nullptr); 642 Decl *VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, 643 LookupResult *Lookup); 644 645 // Enable late instantiation of attributes. Late instantiated attributes 646 // will be stored in LA. 647 void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { 648 LateAttrs = LA; 649 StartingScope = SemaRef.CurrentInstantiationScope; 650 } 651 652 // Disable late instantiation of attributes. 653 void disableLateAttributeInstantiation() { 654 LateAttrs = nullptr; 655 StartingScope = nullptr; 656 } 657 658 LocalInstantiationScope *getStartingScope() const { return StartingScope; } 659 660 using delayed_partial_spec_iterator = SmallVectorImpl<std::pair< 661 ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator; 662 663 using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair< 664 VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator; 665 666 /// Return an iterator to the beginning of the set of 667 /// "delayed" partial specializations, which must be passed to 668 /// InstantiateClassTemplatePartialSpecialization once the class 669 /// definition has been completed. 670 delayed_partial_spec_iterator delayed_partial_spec_begin() { 671 return OutOfLinePartialSpecs.begin(); 672 } 673 674 delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { 675 return OutOfLineVarPartialSpecs.begin(); 676 } 677 678 /// Return an iterator to the end of the set of 679 /// "delayed" partial specializations, which must be passed to 680 /// InstantiateClassTemplatePartialSpecialization once the class 681 /// definition has been completed. 682 delayed_partial_spec_iterator delayed_partial_spec_end() { 683 return OutOfLinePartialSpecs.end(); 684 } 685 686 delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { 687 return OutOfLineVarPartialSpecs.end(); 688 } 689 690 // Helper functions for instantiating methods. 691 TypeSourceInfo *SubstFunctionType(FunctionDecl *D, 692 SmallVectorImpl<ParmVarDecl *> &Params); 693 bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); 694 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); 695 696 bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl); 697 698 TemplateParameterList * 699 SubstTemplateParams(TemplateParameterList *List); 700 701 bool SubstQualifier(const DeclaratorDecl *OldDecl, 702 DeclaratorDecl *NewDecl); 703 bool SubstQualifier(const TagDecl *OldDecl, 704 TagDecl *NewDecl); 705 706 Decl *VisitVarTemplateSpecializationDecl( 707 VarTemplateDecl *VarTemplate, VarDecl *FromVar, 708 const TemplateArgumentListInfo &TemplateArgsInfo, 709 ArrayRef<TemplateArgument> Converted, 710 VarTemplateSpecializationDecl *PrevDecl = nullptr); 711 712 Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); 713 ClassTemplatePartialSpecializationDecl * 714 InstantiateClassTemplatePartialSpecialization( 715 ClassTemplateDecl *ClassTemplate, 716 ClassTemplatePartialSpecializationDecl *PartialSpec); 717 VarTemplatePartialSpecializationDecl * 718 InstantiateVarTemplatePartialSpecialization( 719 VarTemplateDecl *VarTemplate, 720 VarTemplatePartialSpecializationDecl *PartialSpec); 721 void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); 722 723 private: 724 template<typename T> 725 Decl *instantiateUnresolvedUsingDecl(T *D, 726 bool InstantiatingPackElement = false); 727 }; 728 729 } // namespace clang 730 731 #endif // LLVM_CLANG_SEMA_TEMPLATE_H 732