Home | History | Annotate | Line # | Download | only in Sema
      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
     96     MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
     97       addOuterTemplateArguments(&TemplateArgs);
     98     }
     99 
    100     void setKind(TemplateSubstitutionKind K) { Kind = K; }
    101 
    102     /// Determine the kind of template substitution being performed.
    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.
    108     bool isRewrite() const {
    109       return Kind == TemplateSubstitutionKind::Rewrite;
    110     }
    111 
    112     /// Determine the number of levels in this template argument
    113     /// list.
    114     unsigned getNumLevels() const {
    115       return TemplateArgumentLists.size() + NumRetainedOuterLevels;
    116     }
    117 
    118     /// Determine the number of substituted levels in this template
    119     /// argument list.
    120     unsigned getNumSubstitutedLevels() const {
    121       return TemplateArgumentLists.size();
    122     }
    123 
    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.
    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.
    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.
    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.
    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.
    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.
    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.
    189     void addOuterRetainedLevel() {
    190       ++NumRetainedOuterLevels;
    191     }
    192     void addOuterRetainedLevels(unsigned Num) {
    193       NumRetainedOuterLevels += Num;
    194     }
    195 
    196     /// Retrieve the innermost template argument list.
    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:
    225     TemplatePartialOrderingContext(TPOC Value) : Value(Value) {}
    226 
    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)
    242         : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) {}
    243 
    244     /// Construct an integral non-type template argument that
    245     /// has been deduced, possibly from an array bound.
    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.
    255     bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
    256 
    257     /// Specify whether the given non-type template argument
    258     /// was deduced from an array bound.
    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)
    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 
    343     ~LocalInstantiationScope() {
    344       Exit();
    345     }
    346 
    347     const Sema &getSema() const { return SemaRef; }
    348 
    349     /// Exit this local instantiation scope early.
    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.
    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.
    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.
    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:
    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.
    543     void enableLateAttributeInstantiation(Sema::LateInstantiatedAttrVec *LA) {
    544       LateAttrs = LA;
    545       StartingScope = SemaRef.CurrentInstantiationScope;
    546     }
    547 
    548     // Disable late instantiation of attributes.
    549     void disableLateAttributeInstantiation() {
    550       LateAttrs = nullptr;
    551       StartingScope = nullptr;
    552     }
    553 
    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.
    566     delayed_partial_spec_iterator delayed_partial_spec_begin() {
    567       return OutOfLinePartialSpecs.begin();
    568     }
    569 
    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.
    578     delayed_partial_spec_iterator delayed_partial_spec_end() {
    579       return OutOfLinePartialSpecs.end();
    580     }
    581 
    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