diff options
Diffstat (limited to 'clang/include/clang/Sema/Template.h')
-rw-r--r-- | clang/include/clang/Sema/Template.h | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index 4c1cfecd4de6..91d175fdd050 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -42,6 +42,17 @@ class TypedefNameDecl; class TypeSourceInfo; class VarDecl; +/// The kind of template substitution being performed. +enum class TemplateSubstitutionKind : char { + /// We are substituting template parameters for template arguments in order + /// to form a template specialization. + Specialization, + /// We are substituting template parameters for (typically) other template + /// parameters in order to rewrite a declaration as a different declaration + /// (for example, when forming a deduction guide from a constructor). + Rewrite, +}; + /// Data structure that captures multiple levels of template argument /// lists for use in template instantiation. /// @@ -73,6 +84,9 @@ class VarDecl; /// being substituted. unsigned NumRetainedOuterLevels = 0; + /// The kind of substitution described by this argument list. + TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization; + public: /// Construct an empty set of template argument lists. MultiLevelTemplateArgumentList() = default; @@ -83,6 +97,18 @@ class VarDecl; addOuterTemplateArguments(&TemplateArgs); } + void setKind(TemplateSubstitutionKind K) { Kind = K; } + + /// Determine the kind of template substitution being performed. + TemplateSubstitutionKind getKind() const { return Kind; } + + /// Determine whether we are rewriting template parameters rather than + /// substituting for them. If so, we should not leave references to the + /// original template parameters behind. + bool isRewrite() const { + return Kind == TemplateSubstitutionKind::Rewrite; + } + /// Determine the number of levels in this template argument /// list. unsigned getNumLevels() const { @@ -95,6 +121,20 @@ class VarDecl; return TemplateArgumentLists.size(); } + unsigned getNumRetainedOuterLevels() const { + return NumRetainedOuterLevels; + } + + /// Determine how many of the \p OldDepth outermost template parameter + /// lists would be removed by substituting these arguments. + unsigned getNewDepth(unsigned OldDepth) const { + if (OldDepth < NumRetainedOuterLevels) + return OldDepth; + if (OldDepth < getNumLevels()) + return NumRetainedOuterLevels; + return OldDepth - TemplateArgumentLists.size(); + } + /// Retrieve the template argument at a given depth and index. const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); @@ -149,6 +189,9 @@ class VarDecl; void addOuterRetainedLevel() { ++NumRetainedOuterLevels; } + void addOuterRetainedLevels(unsigned Num) { + NumRetainedOuterLevels += Num; + } /// Retrieve the innermost template argument list. const ArgList &getInnermost() const { @@ -412,6 +455,9 @@ class VarDecl; NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, unsigned *NumExplicitArgs = nullptr) const; + + /// Determine whether D is a pack expansion created in this scope. + bool isLocalPackExpansion(const Decl *D); }; class TemplateDeclInstantiator |