diff options
Diffstat (limited to 'include/clang/Sema/Template.h')
-rw-r--r-- | include/clang/Sema/Template.h | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index 401bbbf1e5661..644d55b93f1b1 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -46,6 +46,10 @@ namespace clang { /// \brief The template argument lists, stored from the innermost template /// argument list (first) to the outermost template argument list (last). SmallVector<ArgList, 4> TemplateArgumentLists; + + /// \brief The number of outer levels of template arguments that are not + /// being substituted. + unsigned NumRetainedOuterLevels = 0; public: /// \brief Construct an empty set of template argument lists. @@ -59,11 +63,19 @@ namespace clang { /// \brief Determine the number of levels in this template argument /// list. - unsigned getNumLevels() const { return TemplateArgumentLists.size(); } - + unsigned getNumLevels() const { + return TemplateArgumentLists.size() + NumRetainedOuterLevels; + } + + /// \brief Determine the number of substituted levels in this template + /// argument list. + unsigned getNumSubstitutedLevels() const { + return TemplateArgumentLists.size(); + } + /// \brief Retrieve the template argument at a given depth and index. const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { - assert(Depth < TemplateArgumentLists.size()); + assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); return TemplateArgumentLists[getNumLevels() - Depth - 1][Index]; } @@ -73,7 +85,10 @@ namespace clang { /// /// There must exist a template argument list at the given depth. bool hasTemplateArgument(unsigned Depth, unsigned Index) const { - assert(Depth < TemplateArgumentLists.size()); + assert(Depth < getNumLevels()); + + if (Depth < NumRetainedOuterLevels) + return false; if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size()) return false; @@ -84,7 +99,7 @@ namespace clang { /// \brief Clear out a specific template argument. void setArgument(unsigned Depth, unsigned Index, TemplateArgument Arg) { - assert(Depth < TemplateArgumentLists.size()); + assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); const_cast<TemplateArgument&>( TemplateArgumentLists[getNumLevels() - Depth - 1][Index]) @@ -101,9 +116,18 @@ namespace clang { /// \brief Add a new outmost level to the multi-level template argument /// list. void addOuterTemplateArguments(ArgList Args) { + assert(!NumRetainedOuterLevels && + "substituted args outside retained args?"); TemplateArgumentLists.push_back(Args); } + /// \brief Add an outermost level that we are not substituting. We have no + /// arguments at this level, and do not remove it from the depth of inner + /// template parameters that we instantiate. + void addOuterRetainedLevel() { + ++NumRetainedOuterLevels; + } + /// \brief Retrieve the innermost template argument list. const ArgList &getInnermost() const { return TemplateArgumentLists.front(); |