diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c64951ac7f140c9f452f52d43685361fbea691b..4d1db9c800ed4c73ee1d3f752319aa5f2c4c5300 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +1999-04-10 Mark Mitchell <mark@codesourcery.com> + + * error.c (dump_type_real): If a typename is a template-id, put + out the template arguments. + (dump_expr): Handle TEMPLATE_ID_EXPR. + * pt.c (lookup_template_class): Now that full arguments are + available everywhere, remove code that tried to guess them. + 1999-04-09 Mark Mitchell <mark@codesourcery.com> * decl.c (make_typename_type): Complain if we don't find a type diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 055f92accb0eddbcf810c8b7c524677f9d5893c5..025e9329797014d85e5ca406c8436cc5c80cff7b 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -321,7 +321,7 @@ dump_type_real (t, v, canonical_name) OB_PUTS ("typename "); dump_type_real (TYPE_CONTEXT (t), 0, canonical_name); OB_PUTS ("::"); - OB_PUTID (TYPE_IDENTIFIER (t)); + dump_decl (TYPENAME_TYPE_FULLNAME (t), v); break; case TYPEOF_TYPE: @@ -1766,6 +1766,10 @@ dump_expr (t, nop) dump_expr (TREE_OPERAND (t, 0), nop); break; + case TEMPLATE_ID_EXPR: + dump_decl (t, 0); + break; + case TREE_LIST: if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL) { diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a4060c0c4b8685877a3b40c6369788373a4f6a50..154ee1bf3de85062e2d610b68b76d53dd623ca68 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3568,9 +3568,9 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) if (context) push_decl_namespace (context); if (current_class_type != NULL_TREE) - template = + template = maybe_get_template_decl_from_type_decl - (IDENTIFIER_CLASS_VALUE (d1)); + (IDENTIFIER_CLASS_VALUE (d1))); if (template == NULL_TREE) template = lookup_name_nonclass (d1); if (context) @@ -3650,14 +3650,15 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) else { tree template_type = TREE_TYPE (template); + tree gen_tmpl; tree type_decl; tree found = NULL_TREE; int arg_depth; int parm_depth; int is_partial_instantiation; - template = most_general_template (template); - parmlist = DECL_TEMPLATE_PARMS (template); + gen_tmpl = most_general_template (template); + parmlist = DECL_TEMPLATE_PARMS (gen_tmpl); parm_depth = TMPL_PARMS_DEPTH (parmlist); arg_depth = TMPL_ARGS_DEPTH (arglist); @@ -3679,36 +3680,19 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope) TEMPLATE will be `template <class T> template <class U> struct S1<T>::S2'. We must fill in the missing arguments. */ - my_friendly_assert (context != NULL_TREE, 0); - while (!IS_AGGR_TYPE_CODE (TREE_CODE (context)) - && context != global_namespace) - context = DECL_REAL_CONTEXT (context); - - if (context == global_namespace) - /* This is bad. We cannot get enough arguments, even from - the surrounding context, to resolve this class. One - case where this might happen is (illegal) code like: - - template <class U> - template <class T> - struct S { - A(const A<T>& a) {} - }; - - We should catch this error sooner (at the opening curly - for `S', but it is better to be safe than sorry here. */ - { - cp_error ("invalid use of `%D'", template); - return error_mark_node; - } - - arglist = add_to_template_args (TYPE_TI_ARGS (context), - arglist); + arglist + = add_outermost_template_args (TYPE_TI_ARGS (TREE_TYPE (template)), + arglist); arg_depth = TMPL_ARGS_DEPTH (arglist); } + /* Now we should enough arguments. */ my_friendly_assert (parm_depth == arg_depth, 0); + /* From here on, we're only interested in the most general + template. */ + template = gen_tmpl; + /* Calculate the BOUND_ARGS. These will be the args that are actually tsubst'd into the definition to create the instantiation. */ diff --git a/gcc/testsuite/g++.old-deja/g++.pt/memclass20.C b/gcc/testsuite/g++.old-deja/g++.pt/memclass20.C new file mode 100644 index 0000000000000000000000000000000000000000..c57c27dfe098ec1842c2cdad82c2bddebd553ce1 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/memclass20.C @@ -0,0 +1,18 @@ +// Build don't link: +// Origin: Mark Mitchell <mark@codesourcery.com> + +template <class X, class Y> +struct S{}; + +template <class X> +struct S<int, X> { + template <class W> + struct I {}; +}; + +template <class T> +void f() { + typename S<T, T>::I<T> si; +} + +template void f<int>();