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. MultiLevelTemplateArgumentList(Decl * D,ArgList Args,bool Final)105 MultiLevelTemplateArgumentList(Decl *D, ArgList Args, bool Final) { 106 addOuterTemplateArguments(D, Args, Final); 107 } 108 setKind(TemplateSubstitutionKind K)109 void setKind(TemplateSubstitutionKind K) { Kind = K; } 110 111 /// Determine the kind of template substitution being performed. getKind()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. isRewrite()117 bool isRewrite() const { 118 return Kind == TemplateSubstitutionKind::Rewrite; 119 } 120 121 /// Determine the number of levels in this template argument 122 /// list. getNumLevels()123 unsigned getNumLevels() const { 124 return TemplateArgumentLists.size() + NumRetainedOuterLevels; 125 } 126 127 /// Determine the number of substituted levels in this template 128 /// argument list. getNumSubstitutedLevels()129 unsigned getNumSubstitutedLevels() const { 130 return TemplateArgumentLists.size(); 131 } 132 133 // Determine the number of substituted args at 'Depth'. getNumSubsitutedArgs(unsigned Depth)134 unsigned getNumSubsitutedArgs(unsigned Depth) const { 135 assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); 136 return TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size(); 137 } 138 getNumRetainedOuterLevels()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. getNewDepth(unsigned OldDepth)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. operator()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. getAssociatedDecl(unsigned Depth)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. hasTemplateArgument(unsigned Depth,unsigned Index)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 isAnyArgInstantiationDependent()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. setArgument(unsigned Depth,unsigned Index,TemplateArgument Arg)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. addOuterTemplateArguments(Decl * AssociatedDecl,ArgList Args,bool Final)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 addOuterTemplateArguments(ArgList Args)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 addOuterTemplateArguments(std::nullopt_t)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. replaceInnermostTemplateArguments(ArgList Args)235 void replaceInnermostTemplateArguments(ArgList Args) { 236 assert(TemplateArgumentLists.size() > 0 && "Replacing in an empty list?"); 237 TemplateArgumentLists[0].Args = Args; 238 } 239 240 /// Add an outermost level that we are not substituting. We have no 241 /// arguments at this level, and do not remove it from the depth of inner 242 /// template parameters that we instantiate. addOuterRetainedLevel()243 void addOuterRetainedLevel() { 244 ++NumRetainedOuterLevels; 245 } addOuterRetainedLevels(unsigned Num)246 void addOuterRetainedLevels(unsigned Num) { 247 NumRetainedOuterLevels += Num; 248 } 249 250 /// Retrieve the innermost template argument list. getInnermost()251 const ArgList &getInnermost() const { 252 return TemplateArgumentLists.front().Args; 253 } 254 /// Retrieve the outermost template argument list. getOutermost()255 const ArgList &getOutermost() const { 256 return TemplateArgumentLists.back().Args; 257 } begin()258 ArgListsIterator begin() { return TemplateArgumentLists.begin(); } begin()259 ConstArgListsIterator begin() const { 260 return TemplateArgumentLists.begin(); 261 } end()262 ArgListsIterator end() { return TemplateArgumentLists.end(); } end()263 ConstArgListsIterator end() const { return TemplateArgumentLists.end(); } 264 }; 265 266 /// The context in which partial ordering of function templates occurs. 267 enum TPOC { 268 /// Partial ordering of function templates for a function call. 269 TPOC_Call, 270 271 /// Partial ordering of function templates for a call to a 272 /// conversion function. 273 TPOC_Conversion, 274 275 /// Partial ordering of function templates in other contexts, e.g., 276 /// taking the address of a function template or matching a function 277 /// template specialization to a function template. 278 TPOC_Other 279 }; 280 281 // This is lame but unavoidable in a world without forward 282 // declarations of enums. The alternatives are to either pollute 283 // Sema.h (by including this file) or sacrifice type safety (by 284 // making Sema.h declare things as enums). 285 class TemplatePartialOrderingContext { 286 TPOC Value; 287 288 public: TemplatePartialOrderingContext(TPOC Value)289 TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} 290 TPOC()291 operator TPOC() const { return Value; } 292 }; 293 294 /// Captures a template argument whose value has been deduced 295 /// via c++ template argument deduction. 296 class DeducedTemplateArgument : public TemplateArgument { 297 /// For a non-type template argument, whether the value was 298 /// deduced from an array bound. 299 bool DeducedFromArrayBound = false; 300 301 public: 302 DeducedTemplateArgument() = default; 303 304 DeducedTemplateArgument(const TemplateArgument &Arg, 305 bool DeducedFromArrayBound = false) TemplateArgument(Arg)306 : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {} 307 308 /// Construct an integral non-type template argument that 309 /// has been deduced, possibly from an array bound. DeducedTemplateArgument(ASTContext & Ctx,const llvm::APSInt & Value,QualType ValueType,bool DeducedFromArrayBound)310 DeducedTemplateArgument(ASTContext &Ctx, 311 const llvm::APSInt &Value, 312 QualType ValueType, 313 bool DeducedFromArrayBound) 314 : TemplateArgument(Ctx, Value, ValueType), 315 DeducedFromArrayBound(DeducedFromArrayBound) {} 316 317 /// For a non-type template argument, determine whether the 318 /// template argument was deduced from an array bound. wasDeducedFromArrayBound()319 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } 320 321 /// Specify whether the given non-type template argument 322 /// was deduced from an array bound. setDeducedFromArrayBound(bool Deduced)323 void setDeducedFromArrayBound(bool Deduced) { 324 DeducedFromArrayBound = Deduced; 325 } 326 }; 327 328 /// A stack-allocated class that identifies which local 329 /// variable declaration instantiations are present in this scope. 330 /// 331 /// A new instance of this class type will be created whenever we 332 /// instantiate a new function declaration, which will have its own 333 /// set of parameter declarations. 334 class LocalInstantiationScope { 335 public: 336 /// A set of declarations. 337 using DeclArgumentPack = SmallVector<VarDecl *, 4>; 338 339 private: 340 /// Reference to the semantic analysis that is performing 341 /// this template instantiation. 342 Sema &SemaRef; 343 344 using LocalDeclsMap = 345 llvm::SmallDenseMap<const Decl *, 346 llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4>; 347 348 /// A mapping from local declarations that occur 349 /// within a template to their instantiations. 350 /// 351 /// This mapping is used during instantiation to keep track of, 352 /// e.g., function parameter and variable declarations. For example, 353 /// given: 354 /// 355 /// \code 356 /// template<typename T> T add(T x, T y) { return x + y; } 357 /// \endcode 358 /// 359 /// when we instantiate add<int>, we will introduce a mapping from 360 /// the ParmVarDecl for 'x' that occurs in the template to the 361 /// instantiated ParmVarDecl for 'x'. 362 /// 363 /// For a parameter pack, the local instantiation scope may contain a 364 /// set of instantiated parameters. This is stored as a DeclArgumentPack 365 /// pointer. 366 LocalDeclsMap LocalDecls; 367 368 /// The set of argument packs we've allocated. 369 SmallVector<DeclArgumentPack *, 1> ArgumentPacks; 370 371 /// The outer scope, which contains local variable 372 /// definitions from some other instantiation (that may not be 373 /// relevant to this particular scope). 374 LocalInstantiationScope *Outer; 375 376 /// Whether we have already exited this scope. 377 bool Exited = false; 378 379 /// Whether to combine this scope with the outer scope, such that 380 /// lookup will search our outer scope. 381 bool CombineWithOuterScope; 382 383 /// If non-NULL, the template parameter pack that has been 384 /// partially substituted per C++0x [temp.arg.explicit]p9. 385 NamedDecl *PartiallySubstitutedPack = nullptr; 386 387 /// If \c PartiallySubstitutedPack is non-null, the set of 388 /// explicitly-specified template arguments in that pack. 389 const TemplateArgument *ArgsInPartiallySubstitutedPack; 390 391 /// If \c PartiallySubstitutedPack, the number of 392 /// explicitly-specified template arguments in 393 /// ArgsInPartiallySubstitutedPack. 394 unsigned NumArgsInPartiallySubstitutedPack; 395 396 public: 397 LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) SemaRef(SemaRef)398 : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 399 CombineWithOuterScope(CombineWithOuterScope) { 400 SemaRef.CurrentInstantiationScope = this; 401 } 402 403 LocalInstantiationScope(const LocalInstantiationScope &) = delete; 404 LocalInstantiationScope & 405 operator=(const LocalInstantiationScope &) = delete; 406 ~LocalInstantiationScope()407 ~LocalInstantiationScope() { 408 Exit(); 409 } 410 getSema()411 const Sema &getSema() const { return SemaRef; } 412 413 /// Exit this local instantiation scope early. Exit()414 void Exit() { 415 if (Exited) 416 return; 417 418 for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) 419 delete ArgumentPacks[I]; 420 421 SemaRef.CurrentInstantiationScope = Outer; 422 Exited = true; 423 } 424 425 /// Clone this scope, and all outer scopes, down to the given 426 /// outermost scope. cloneScopes(LocalInstantiationScope * Outermost)427 LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) { 428 if (this == Outermost) return this; 429 430 // Save the current scope from SemaRef since the LocalInstantiationScope 431 // will overwrite it on construction 432 LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope; 433 434 LocalInstantiationScope *newScope = 435 new LocalInstantiationScope(SemaRef, CombineWithOuterScope); 436 437 newScope->Outer = nullptr; 438 if (Outer) 439 newScope->Outer = Outer->cloneScopes(Outermost); 440 441 newScope->PartiallySubstitutedPack = PartiallySubstitutedPack; 442 newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack; 443 newScope->NumArgsInPartiallySubstitutedPack = 444 NumArgsInPartiallySubstitutedPack; 445 446 for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end(); 447 I != E; ++I) { 448 const Decl *D = I->first; 449 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = 450 newScope->LocalDecls[D]; 451 if (I->second.is<Decl *>()) { 452 Stored = I->second.get<Decl *>(); 453 } else { 454 DeclArgumentPack *OldPack = I->second.get<DeclArgumentPack *>(); 455 DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); 456 Stored = NewPack; 457 newScope->ArgumentPacks.push_back(NewPack); 458 } 459 } 460 // Restore the saved scope to SemaRef 461 SemaRef.CurrentInstantiationScope = oldScope; 462 return newScope; 463 } 464 465 /// deletes the given scope, and all outer scopes, down to the 466 /// given outermost scope. deleteScopes(LocalInstantiationScope * Scope,LocalInstantiationScope * Outermost)467 static void deleteScopes(LocalInstantiationScope *Scope, 468 LocalInstantiationScope *Outermost) { 469 while (Scope && Scope != Outermost) { 470 LocalInstantiationScope *Out = Scope->Outer; 471 delete Scope; 472 Scope = Out; 473 } 474 } 475 476 /// Find the instantiation of the declaration D within the current 477 /// instantiation scope. 478 /// 479 /// \param D The declaration whose instantiation we are searching for. 480 /// 481 /// \returns A pointer to the declaration or argument pack of declarations 482 /// to which the declaration \c D is instantiated, if found. Otherwise, 483 /// returns NULL. 484 llvm::PointerUnion<Decl *, DeclArgumentPack *> * 485 findInstantiationOf(const Decl *D); 486 487 void InstantiatedLocal(const Decl *D, Decl *Inst); 488 void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst); 489 void MakeInstantiatedLocalArgPack(const Decl *D); 490 491 /// Note that the given parameter pack has been partially substituted 492 /// via explicit specification of template arguments 493 /// (C++0x [temp.arg.explicit]p9). 494 /// 495 /// \param Pack The parameter pack, which will always be a template 496 /// parameter pack. 497 /// 498 /// \param ExplicitArgs The explicitly-specified template arguments provided 499 /// for this parameter pack. 500 /// 501 /// \param NumExplicitArgs The number of explicitly-specified template 502 /// arguments provided for this parameter pack. 503 void SetPartiallySubstitutedPack(NamedDecl *Pack, 504 const TemplateArgument *ExplicitArgs, 505 unsigned NumExplicitArgs); 506 507 /// Reset the partially-substituted pack when it is no longer of 508 /// interest. ResetPartiallySubstitutedPack()509 void ResetPartiallySubstitutedPack() { 510 assert(PartiallySubstitutedPack && "No partially-substituted pack"); 511 PartiallySubstitutedPack = nullptr; 512 ArgsInPartiallySubstitutedPack = nullptr; 513 NumArgsInPartiallySubstitutedPack = 0; 514 } 515 516 /// Retrieve the partially-substitued template parameter pack. 517 /// 518 /// If there is no partially-substituted parameter pack, returns NULL. 519 NamedDecl * 520 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, 521 unsigned *NumExplicitArgs = nullptr) const; 522 523 /// Determine whether D is a pack expansion created in this scope. 524 bool isLocalPackExpansion(const Decl *D); 525 }; 526 527 class TemplateDeclInstantiator 528 : public DeclVisitor<TemplateDeclInstantiator, Decl *> 529 { 530 Sema &SemaRef; 531 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; 532 DeclContext *Owner; 533 const MultiLevelTemplateArgumentList &TemplateArgs; 534 Sema::LateInstantiatedAttrVec* LateAttrs = nullptr; 535 LocalInstantiationScope *StartingScope = nullptr; 536 bool EvaluateConstraints = true; 537 538 /// A list of out-of-line class template partial 539 /// specializations that will need to be instantiated after the 540 /// enclosing class's instantiation is complete. 541 SmallVector<std::pair<ClassTemplateDecl *, 542 ClassTemplatePartialSpecializationDecl *>, 4> 543 OutOfLinePartialSpecs; 544 545 /// A list of out-of-line variable template partial 546 /// specializations that will need to be instantiated after the 547 /// enclosing variable's instantiation is complete. 548 /// FIXME: Verify that this is needed. 549 SmallVector< 550 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> 551 OutOfLineVarPartialSpecs; 552 553 public: TemplateDeclInstantiator(Sema & SemaRef,DeclContext * Owner,const MultiLevelTemplateArgumentList & TemplateArgs)554 TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, 555 const MultiLevelTemplateArgumentList &TemplateArgs) 556 : SemaRef(SemaRef), 557 SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), 558 Owner(Owner), TemplateArgs(TemplateArgs) {} 559 setEvaluateConstraints(bool B)560 void setEvaluateConstraints(bool B) { 561 EvaluateConstraints = B; 562 } getEvaluateConstraints()563 bool getEvaluateConstraints() { 564 return EvaluateConstraints; 565 } 566 567 // Define all the decl visitors using DeclNodes.inc 568 #define DECL(DERIVED, BASE) \ 569 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); 570 #define ABSTRACT_DECL(DECL) 571 572 // Decls which never appear inside a class or function. 573 #define OBJCCONTAINER(DERIVED, BASE) 574 #define FILESCOPEASM(DERIVED, BASE) 575 #define TOPLEVELSTMT(DERIVED, BASE) 576 #define IMPORT(DERIVED, BASE) 577 #define EXPORT(DERIVED, BASE) 578 #define LINKAGESPEC(DERIVED, BASE) 579 #define OBJCCOMPATIBLEALIAS(DERIVED, BASE) 580 #define OBJCMETHOD(DERIVED, BASE) 581 #define OBJCTYPEPARAM(DERIVED, BASE) 582 #define OBJCIVAR(DERIVED, BASE) 583 #define OBJCPROPERTY(DERIVED, BASE) 584 #define OBJCPROPERTYIMPL(DERIVED, BASE) 585 #define EMPTY(DERIVED, BASE) 586 #define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE) 587 588 // Decls which use special-case instantiation code. 589 #define BLOCK(DERIVED, BASE) 590 #define CAPTURED(DERIVED, BASE) 591 #define IMPLICITPARAM(DERIVED, BASE) 592 593 #include "clang/AST/DeclNodes.inc" 594 595 enum class RewriteKind { None, RewriteSpaceshipAsEqualEqual }; 596 597 void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, 598 TypeSourceInfo *&TInfo, 599 DeclarationNameInfo &NameInfo); 600 601 // A few supplemental visitor functions. 602 Decl *VisitCXXMethodDecl(CXXMethodDecl *D, 603 TemplateParameterList *TemplateParams, 604 std::optional<const ASTTemplateArgumentListInfo *> 605 ClassScopeSpecializationArgs = std::nullopt, 606 RewriteKind RK = RewriteKind::None); 607 Decl *VisitFunctionDecl(FunctionDecl *D, 608 TemplateParameterList *TemplateParams, 609 RewriteKind RK = RewriteKind::None); 610 Decl *VisitDecl(Decl *D); 611 Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, 612 ArrayRef<BindingDecl *> *Bindings = nullptr); 613 Decl *VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, 614 LookupResult *Lookup); 615 616 // Enable late instantiation of attributes. Late instantiated attributes 617 // will be stored in LA. enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec * LA)618 void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { 619 LateAttrs = LA; 620 StartingScope = SemaRef.CurrentInstantiationScope; 621 } 622 623 // Disable late instantiation of attributes. disableLateAttributeInstantiation()624 void disableLateAttributeInstantiation() { 625 LateAttrs = nullptr; 626 StartingScope = nullptr; 627 } 628 getStartingScope()629 LocalInstantiationScope *getStartingScope() const { return StartingScope; } 630 631 using delayed_partial_spec_iterator = SmallVectorImpl<std::pair< 632 ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator; 633 634 using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair< 635 VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator; 636 637 /// Return an iterator to the beginning of the set of 638 /// "delayed" partial specializations, which must be passed to 639 /// InstantiateClassTemplatePartialSpecialization once the class 640 /// definition has been completed. delayed_partial_spec_begin()641 delayed_partial_spec_iterator delayed_partial_spec_begin() { 642 return OutOfLinePartialSpecs.begin(); 643 } 644 delayed_var_partial_spec_begin()645 delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { 646 return OutOfLineVarPartialSpecs.begin(); 647 } 648 649 /// Return an iterator to the end of the set of 650 /// "delayed" partial specializations, which must be passed to 651 /// InstantiateClassTemplatePartialSpecialization once the class 652 /// definition has been completed. delayed_partial_spec_end()653 delayed_partial_spec_iterator delayed_partial_spec_end() { 654 return OutOfLinePartialSpecs.end(); 655 } 656 delayed_var_partial_spec_end()657 delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { 658 return OutOfLineVarPartialSpecs.end(); 659 } 660 661 // Helper functions for instantiating methods. 662 TypeSourceInfo *SubstFunctionType(FunctionDecl *D, 663 SmallVectorImpl<ParmVarDecl *> &Params); 664 bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); 665 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); 666 667 bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl); 668 669 TemplateParameterList * 670 SubstTemplateParams(TemplateParameterList *List); 671 672 bool SubstQualifier(const DeclaratorDecl *OldDecl, 673 DeclaratorDecl *NewDecl); 674 bool SubstQualifier(const TagDecl *OldDecl, 675 TagDecl *NewDecl); 676 677 Decl *VisitVarTemplateSpecializationDecl( 678 VarTemplateDecl *VarTemplate, VarDecl *FromVar, 679 const TemplateArgumentListInfo &TemplateArgsInfo, 680 ArrayRef<TemplateArgument> Converted, 681 VarTemplateSpecializationDecl *PrevDecl = nullptr); 682 683 Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); 684 ClassTemplatePartialSpecializationDecl * 685 InstantiateClassTemplatePartialSpecialization( 686 ClassTemplateDecl *ClassTemplate, 687 ClassTemplatePartialSpecializationDecl *PartialSpec); 688 VarTemplatePartialSpecializationDecl * 689 InstantiateVarTemplatePartialSpecialization( 690 VarTemplateDecl *VarTemplate, 691 VarTemplatePartialSpecializationDecl *PartialSpec); 692 void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); 693 694 private: 695 template<typename T> 696 Decl *instantiateUnresolvedUsingDecl(T *D, 697 bool InstantiatingPackElement = false); 698 }; 699 700 } // namespace clang 701 702 #endif // LLVM_CLANG_SEMA_TEMPLATE_H 703