Implement template instantiation for member class templates.
When performing template instantiation of the definitions of member
templates (or members thereof), we build a data structure containing
the template arguments from each "level" of template
instantiation. During template instantiation, we substitute all levels
of template arguments simultaneously.
llvm-svn: 80389
diff --git a/clang/lib/Sema/SemaTemplate.h b/clang/lib/Sema/SemaTemplate.h
index 3f814e4..183b5a3 100644
--- a/clang/lib/Sema/SemaTemplate.h
+++ b/clang/lib/Sema/SemaTemplate.h
@@ -46,8 +46,8 @@
MultiLevelTemplateArgumentList() { }
/// \brief Construct a single-level template argument list.
- MultiLevelTemplateArgumentList(const TemplateArgumentList *TemplateArgs) {
- TemplateArgumentLists.push_back(TemplateArgs);
+ MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
+ TemplateArgumentLists.push_back(&TemplateArgs);
}
/// \brief Determine the number of levels in this template argument
@@ -57,8 +57,21 @@
/// \brief Retrieve the template argument at a given depth and index.
const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
assert(Depth < TemplateArgumentLists.size());
- assert(Index < TemplateArgumentLists[getNumLevels() - Depth]->size());
- return TemplateArgumentLists[getNumLevels() - Depth]->get(Index);
+ assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1]->size());
+ return TemplateArgumentLists[getNumLevels() - Depth - 1]->get(Index);
+ }
+
+ /// \brief Determine whether there is a non-NULL template argument at the
+ /// given depth and index.
+ ///
+ /// There must exist a template argument list at the given depth.
+ bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
+ assert(Depth < TemplateArgumentLists.size());
+
+ if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1]->size())
+ return false;
+
+ return !(*this)(Depth, Index).isNull();
}
/// \brief Add a new outermost level to the multi-level template argument
@@ -67,6 +80,11 @@
TemplateArgumentLists.push_back(TemplateArgs);
}
+ /// \brief Retrieve the innermost template argument list.
+ const TemplateArgumentList &getInnermost() const {
+ return *TemplateArgumentLists.front();
+ }
+
// Implicit conversion to a single template argument list, to facilitate a
// gradual transition to MultiLevelTemplateArgumentLists.
operator const TemplateArgumentList &() const {