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