C++ PATCH for member class templates
Mark Mitchell
mark@codesourcery.com
Sat Apr 10 10:50:00 GMT 1999
This patch fixes a situation where we could get confused by member
class templates in a specialization of a template class.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
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.
Index: testsuite/g++.old-deja/g++.pt/memclass20.C
===================================================================
RCS file: memclass20.C
diff -N memclass20.C
*** /dev/null Sat Dec 5 20:30:03 1998
--- memclass20.C Sat Apr 10 10:44:48 1999
***************
*** 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>();
Index: testsuite/g++.old-deja/cp/error.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/error.c,v
retrieving revision 1.72
diff -c -p -r1.72 error.c
*** error.c 1999/04/08 20:16:51 1.72
--- error.c 1999/04/10 17:44:58
*************** dump_type_real (t, v, canonical_name)
*** 321,327 ****
OB_PUTS ("typename ");
dump_type_real (TYPE_CONTEXT (t), 0, canonical_name);
OB_PUTS ("::");
! OB_PUTID (TYPE_IDENTIFIER (t));
break;
case TYPEOF_TYPE:
--- 321,327 ----
OB_PUTS ("typename ");
dump_type_real (TYPE_CONTEXT (t), 0, canonical_name);
OB_PUTS ("::");
! dump_decl (TYPENAME_TYPE_FULLNAME (t), v);
break;
case TYPEOF_TYPE:
*************** dump_expr (t, nop)
*** 1764,1769 ****
--- 1764,1773 ----
case WITH_CLEANUP_EXPR:
case CLEANUP_POINT_EXPR:
dump_expr (TREE_OPERAND (t, 0), nop);
+ break;
+
+ case TEMPLATE_ID_EXPR:
+ dump_decl (t, 0);
break;
case TREE_LIST:
Index: testsuite/g++.old-deja/cp/pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.280
diff -c -p -r1.280 pt.c
*** pt.c 1999/04/05 01:34:46 1.280
--- pt.c 1999/04/10 17:45:04
*************** lookup_template_class (d1, arglist, in_d
*** 3650,3663 ****
else
{
tree template_type = TREE_TYPE (template);
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);
parm_depth = TMPL_PARMS_DEPTH (parmlist);
arg_depth = TMPL_ARGS_DEPTH (arglist);
--- 3650,3664 ----
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;
! gen_tmpl = most_general_template (template);
! parmlist = DECL_TEMPLATE_PARMS (gen_tmpl);
parm_depth = TMPL_PARMS_DEPTH (parmlist);
arg_depth = TMPL_ARGS_DEPTH (arglist);
*************** lookup_template_class (d1, arglist, in_d
*** 3679,3714 ****
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);
arg_depth = TMPL_ARGS_DEPTH (arglist);
}
my_friendly_assert (parm_depth == arg_depth, 0);
/* Calculate the BOUND_ARGS. These will be the args that are
actually tsubst'd into the definition to create the
instantiation. */
--- 3680,3698 ----
TEMPLATE will be `template <class T> template
<class U> struct S1<T>::S2'. We must fill in the missing
arguments. */
! 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. */
More information about the Gcc-patches
mailing list