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