This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH for redeclaration of template classes



Here's a patch that improves both the error-checking and the
default argument processing of template class redeclarations.  Is it
OK?

-- 
Mark Mitchell <mmitchell@usa.net>
http://home.earthlink.net/~mbmitchell
Consulting Services Available

Thu Mar 26 16:43:49 1998  Mark Mitchell  <mmitchell@usa.net>

	* pt.c (redeclare_class_template): New function.
	* cp_tree.h (redeclare_class_template): Declare it.
	* decl.c (xref_tag): Use it.
	* error.c (dump_decl): Be a bit more explicit with template
	type arguments, when verbose.

Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.106
diff -c -p -r1.106 pt.c
*** pt.c	1998/03/26 10:32:03	1.106
--- pt.c	1998/03/27 00:29:35
*************** push_template_decl (decl)
*** 1792,1798 ****
--- 1792,1857 ----
    return DECL_TEMPLATE_RESULT (tmpl);
  }
  
+ /* Called when a class template TYPE is redeclared, e.g.:
  
+      template <class T> struct S;
+      template <class T> struct S {};  */
+ 
+ void 
+ redeclare_class_template (type)
+      tree type;
+ {
+   tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
+   tree tmpl_parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
+   tree parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
+   int i;
+ 
+   if (!PRIMARY_TEMPLATE_P (tmpl))
+     /* The type is nested in some template class.  Nothing to worry
+        about here; there are no new template parameters for the nested
+        type.  */
+     return;
+ 
+   if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms))
+     {
+       cp_error_at ("previous declaration `%D'", tmpl);
+       cp_error ("used %d template parameter%s instead of %d",
+ 		TREE_VEC_LENGTH (tmpl_parms), 
+ 		TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s",
+ 		TREE_VEC_LENGTH (parms));
+       return;
+     }
+ 
+   for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i)
+     {
+       tree tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i));
+       tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+       tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i));
+       tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i));
+ 
+       if (TREE_CODE (tmpl_parm) != TREE_CODE (parm))
+ 	{
+ 	  cp_error_at ("template parameter `%#D'", tmpl_parm);
+ 	  cp_error ("redeclared here as `%#D'", parm);
+ 	  return;
+ 	}
+ 
+       if (tmpl_default != NULL_TREE && parm_default != NULL_TREE)
+ 	{
+ 	  /* We have in [temp.param]:
+ 
+ 	     A template-parameter may not be given default arguments
+ 	     by two different declarations in the same scope.  */
+ 	  cp_error ("redefinition of default argument for `%#D'", parm);
+ 	  return;
+ 	}
+ 
+       /* Update the previous template parameters (which are the ones
+ 	 that will really count) with the new default value.  */
+       TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)) = parm_default;
+     }
+ }
+ 
  /* Attempt to convert the non-type template parameter EXPR to the
     indicated TYPE.  If the conversion is successful, return the
     converted value.  If the conversion is unsuccesful, return
Index: error.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/error.c,v
retrieving revision 1.30
diff -c -p -r1.30 error.c
*** error.c	1998/03/24 10:25:41	1.30
--- error.c	1998/03/27 00:29:38
*************** dump_decl (t, v)
*** 655,660 ****
--- 655,664 ----
  	/* Don't say 'typedef class A' */
          if (DECL_ARTIFICIAL (t))
  	  {
+ 	    if (v > 0 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
+ 	      /* Say `class T' not just `T'. */
+ 	      OB_PUTS ("class ");
+ 
  	    dump_type (TREE_TYPE (t), v);
  	    break;
  	  }
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.46
diff -c -p -r1.46 cp-tree.h
*** cp-tree.h	1998/03/25 16:14:45	1.46
--- cp-tree.h	1998/03/27 00:29:49
*************** extern tree end_template_parm_list		PROT
*** 2457,2462 ****
--- 2457,2463 ----
  extern void end_template_decl			PROTO((void));
  extern tree current_template_args		PROTO((void));
  extern tree push_template_decl			PROTO((tree));
+ extern void redeclare_class_template            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: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.84
diff -c -p -r1.84 decl.c
*** decl.c	1998/03/26 11:16:45	1.84
--- decl.c	1998/03/27 00:30:27
*************** xref_tag (code_type_node, name, binfo, g
*** 10889,10894 ****
--- 10889,10897 ----
  	  if (BINDING_VALUE (binding) == NULL_TREE)
  	    BINDING_VALUE (binding) = TYPE_NAME (ref);
  	}
+ 
+       if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref))
+ 	redeclare_class_template (ref);
      }
  
    if (binfo)
Index: redecl1.C
===================================================================
RCS file: redecl1.C
diff -N redecl1.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- redecl1.C	Thu Mar 26 16:30:43 1998
***************
*** 0 ****
--- 1,22 ----
+ // Build don't link:
+ 
+ template <class T>
+ struct S1; // ERROR - previous declaration
+ 
+ template <class T, class U>
+ struct S1 {}; // ERROR - used 1 template parameter
+ 
+ template <class T = int>
+ struct S2; 
+ 
+ template <class T = int>
+ struct S2; // ERROR - redefinition of default
+ 
+ template <class T> // ERROR - template parameter
+ struct S3;
+ 
+ template <int I>
+ struct S3; // ERROR - redeclared here
+ 
+ template <template <class T> class C>
+ struct S3; // ERROR - redeclared here
Index: defarg3.C
===================================================================
RCS file: defarg3.C
diff -N defarg3.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- defarg3.C	Thu Mar 26 16:31:28 1998
***************
*** 0 ****
--- 1,10 ----
+ // Build don't link:
+ 
+ template <class T = int>
+ struct S {};
+ 
+ void f()
+ {
+   S<> s;
+ }
+ 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]