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