aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-06-11 23:53:24 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-06-11 23:53:24 +0000
commit2ee4e084b7b20e4da9bbab88fe862932059d1524 (patch)
tree53de487a5e93cf13ec48b9c1d21ff1ee24063571
parent9bc6d2c2070cccaaa5f0c129bd7b27bdb728af27 (diff)
downloadgcc-2ee4e084b7b20e4da9bbab88fe862932059d1524.zip
gcc-2ee4e084b7b20e4da9bbab88fe862932059d1524.tar.gz
gcc-2ee4e084b7b20e4da9bbab88fe862932059d1524.tar.bz2
pt.c (is_member_template_class): New function.
* pt.c (is_member_template_class): New function. (push_template_decl_real): Use it. From-SVN: r20435
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/pt.c33
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/memclass12.C6
3 files changed, 41 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d02ae09..5539b4c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+1998-06-11 Mark Mitchell <mark@markmitchell.com>
+
+ * pt.c (is_member_template_class): New function.
+ (push_template_decl_real): Use it.
+
1998-06-11 Benjamin Kosnik <bkoz@elmo.cygnus.com>
* friend.c (do_friend): Add support for nested classes using
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2a06dab..537361e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -115,6 +115,7 @@ static tree maybe_get_template_decl_from_type_decl PROTO((tree));
static int check_cv_quals_for_unify PROTO((int, tree, tree));
static tree tsubst_template_arg_vector PROTO((tree, tree));
static void regenerate_decl_from_template PROTO((tree, tree));
+static int is_member_template_class PROTO((tree));
/* Nonzero if ARGVEC contains multiple levels of template arguments. */
#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \
@@ -378,6 +379,31 @@ is_member_template (t)
return 0;
}
+/* Returns non-zero iff T is a member template class. See
+ is_member_template for a description of what precisely constitutes
+ a member template. */
+
+int
+is_member_template_class (t)
+ tree t;
+{
+ if (!DECL_CLASS_TEMPLATE_P (t))
+ /* Anything that isn't a class template, is certainly not a member
+ template. */
+ return 0;
+
+ if (!DECL_CLASS_SCOPE_P (t))
+ /* Anything whose context isn't a class type is surely not a
+ member template. */
+ return 0;
+
+ /* If there are more levels of template parameters than there are
+ template classes surrounding the declaration, then we have a
+ member template. */
+ return (list_length (DECL_TEMPLATE_PARMS (t)) >
+ template_class_depth (DECL_CONTEXT (t)));
+}
+
/* Return a new template argument vector which contains all of ARGS
for all outer templates TMPL is contained in, but has as its
innermost set of arguments the EXTRA_ARGS. If UNBOUND_ONLY, we
@@ -1784,9 +1810,10 @@ push_template_decl_real (decl, is_friend)
else
tmpl = DECL_TI_TEMPLATE (decl);
- if (is_member_template (tmpl))
+ if (is_member_template (tmpl) || is_member_template_class (tmpl))
{
- if (DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
+ if (DECL_FUNCTION_TEMPLATE_P (tmpl)
+ && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl)
&& DECL_TEMPLATE_SPECIALIZATION (decl))
{
tree new_tmpl;
@@ -1812,7 +1839,7 @@ push_template_decl_real (decl, is_friend)
}
a = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
- t = DECL_INNERMOST_TEMPLATE_PARMS (DECL_TI_TEMPLATE (decl));
+ t = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a))
{
cp_error ("got %d template parameters for `%#D'",
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass12.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass12.C
new file mode 100644
index 0000000..f4d0354
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass12.C
@@ -0,0 +1,6 @@
+// Build don't link:
+
+struct outer {
+ template <class T> struct inner;
+} o;
+template <class T> struct outer::inner {};