Patch for more template problems
Mark Mitchell
mmitchell@usa.net
Mon Feb 9 23:22:00 GMT 1998
Here's a patch for a two small template problems:
o Templates declarations using default arguments were clobbered
by subsequent definitions without the default arguments. This
made some uses of getline fail.
o Nested classes within partial specializations didn't work.
There are also a couple of test-case patches that I neglected to send with
earlier patches.
--
Mark Mitchell mmitchell@usa.net
Stanford University http://www.stanford.edu
Mon Feb 9 22:23:31 1998 Mark Mitchell <mmitchell@usa.net>
* cp-tree.h (push_template_decl): Return the decl passed in, or an
equivalent duplicate.
* decl2.c (grokfield): Use it.
* parse.y (named_class_head): Likewise.
(left_curly): Likewise.
* decl.c (pushtag): Likewise.
(shadow_tag): Likewise.
(start_decl): Likewise.
(start_function): Likewise.
(start_method): Likewise.
(duplicate_decls): When duplicating a template declaration, merge
the DECL_TEMPLATE_RESULTs as well.
(make_implicit_typename): Don't try to dive into typename types to
find a context for making a new implicit typename.
* pt.c (push_template_decl): Return the decl passed in, or an
equivalent duplicate.
(lookup_template_class): When searching in a nested context,
use the right arguments.
(uses_template_parms): Handle the DECL_INITIAL for a CONST_DECL.
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.13
diff -c -p -r1.13 cp-tree.h
*** cp-tree.h 1998/01/30 00:53:42 1.13
--- cp-tree.h 1998/02/10 05:25:03
*************** extern tree process_template_parm PROTO
*** 2346,2352 ****
extern tree end_template_parm_list PROTO((tree));
extern void end_template_decl PROTO((void));
extern tree current_template_args PROTO((void));
! extern void push_template_decl PROTO((tree));
extern tree lookup_template_class PROTO((tree, tree, tree, tree));
extern tree lookup_template_function PROTO((tree, tree));
extern int uses_template_parms PROTO((tree));
--- 2346,2352 ----
extern tree end_template_parm_list PROTO((tree));
extern void end_template_decl PROTO((void));
extern tree current_template_args PROTO((void));
! extern tree push_template_decl PROTO((tree));
extern tree lookup_template_class PROTO((tree, tree, tree, tree));
extern tree lookup_template_function PROTO((tree, tree));
extern int uses_template_parms PROTO((tree));
Index: gcc/cp/decl.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/decl.c,v
retrieving revision 1.21
diff -c -p -r1.21 decl.c
*** decl.c 1998/01/30 00:53:44 1.21
--- decl.c 1998/02/10 06:34:27
*************** pushtag (name, type, globalize)
*** 2142,2148 ****
TYPE_NAME (type) = d;
DECL_CONTEXT (d) = context;
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
! push_template_decl (d);
if (b->parm_flag == 2)
d = pushdecl_class_level (d);
--- 2142,2148 ----
TYPE_NAME (type) = d;
DECL_CONTEXT (d) = context;
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
! d = push_template_decl (d);
if (b->parm_flag == 2)
d = pushdecl_class_level (d);
*************** pushtag (name, type, globalize)
*** 2158,2164 ****
TYPE_NAME (type) = d;
DECL_CONTEXT (d) = context;
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
! push_template_decl (d);
d = pushdecl_class_level (d);
}
--- 2158,2164 ----
TYPE_NAME (type) = d;
DECL_CONTEXT (d) = context;
if (! globalize && processing_template_decl && IS_AGGR_TYPE (type))
! d = push_template_decl (d);
d = pushdecl_class_level (d);
}
*************** duplicate_decls (newdecl, olddecl)
*** 2757,2764 ****
{
if (DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)) == NULL_TREE)
{
! TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
! DECL_TEMPLATE_RESULT (olddecl) = DECL_TEMPLATE_RESULT (newdecl);
DECL_TEMPLATE_PARMS (olddecl) = DECL_TEMPLATE_PARMS (newdecl);
}
return 1;
--- 2757,2766 ----
{
if (DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)) == NULL_TREE)
{
! if (! duplicate_decls (DECL_TEMPLATE_RESULT (newdecl),
! DECL_TEMPLATE_RESULT (olddecl)))
! cp_error ("invalid redeclaration of %D", newdecl);
! TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl));
DECL_TEMPLATE_PARMS (olddecl) = DECL_TEMPLATE_PARMS (newdecl);
}
return 1;
*************** make_implicit_typename (context, t)
*** 4466,4472 ****
{
tree retval;
! if (uses_template_parms (DECL_CONTEXT (t))
&& DECL_CONTEXT (t) != context)
{
tree binfo = get_binfo (DECL_CONTEXT (t), context, 0);
--- 4468,4475 ----
{
tree retval;
! if (TREE_CODE (context) != TYPENAME_TYPE
! && uses_template_parms (DECL_CONTEXT (t))
&& DECL_CONTEXT (t) != context)
{
tree binfo = get_binfo (DECL_CONTEXT (t), context, 0);
*************** shadow_tag (declspecs)
*** 5852,5858 ****
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (value);
if (processing_template_decl)
! push_template_decl (TYPE_MAIN_DECL (value));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (value))
cp_error ("specialization after instantiation of `%T'", value);
--- 5855,5862 ----
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (value);
if (processing_template_decl)
! TYPE_MAIN_DECL (value)
! = push_template_decl (TYPE_MAIN_DECL (value));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (value))
cp_error ("specialization after instantiation of `%T'", value);
*************** start_decl (declarator, declspecs, initi
*** 6161,6167 ****
if (processing_template_decl)
{
if (! current_function_decl)
! push_template_decl (tem);
else if (minimal_parse_mode)
DECL_VINDEX (decl)
= build_min_nt (DECL_STMT, copy_to_permanent (declarator),
--- 6165,6171 ----
if (processing_template_decl)
{
if (! current_function_decl)
! tem = push_template_decl (tem);
else if (minimal_parse_mode)
DECL_VINDEX (decl)
= build_min_nt (DECL_STMT, copy_to_permanent (declarator),
*************** start_function (declspecs, declarator, a
*** 11637,11643 ****
use the old decl. */
if (processing_template_decl)
! push_template_decl (decl1);
else if (pre_parsed_p == 0)
{
/* A specialization is not used to guide overload resolution. */
--- 11641,11647 ----
use the old decl. */
if (processing_template_decl)
! decl1 = push_template_decl (decl1);
else if (pre_parsed_p == 0)
{
/* A specialization is not used to guide overload resolution. */
*************** start_method (declspecs, declarator)
*** 12688,12694 ****
DECL_INLINE (fndecl) = 1;
if (processing_template_decl)
! push_template_decl (fndecl);
/* We read in the parameters on the maybepermanent_obstack,
but we won't be getting back to them until after we
--- 12692,12698 ----
DECL_INLINE (fndecl) = 1;
if (processing_template_decl)
! fndecl = push_template_decl (fndecl);
/* We read in the parameters on the maybepermanent_obstack,
but we won't be getting back to them until after we
Index: gcc/cp/decl2.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/decl2.c,v
retrieving revision 1.11
diff -c -p -r1.11 decl2.c
*** decl2.c 1998/02/03 07:19:18 1.11
--- decl2.c 1998/02/10 05:35:37
*************** grokfield (declarator, declspecs, init,
*** 1678,1684 ****
if (processing_template_decl && ! current_function_decl
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
! push_template_decl (value);
if (attrlist)
cplus_decl_attributes (value, TREE_PURPOSE (attrlist),
--- 1678,1684 ----
if (processing_template_decl && ! current_function_decl
&& (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL))
! value = push_template_decl (value);
if (attrlist)
cplus_decl_attributes (value, TREE_PURPOSE (attrlist),
Index: gcc/cp/parse.y
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/parse.y,v
retrieving revision 1.14
diff -c -p -r1.14 parse.y
*** parse.y 1998/02/03 04:44:14 1.14
--- parse.y 1998/02/10 06:27:26
*************** named_class_head:
*** 2474,2480 ****
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$);
if (processing_template_decl)
! push_template_decl (TYPE_MAIN_DECL ($$));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$))
cp_error ("specialization after instantiation of `%T'", $$);
--- 2474,2481 ----
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$);
if (processing_template_decl)
! TYPE_MAIN_DECL ($$)
! = push_template_decl (TYPE_MAIN_DECL ($$));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$))
cp_error ("specialization after instantiation of `%T'", $$);
*************** left_curly:
*** 2676,2682 ****
}
if (processing_template_decl && TYPE_CONTEXT (t)
&& ! current_class_type)
! push_template_decl (TYPE_STUB_DECL (t));
pushclass (t, 0);
TYPE_BEING_DEFINED (t) = 1;
if (IS_AGGR_TYPE (t) && CLASSTYPE_USE_TEMPLATE (t))
--- 2677,2684 ----
}
if (processing_template_decl && TYPE_CONTEXT (t)
&& ! current_class_type)
! TYPE_STUB_DECL (t)
! = push_template_decl (TYPE_STUB_DECL (t));
pushclass (t, 0);
TYPE_BEING_DEFINED (t) = 1;
if (IS_AGGR_TYPE (t) && CLASSTYPE_USE_TEMPLATE (t))
*************** left_curly:
*** 2686,2692 ****
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t);
if (processing_template_decl)
! push_template_decl (TYPE_MAIN_DECL (t));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
cp_error ("specialization after instantiation of `%T'", t);
--- 2688,2695 ----
{
SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (t);
if (processing_template_decl)
! TYPE_MAIN_DECL (t)
! = push_template_decl (TYPE_MAIN_DECL (t));
}
else if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
cp_error ("specialization after instantiation of `%T'", t);
Index: gcc/cp/pt.c
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/cp/pt.c,v
retrieving revision 1.22
diff -c -p -r1.22 pt.c
*** pt.c 1998/02/03 04:44:15 1.22
--- pt.c 1998/02/10 06:36:45
*************** build_template_decl (decl, parms)
*** 1200,1206 ****
}
! void
push_template_decl (decl)
tree decl;
{
--- 1200,1211 ----
}
! /* Creates a TEMPLATE_DECL for the indicated DECL using the template
! parameters given by current_template_args, or reuses a previously
! existing one, if appropriate. Returns the DECL, or an equivalent
! one, if it is replaced via a call to duplicate_decls. */
!
! tree
push_template_decl (decl)
tree decl;
{
*************** push_template_decl (decl)
*** 1235,1248 ****
/* purpose: args to main template
value: spec template */
if (comp_template_args (TREE_PURPOSE (spec), mainargs))
! return;
}
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = CLASSTYPE_TI_SPEC_INFO (type)
= perm_tree_cons (mainargs, TREE_VALUE (current_template_parms),
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
! return;
}
args = current_template_args ();
--- 1240,1253 ----
/* purpose: args to main template
value: spec template */
if (comp_template_args (TREE_PURPOSE (spec), mainargs))
! return decl;
}
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = CLASSTYPE_TI_SPEC_INFO (type)
= perm_tree_cons (mainargs, TREE_VALUE (current_template_parms),
DECL_TEMPLATE_SPECIALIZATIONS (maintmpl));
TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type;
! return decl;
}
args = current_template_args ();
*************** push_template_decl (decl)
*** 1275,1281 ****
else if (! DECL_TEMPLATE_INFO (decl))
{
cp_error ("template definition of non-template `%#D'", decl);
! return;
}
else
tmpl = DECL_TI_TEMPLATE (decl);
--- 1280,1286 ----
else if (! DECL_TEMPLATE_INFO (decl))
{
cp_error ("template definition of non-template `%#D'", decl);
! return decl;
}
else
tmpl = DECL_TI_TEMPLATE (decl);
*************** push_template_decl (decl)
*** 1304,1310 ****
perm_tree_cons (tmpl, args, NULL_TREE);
register_specialization (new_tmpl, tmpl, args);
! return;
}
a = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
--- 1309,1315 ----
perm_tree_cons (tmpl, args, NULL_TREE);
register_specialization (new_tmpl, tmpl, args);
! return decl;
}
a = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1);
*************** push_template_decl (decl)
*** 1374,1379 ****
--- 1379,1386 ----
cp_error ("template declaration of `%#D'", decl);
else
DECL_TEMPLATE_INFO (decl) = info;
+
+ return DECL_TEMPLATE_RESULT (tmpl);
}
*************** lookup_template_class (d1, arglist, in_d
*** 2360,2367 ****
}
else
{
! tree ctx = lookup_template_class (TYPE_CONTEXT (TREE_TYPE (template)),
! arglist, in_decl, NULL_TREE);
id = d1;
arglist = CLASSTYPE_TI_ARGS (ctx);
--- 2367,2379 ----
}
else
{
! tree type_ctx = TYPE_CONTEXT (TREE_TYPE (template));
! tree args = tsubst (CLASSTYPE_TI_ARGS (type_ctx),
! arglist,
! TREE_VEC_LENGTH (arglist),
! in_decl);
! tree ctx = lookup_template_class (type_ctx, args,
! in_decl, NULL_TREE);
id = d1;
arglist = CLASSTYPE_TI_ARGS (ctx);
*************** uses_template_parms (t)
*** 2490,2495 ****
--- 2502,2512 ----
parameter */
return 0;
+ case CONST_DECL:
+ if (uses_template_parms (DECL_INITIAL (t)))
+ return 1;
+ goto check_type_and_context;
+
case FUNCTION_DECL:
case VAR_DECL:
/* ??? What about FIELD_DECLs? */
*************** uses_template_parms (t)
*** 2497,2504 ****
&& uses_template_parms (DECL_TI_ARGS (t)))
return 1;
/* fall through */
- case CONST_DECL:
case PARM_DECL:
if (uses_template_parms (TREE_TYPE (t)))
return 1;
if (DECL_CONTEXT (t) && uses_template_parms (DECL_CONTEXT (t)))
--- 2514,2521 ----
&& uses_template_parms (DECL_TI_ARGS (t)))
return 1;
/* fall through */
case PARM_DECL:
+ check_type_and_context:
if (uses_template_parms (TREE_TYPE (t)))
return 1;
if (DECL_CONTEXT (t) && uses_template_parms (DECL_CONTEXT (t)))
cvs diff: Diffing gcc/cp/inc
cvs diff: Diffing gcc/f
cvs diff: Diffing gcc/f/gbe
cvs diff: Diffing gcc/f/runtime
cvs diff: Diffing gcc/f/runtime/libF77
cvs diff: Diffing gcc/f/runtime/libI77
cvs diff: Diffing gcc/f/runtime/libU77
cvs diff: Diffing gcc/ginclude
cvs diff: Diffing gcc/objc
cvs diff: Diffing gcc/testsuite
cvs diff: Diffing gcc/testsuite/config
cvs diff: Diffing gcc/testsuite/g++.old-deja
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.benjamin
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.bob
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.brendan
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.bugs
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.eh
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.ext
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.gb
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.jason
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.law
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.mike
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.niklas
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.other
Index: gcc/testsuite/g++.old-deja/g++.other/init3.C
===================================================================
RCS file: init3.C
diff -N init3.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- init3.C Mon Feb 9 22:19:55 1998
***************
*** 0 ****
--- 1,7 ----
+ // Build don't link:
+
+ struct X
+ {
+ static const bool is_signed = true ;
+ static const int digits = is_signed ? 8 *sizeof(wchar_t)-1 : 0;
+ };
Index: gcc/testsuite/g++.old-deja/g++.other/realloc.C
===================================================================
RCS file: /home/mitchell/Repository/egcs/gcc/testsuite/g++.old-deja/g++.other/realloc.C,v
retrieving revision 1.1
diff -c -p -r1.1 realloc.C
*** realloc.C 1998/02/03 07:19:29 1.1
--- realloc.C 1998/02/03 07:20:12
*************** public:
*** 7,13 ****
void realloc(int foo,int bar);
};
! int f() {
bug c;
c.realloc(50,50);
}
--- 7,13 ----
void realloc(int foo,int bar);
};
! void f() {
bug c;
c.realloc(50,50);
}
cvs diff: Diffing gcc/testsuite/g++.old-deja/g++.pt
Index: gcc/testsuite/g++.old-deja/g++.pt/defarg.C
===================================================================
RCS file: defarg.C
diff -N defarg.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- defarg.C Mon Feb 9 22:20:45 1998
***************
*** 0 ****
--- 1,10 ----
+ template <class T>
+ void f(T t, int i = 10);
+
+ template <class T>
+ void f(T t, int i) {}
+
+ int main()
+ {
+ f(3);
+ }
Index: gcc/testsuite/g++.old-deja/g++.pt/nested1.C
===================================================================
RCS file: nested1.C
diff -N nested1.C
*** /dev/null Mon Dec 31 20:00:00 1979
--- nested1.C Mon Feb 9 22:20:23 1998
***************
*** 0 ****
--- 1,47 ----
+ // Build don't link:
+
+ template <class T1,class T2>
+ struct X
+ {
+ T1 a;
+
+ struct Y
+ {
+ T2 x;
+ Y (T2 _x) { x=_x; }
+ };
+
+ };
+
+ template <class T1>
+ struct X<T1,int>
+ {
+ T1 a;
+
+ struct Y
+ {
+ int x;
+ Y (int _x) { x=_x; }
+ };
+
+ };
+
+ template <>
+ struct X<int,int>
+ {
+ int a;
+
+ struct Y
+ {
+ int x;
+ Y (int _x) { x=_x; }
+ };
+
+ };
+
+ void f ()
+ {
+ X<char,char> t1;
+ X<char,int> t2;
+ X<int,int> t3;
+ }
More information about the Gcc-bugs
mailing list