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<ValueDecl *, 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) SemaRef(SemaRef)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 ~LocalInstantiationScope()445 ~LocalInstantiationScope() { 446 Exit(); 447 } 448 getSema()449 const Sema &getSema() const { return SemaRef; } 450 451 /// Exit this local instantiation scope early. Exit()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. cloneScopes(LocalInstantiationScope * Outermost)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. deleteScopes(LocalInstantiationScope * Scope,LocalInstantiationScope * Outermost)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 /// Similar to \p findInstantiationOf(), but it wouldn't assert if the 526 /// instantiation was not found within the current instantiation scope. This 527 /// is helpful for on-demand declaration instantiation. 528 llvm::PointerUnion<Decl *, DeclArgumentPack *> * 529 getInstantiationOfIfExists(const Decl *D); 530 531 void InstantiatedLocal(const Decl *D, Decl *Inst); 532 void InstantiatedLocalPackArg(const Decl *D, VarDecl *Inst); 533 void MakeInstantiatedLocalArgPack(const Decl *D); 534 535 /// Note that the given parameter pack has been partially substituted 536 /// via explicit specification of template arguments 537 /// (C++0x [temp.arg.explicit]p9). 538 /// 539 /// \param Pack The parameter pack, which will always be a template 540 /// parameter pack. 541 /// 542 /// \param ExplicitArgs The explicitly-specified template arguments provided 543 /// for this parameter pack. 544 /// 545 /// \param NumExplicitArgs The number of explicitly-specified template 546 /// arguments provided for this parameter pack. 547 void SetPartiallySubstitutedPack(NamedDecl *Pack, 548 const TemplateArgument *ExplicitArgs, 549 unsigned NumExplicitArgs); 550 551 /// Reset the partially-substituted pack when it is no longer of 552 /// interest. ResetPartiallySubstitutedPack()553 void ResetPartiallySubstitutedPack() { 554 assert(PartiallySubstitutedPack && "No partially-substituted pack"); 555 PartiallySubstitutedPack = nullptr; 556 ArgsInPartiallySubstitutedPack = nullptr; 557 NumArgsInPartiallySubstitutedPack = 0; 558 } 559 560 /// Retrieve the partially-substitued template parameter pack. 561 /// 562 /// If there is no partially-substituted parameter pack, returns NULL. 563 NamedDecl * 564 getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, 565 unsigned *NumExplicitArgs = nullptr) const; 566 567 /// Determine whether D is a pack expansion created in this scope. 568 bool isLocalPackExpansion(const Decl *D); 569 570 /// Determine whether this scope is for instantiating a lambda or block. isLambdaOrBlock()571 bool isLambdaOrBlock() const { return InstantiatingLambdaOrBlock; } 572 }; 573 574 class TemplateDeclInstantiator 575 : public DeclVisitor<TemplateDeclInstantiator, Decl *> 576 { 577 Sema &SemaRef; 578 Sema::ArgPackSubstIndexRAII SubstIndex; 579 DeclContext *Owner; 580 const MultiLevelTemplateArgumentList &TemplateArgs; 581 Sema::LateInstantiatedAttrVec* LateAttrs = nullptr; 582 LocalInstantiationScope *StartingScope = nullptr; 583 // Whether to evaluate the C++20 constraints or simply substitute into them. 584 bool EvaluateConstraints = true; 585 586 /// A list of out-of-line class template partial 587 /// specializations that will need to be instantiated after the 588 /// enclosing class's instantiation is complete. 589 SmallVector<std::pair<ClassTemplateDecl *, 590 ClassTemplatePartialSpecializationDecl *>, 591 1> 592 OutOfLinePartialSpecs; 593 594 /// A list of out-of-line variable template partial 595 /// specializations that will need to be instantiated after the 596 /// enclosing variable's instantiation is complete. 597 /// FIXME: Verify that this is needed. 598 SmallVector< 599 std::pair<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>, 1> 600 OutOfLineVarPartialSpecs; 601 602 public: TemplateDeclInstantiator(Sema & SemaRef,DeclContext * Owner,const MultiLevelTemplateArgumentList & TemplateArgs)603 TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, 604 const MultiLevelTemplateArgumentList &TemplateArgs) 605 : SemaRef(SemaRef), SubstIndex(SemaRef, SemaRef.ArgPackSubstIndex), 606 Owner(Owner), TemplateArgs(TemplateArgs) {} 607 setEvaluateConstraints(bool B)608 void setEvaluateConstraints(bool B) { 609 EvaluateConstraints = B; 610 } getEvaluateConstraints()611 bool getEvaluateConstraints() { 612 return EvaluateConstraints; 613 } 614 615 // Define all the decl visitors using DeclNodes.inc 616 #define DECL(DERIVED, BASE) \ 617 Decl *Visit ## DERIVED ## Decl(DERIVED ## Decl *D); 618 #define ABSTRACT_DECL(DECL) 619 620 // Decls which never appear inside a class or function. 621 #define OBJCCONTAINER(DERIVED, BASE) 622 #define FILESCOPEASM(DERIVED, BASE) 623 #define TOPLEVELSTMT(DERIVED, BASE) 624 #define IMPORT(DERIVED, BASE) 625 #define EXPORT(DERIVED, BASE) 626 #define LINKAGESPEC(DERIVED, BASE) 627 #define OBJCCOMPATIBLEALIAS(DERIVED, BASE) 628 #define OBJCMETHOD(DERIVED, BASE) 629 #define OBJCTYPEPARAM(DERIVED, BASE) 630 #define OBJCIVAR(DERIVED, BASE) 631 #define OBJCPROPERTY(DERIVED, BASE) 632 #define OBJCPROPERTYIMPL(DERIVED, BASE) 633 #define EMPTY(DERIVED, BASE) 634 #define LIFETIMEEXTENDEDTEMPORARY(DERIVED, BASE) 635 636 // Decls which never appear inside a template. 637 #define OUTLINEDFUNCTION(DERIVED, BASE) 638 639 // Decls which use special-case instantiation code. 640 #define BLOCK(DERIVED, BASE) 641 #define CAPTURED(DERIVED, BASE) 642 #define IMPLICITPARAM(DERIVED, BASE) 643 644 #include "clang/AST/DeclNodes.inc" 645 646 enum class RewriteKind { None, RewriteSpaceshipAsEqualEqual }; 647 648 void adjustForRewrite(RewriteKind RK, FunctionDecl *Orig, QualType &T, 649 TypeSourceInfo *&TInfo, 650 DeclarationNameInfo &NameInfo); 651 652 // A few supplemental visitor functions. 653 Decl *VisitCXXMethodDecl(CXXMethodDecl *D, 654 TemplateParameterList *TemplateParams, 655 RewriteKind RK = RewriteKind::None); 656 Decl *VisitFunctionDecl(FunctionDecl *D, 657 TemplateParameterList *TemplateParams, 658 RewriteKind RK = RewriteKind::None); 659 Decl *VisitDecl(Decl *D); 660 Decl *VisitVarDecl(VarDecl *D, bool InstantiatingVarTemplate, 661 ArrayRef<BindingDecl *> *Bindings = nullptr); 662 Decl *VisitBaseUsingDecls(BaseUsingDecl *D, BaseUsingDecl *Inst, 663 LookupResult *Lookup); 664 665 // Enable late instantiation of attributes. Late instantiated attributes 666 // will be stored in LA. enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec * LA)667 void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) { 668 LateAttrs = LA; 669 StartingScope = SemaRef.CurrentInstantiationScope; 670 } 671 672 // Disable late instantiation of attributes. disableLateAttributeInstantiation()673 void disableLateAttributeInstantiation() { 674 LateAttrs = nullptr; 675 StartingScope = nullptr; 676 } 677 getStartingScope()678 LocalInstantiationScope *getStartingScope() const { return StartingScope; } 679 680 using delayed_partial_spec_iterator = SmallVectorImpl<std::pair< 681 ClassTemplateDecl *, ClassTemplatePartialSpecializationDecl *>>::iterator; 682 683 using delayed_var_partial_spec_iterator = SmallVectorImpl<std::pair< 684 VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>>::iterator; 685 686 /// Return an iterator to the beginning of the set of 687 /// "delayed" partial specializations, which must be passed to 688 /// InstantiateClassTemplatePartialSpecialization once the class 689 /// definition has been completed. delayed_partial_spec_begin()690 delayed_partial_spec_iterator delayed_partial_spec_begin() { 691 return OutOfLinePartialSpecs.begin(); 692 } 693 delayed_var_partial_spec_begin()694 delayed_var_partial_spec_iterator delayed_var_partial_spec_begin() { 695 return OutOfLineVarPartialSpecs.begin(); 696 } 697 698 /// Return an iterator to the end of the set of 699 /// "delayed" partial specializations, which must be passed to 700 /// InstantiateClassTemplatePartialSpecialization once the class 701 /// definition has been completed. delayed_partial_spec_end()702 delayed_partial_spec_iterator delayed_partial_spec_end() { 703 return OutOfLinePartialSpecs.end(); 704 } 705 delayed_var_partial_spec_end()706 delayed_var_partial_spec_iterator delayed_var_partial_spec_end() { 707 return OutOfLineVarPartialSpecs.end(); 708 } 709 710 // Helper functions for instantiating methods. 711 TypeSourceInfo *SubstFunctionType(FunctionDecl *D, 712 SmallVectorImpl<ParmVarDecl *> &Params); 713 bool InitFunctionInstantiation(FunctionDecl *New, FunctionDecl *Tmpl); 714 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); 715 716 bool SubstDefaultedFunction(FunctionDecl *New, FunctionDecl *Tmpl); 717 718 TemplateParameterList * 719 SubstTemplateParams(TemplateParameterList *List); 720 721 bool SubstQualifier(const DeclaratorDecl *OldDecl, 722 DeclaratorDecl *NewDecl); 723 bool SubstQualifier(const TagDecl *OldDecl, 724 TagDecl *NewDecl); 725 726 Decl *VisitVarTemplateSpecializationDecl( 727 VarTemplateDecl *VarTemplate, VarDecl *FromVar, 728 const TemplateArgumentListInfo &TemplateArgsInfo, 729 ArrayRef<TemplateArgument> Converted, 730 VarTemplateSpecializationDecl *PrevDecl = nullptr); 731 732 Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); 733 Decl *InstantiateTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); 734 ClassTemplatePartialSpecializationDecl * 735 InstantiateClassTemplatePartialSpecialization( 736 ClassTemplateDecl *ClassTemplate, 737 ClassTemplatePartialSpecializationDecl *PartialSpec); 738 VarTemplatePartialSpecializationDecl * 739 InstantiateVarTemplatePartialSpecialization( 740 VarTemplateDecl *VarTemplate, 741 VarTemplatePartialSpecializationDecl *PartialSpec); 742 void InstantiateEnumDefinition(EnumDecl *Enum, EnumDecl *Pattern); 743 744 private: 745 template<typename T> 746 Decl *instantiateUnresolvedUsingDecl(T *D, 747 bool InstantiatingPackElement = false); 748 }; 749 750 } // namespace clang 751 752 #endif // LLVM_CLANG_SEMA_TEMPLATE_H 753