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