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 ? AssociatedDecl->getCanonicalDecl() : nullptr, 217 Final}, 218 Args}); 219 } 220 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 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. 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. 257 void addOuterRetainedLevel() { 258 ++NumRetainedOuterLevels; 259 } 260 void addOuterRetainedLevels(unsigned Num) { 261 NumRetainedOuterLevels += Num; 262 } 263 264 /// Retrieve the innermost template argument list. 265 const ArgList &getInnermost() const { 266 return TemplateArgumentLists.front().Args; 267 } 268 /// Retrieve the outermost template argument list. 269 const ArgList &getOutermost() const { 270 return TemplateArgumentLists.back().Args; 271 } 272 ArgListsIterator begin() { return TemplateArgumentLists.begin(); } 273 ConstArgListsIterator begin() const { 274 return TemplateArgumentLists.begin(); 275 } 276 ArgListsIterator end() { return TemplateArgumentLists.end(); } 277 ConstArgListsIterator end() const { return TemplateArgumentLists.end(); } 278 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: 320 TemplatePartialOrderingContext(TPOC Value) : Value(Value) {} 321 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) 337 : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {} 338 339 /// Construct an integral non-type template argument that 340 /// has been deduced, possibly from an array bound. 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. 350 bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; } 351 352 /// Specify whether the given non-type template argument 353 /// was deduced from an array bound. 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 /// Whether this scope is being used to instantiate a lambda or block 415 /// expression, in which case it should be reused for instantiating the 416 /// lambda's FunctionProtoType. 417 bool InstantiatingLambdaOrBlock = false; 418 419 /// If non-NULL, the template parameter pack that has been 420 /// partially substituted per C++0x [temp.arg.explicit]p9. 421 NamedDecl *PartiallySubstitutedPack = nullptr; 422 423 /// If \c PartiallySubstitutedPack is non-null, the set of 424 /// explicitly-specified template arguments in that pack. 425 const TemplateArgument *ArgsInPartiallySubstitutedPack; 426 427 /// If \c PartiallySubstitutedPack, the number of 428 /// explicitly-specified template arguments in 429 /// ArgsInPartiallySubstitutedPack. 430 unsigned NumArgsInPartiallySubstitutedPack; 431 432 public: 433 LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false, 434 bool InstantiatingLambdaOrBlock = false) 435 : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope), 436 CombineWithOuterScope(CombineWithOuterScope), 437 InstantiatingLambdaOrBlock(InstantiatingLambdaOrBlock) { 438 SemaRef.CurrentInstantiationScope = this; 439 } 440 441 LocalInstantiationScope(const LocalInstantiationScope &) = delete; 442 LocalInstantiationScope & 443 operator=(const LocalInstantiationScope &) = delete; 444 445 ~LocalInstantiationScope() { 446 Exit(); 447 } 448 449 const Sema &getSema() const { return SemaRef; } 450 451 /// Exit this local instantiation scope early. 452 void Exit() { 453 if (Exited) 454 return; 455 456 for (unsigned I = 0, N = ArgumentPacks.size(); I != N; ++I) 457 delete ArgumentPacks[I]; 458 459 SemaRef.CurrentInstantiationScope = Outer; 460 Exited = true; 461 } 462 463 /// Clone this scope, and all outer scopes, down to the given 464 /// outermost scope. 465 LocalInstantiationScope *cloneScopes(LocalInstantiationScope *Outermost) { 466 if (this == Outermost) return this; 467 468 // Save the current scope from SemaRef since the LocalInstantiationScope 469 // will overwrite it on construction 470 LocalInstantiationScope *oldScope = SemaRef.CurrentInstantiationScope; 471 472 LocalInstantiationScope *newScope = 473 new LocalInstantiationScope(SemaRef, CombineWithOuterScope); 474 475 newScope->Outer = nullptr; 476 if (Outer) 477 newScope->Outer = Outer->cloneScopes(Outermost); 478 479 newScope->PartiallySubstitutedPack = PartiallySubstitutedPack; 480 newScope->ArgsInPartiallySubstitutedPack = ArgsInPartiallySubstitutedPack; 481 newScope->NumArgsInPartiallySubstitutedPack = 482 NumArgsInPartiallySubstitutedPack; 483 484 for (LocalDeclsMap::iterator I = LocalDecls.begin(), E = LocalDecls.end(); 485 I != E; ++I) { 486 const Decl *D = I->first; 487 llvm::PointerUnion<Decl *, DeclArgumentPack *> &Stored = 488 newScope->LocalDecls[D]; 489 if (auto *D2 = dyn_cast<Decl *>(I->second)) { 490 Stored = D2; 491 } else { 492 DeclArgumentPack *OldPack = cast<DeclArgumentPack *>(I->second); 493 DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); 494 Stored = NewPack; 495 newScope->ArgumentPacks.push_back(NewPack); 496 } 497 } 498 // Restore the saved scope to SemaRef 499 SemaRef.CurrentInstantiationScope = oldScope; 500 return newScope; 501 } 502 503 /// deletes the given scope, and all outer scopes, down to the 504 /// given outermost scope. 505 static void deleteScopes(LocalInstantiationScope *Scope, 506 LocalInstantiationScope *Outermost) { 507 while (Scope && Scope != Outermost) { 508 LocalInstantiationScope *Out = Scope->Outer; 509 delete Scope; 510 Scope = Out; 511 } 512 } 513 514 /// Find the instantiation of the declaration D within the current 515 /// instantiation scope. 516 /// 517 /// \param D The declaration whose instantiation we are searching for. 518 /// 519 /// \returns A pointer to the declaration or argument pack of declarations 520 /// to which the declaration \c D is instantiated, if found. Otherwise, 521 /// returns NULL. 522 llvm::PointerUnion<Decl *, DeclArgumentPack *> * 523 findInstantiationOf(const Decl *D); 524 525 void InstantiatedLocal(const Decl *D, Decl *Inst); 526 void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst); 527 void MakeInstantiatedLocalArgPack(const Decl *D); 528 529 /// Note that the given parameter pack has been partially substituted 530 /// via explicit specification of template arguments 531 /// (C++0x [temp.arg.explicit]p9). 532 /// 533 /// \param Pack The parameter pack, which will always be a template 534 /// parameter pack. 535 /// 536 /// \param ExplicitArgs The explicitly-specified template arguments provided 537 /// for this parameter pack. 538 /// 539 /// \param NumExplicitArgs The number of explicitly-specified template 540 /// arguments provided for this parameter pack. 541 void SetPartiallySubstitutedPack(NamedDecl *Pack, 542 const TemplateArgument *ExplicitArgs, 543 unsigned NumExplicitArgs); 544 545 /// Reset the partially-substituted pack when it is no longer of 546 /// interest. 547 void ResetPartiallySubstitutedPack() { 548 assert(PartiallySubstitutedPack && "No partially-substituted pack"); 549 PartiallySubstitutedPack = nullptr; 550 ArgsInPartiallySubstitutedPack = nullptr; 551 NumArgsInPartiallySubstitutedPack = 0; 552 } 553 554 /// Retrieve the partially-substitued template parameter pack. 555 /// 556 /// If there is no partially-substituted parameter pack, returns NULL. 557 NamedDecl * 558 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, 559 unsigned *NumExplicitArgs = nullptr) const; 560 561 /// Determine whether D is a pack expansion created in this scope. 562 bool isLocalPackExpansion(const Decl *D); 563 564 /// Determine whether this scope is for instantiating a lambda or block. 565 bool isLambdaOrBlock() const { return InstantiatingLambdaOrBlock; } 566 }; 567 568 class TemplateDeclInstantiator 569 : public DeclVisitor<TemplateDeclInstantiator, Decl *> 570 { 571 Sema &SemaRef; 572 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex; 573 DeclContext *Owner; 574 const MultiLevelTemplateArgumentList &TemplateArgs; 575 Sema::LateInstantiatedAttrVec* LateAttrs = nullptr; 576 LocalInstantiationScope *StartingScope = nullptr; 577 // Whether to evaluate the C++20 constraints or simply substitute into them. 578 bool EvaluateConstraints = true; 579 580 /// A list of out-of-line class template partial 581 /// specializations that will need to be instantiated after the 582 /// enclosing class's instantiation is complete. 583 SmallVector<std::pair<ClassTemplateDecl *, 584 ClassTemplatePartialSpecializationDecl *>, 4> 585 OutOfLinePartialSpecs; 586 587 /// A list of out-of-line variable template partial 588 /// specializations that will need to be instantiated after the 589 /// enclosing variable's instantiation is complete. 590 /// FIXME: Verify that this is needed. 591 SmallVector< 592 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 4> 593 OutOfLineVarPartialSpecs; 594 595 public: 596 TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, 597 const MultiLevelTemplateArgumentList &TemplateArgs) 598 : SemaRef(SemaRef), 599 SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex), 600 Owner(Owner), TemplateArgs(TemplateArgs) {} 601 602 void setEvaluateConstraints(bool B) { 603 EvaluateConstraints = B; 604 } 605 bool getEvaluateConstraints() { 606 return EvaluateConstraints; 607 } 608 609 // Define all the decl visitors using DeclNodes.inc 610 #define DECL(DERIVED, BASE) \ 611 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); 612 #define ABSTRACT_DECL(DECL) 613 614 // Decls which never appear inside a class or function. 615 #define OBJCCONTAINER(DERIVED, BASE) 616 #define FILESCOPEASM(DERIVED, BASE) 617 #define TOPLEVELSTMT(DERIVED, BASE) 618 #define IMPORT(DERIVED, BASE) 619 #define EXPORT(DERIVED, BASE) 620 #define LINKAGESPEC(DERIVED, BASE) 621 #define OBJCCOMPATIBLEALIAS(DERIVED, BASE) 622 #define OBJCMETHOD(DERIVED, BASE) 623 #define OBJCTYPEPARAM(DERIVED, BASE) 624 #define OBJCIVAR(DERIVED, BASE) 625 #define OBJCPROPERTY(DERIVED, BASE) 626 #define OBJCPROPERTYIMPL(DERIVED, BASE) 627 #define EMPTY(DERIVED, BASE) 628 #define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE) 629 630 // Decls which never appear inside a template. 631 #define OUTLINEDFUNCTION(DERIVED, BASE) 632 633 // Decls which use special-case instantiation code. 634 #define BLOCK(DERIVED, BASE) 635 #define CAPTURED(DERIVED, BASE) 636 #define IMPLICITPARAM(DERIVED, BASE) 637 638 #include "clang/AST/DeclNodes.inc" 639 640 enum class RewriteKind { None, RewriteSpaceshipAsEqualEqual }; 641 642 void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, 643 TypeSourceInfo *&TInfo, 644 DeclarationNameInfo &NameInfo); 645 646 // A few supplemental visitor functions. 647 Decl *VisitCXXMethodDecl(CXXMethodDecl *D, 648 TemplateParameterList *TemplateParams, 649 RewriteKind RK = RewriteKind::None); 650 Decl *VisitFunctionDecl(FunctionDecl *D, 651 TemplateParameterList *TemplateParams, 652 RewriteKind RK = RewriteKind::None); 653 Decl *VisitDecl(Decl *D); 654 Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, 655 ArrayRef<BindingDecl *> *Bindings = nullptr); 656 Decl *VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, 657 LookupResult *Lookup); 658 659 // Enable late instantiation of attributes. Late instantiated attributes 660 // will be stored in LA. 661 void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { 662 LateAttrs = LA; 663 StartingScope = SemaRef.CurrentInstantiationScope; 664 } 665 666 // Disable late instantiation of attributes. 667 void disableLateAttributeInstantiation() { 668 LateAttrs = nullptr; 669 StartingScope = nullptr; 670 } 671 672 LocalInstantiationScope *getStartingScope() const { return StartingScope; } 673 674 using delayed_partial_spec_iterator = SmallVectorImpl<std::pair< 675 ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator; 676 677 using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair< 678 VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator; 679 680 /// Return an iterator to the beginning of the set of 681 /// "delayed" partial specializations, which must be passed to 682 /// InstantiateClassTemplatePartialSpecialization once the class 683 /// definition has been completed. 684 delayed_partial_spec_iterator delayed_partial_spec_begin() { 685 return OutOfLinePartialSpecs.begin(); 686 } 687 688 delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { 689 return OutOfLineVarPartialSpecs.begin(); 690 } 691 692 /// Return an iterator to the end of the set of 693 /// "delayed" partial specializations, which must be passed to 694 /// InstantiateClassTemplatePartialSpecialization once the class 695 /// definition has been completed. 696 delayed_partial_spec_iterator delayed_partial_spec_end() { 697 return OutOfLinePartialSpecs.end(); 698 } 699 700 delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { 701 return OutOfLineVarPartialSpecs.end(); 702 } 703 704 // Helper functions for instantiating methods. 705 TypeSourceInfo *SubstFunctionType(FunctionDecl *D, 706 SmallVectorImpl<ParmVarDecl *> &Params); 707 bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); 708 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); 709 710 bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl); 711 712 TemplateParameterList * 713 SubstTemplateParams(TemplateParameterList *List); 714 715 bool SubstQualifier(const DeclaratorDecl *OldDecl, 716 DeclaratorDecl *NewDecl); 717 bool SubstQualifier(const TagDecl *OldDecl, 718 TagDecl *NewDecl); 719 720 Decl *VisitVarTemplateSpecializationDecl( 721 VarTemplateDecl *VarTemplate, VarDecl *FromVar, 722 const TemplateArgumentListInfo &TemplateArgsInfo, 723 ArrayRef<TemplateArgument> Converted, 724 VarTemplateSpecializationDecl *PrevDecl = nullptr); 725 726 Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); 727 Decl *InstantiateTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); 728 ClassTemplatePartialSpecializationDecl * 729 InstantiateClassTemplatePartialSpecialization( 730 ClassTemplateDecl *ClassTemplate, 731 ClassTemplatePartialSpecializationDecl *PartialSpec); 732 VarTemplatePartialSpecializationDecl * 733 InstantiateVarTemplatePartialSpecialization( 734 VarTemplateDecl *VarTemplate, 735 VarTemplatePartialSpecializationDecl *PartialSpec); 736 void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); 737 738 private: 739 template<typename T> 740 Decl *instantiateUnresolvedUsingDecl(T *D, 741 bool InstantiatingPackElement = false); 742 }; 743 744 } // namespace clang 745 746 #endif // LLVM_CLANG_SEMA_TEMPLATE_H 747