This is the mail archive of the gcc-patches@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]

A thunks patch for the stable branch


The current stable branch contains an old and incomplete thunks
patch from Martin. I am enclosing a patch for the stable branch
which brings it up to date. Could someone please check it in?

Thanks.

-- 
H.J. Lu (hjl@gnu.org)
2000-02-07    <loewis@informatik.hu-berlin.de>

	* decl2.c (import_export_decl): vlist ctor wrappers follow virtual
	methods in their interface.
	(vlist_ctor_wrapper_p): new function.
	(finish_vlist_ctor_wrapper): likewise.

2000-02-06    <loewis@informatik.hu-berlin.de>

	* decl2.c (maybe_retrofit_in_chrg): Move call to
	make_vlist_ctor_wrapper from here ...
	* decl.c (grok_ctor_properties): ... to here.
	* decl.c (grokfndecl): ... and here.
	* init.c (no_vlist_base_init): Declare unseen Vlist ctor weak.
	* decl2.c (maybe_retrofit_in_chrg): Be sorry about varargs ctors.
diff -upr -x ChangeLog cp/decl.c gcc/cp/decl.c
--- cp/decl.c	Thu Apr 13 08:10:46 2000
+++ gcc/cp/decl.c	Mon Feb  7 16:32:05 2000
@@ -8967,9 +8967,12 @@ grokfndecl (ctype, type, declarator, ori
 					    template_count, 
 					    2 * (funcdef_flag != 0) + 
 					    4 * (friendp != 0));
+
       if (decl == error_mark_node)
 	return NULL_TREE;
 
+      maybe_vlist_ctor_wrapper (decl, funcdef_flag);
+
       if ((! TYPE_FOR_JAVA (ctype) || check_java_method (decl))
 	  && check)
 	{
@@ -12170,6 +12173,8 @@ grok_ctor_properties (ctype, decl)
       parmtypes = TREE_CHAIN (parmtypes);
       parmtype = TREE_VALUE (parmtypes);
     }
+
+  maybe_vlist_ctor_wrapper (decl, 0);
 
   /* [class.copy]
 
diff -upr -x ChangeLog cp/decl2.c gcc/cp/decl2.c
--- cp/decl2.c	Thu Apr 13 08:10:47 2000
+++ gcc/cp/decl2.c	Mon Feb  7 16:32:05 2000
@@ -980,7 +980,11 @@ maybe_retrofit_in_chrg (fn)
   if (DECL_CONSTRUCTOR_P (fn))
     {
       if (TYPE_USES_PVBASES (DECL_CLASS_CONTEXT (fn)))
-	DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_PVBASE;
+	{
+	  DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_PVBASE;
+	  if (flag_vtable_thunks_compat && varargs_function_p (fn))
+	    sorry ("-fvtable-thunks=2 for vararg constructor", fn);
+	}
       else
 	DECL_CONSTRUCTOR_FOR_VBASE (fn) = CONSTRUCTOR_FOR_VBASE;
     }
@@ -1028,10 +1032,6 @@ maybe_retrofit_in_chrg (fn)
     fntype = build_exception_variant (fntype,
 				      TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)));
   TREE_TYPE (fn) = fntype;
-
-  if (flag_vtable_thunks_compat
-      && DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))
-    make_vlist_ctor_wrapper (fn);
 }
 
 /* Classes overload their constituent function names automatically.
@@ -2854,6 +2854,30 @@ import_export_decl (decl)
       else
 	DECL_NOT_REALLY_EXTERN (decl) = 0;
     }
+  else if (DECL_VLIST_CTOR_WRAPPER_P (decl))
+    {
+      int implement;
+      tree ctype = DECL_CLASS_CONTEXT (decl);
+      import_export_class (ctype);
+      if (!DECL_THIS_INLINE (DECL_VLIST_CTOR_WRAPPED (decl)))
+	{
+	  /* No change.  */
+	}	  
+      else if (CLASSTYPE_INTERFACE_KNOWN (ctype))
+	{
+	  implement = !CLASSTYPE_INTERFACE_ONLY (ctype) 
+	    && flag_implement_inlines;
+	  DECL_NOT_REALLY_EXTERN (decl) = implement;
+	  DECL_EXTERNAL (decl) = !implement;
+	}
+      else
+	{
+	  DECL_NOT_REALLY_EXTERN (decl) = 1;
+	  DECL_EXTERNAL (decl) = 1;
+	}
+      if (flag_weak)
+	comdat_linkage (decl);
+    }
   else if (DECL_FUNCTION_MEMBER_P (decl))
     {
       tree ctype = DECL_CLASS_CONTEXT (decl);
@@ -3606,6 +3630,33 @@ generate_ctor_and_dtor_functions_for_pri
   return 0;
 }
 
+/* Returns non-zero if T is a vlist ctor wrapper.  */
+
+static int
+vlist_ctor_wrapper_p (t, data)
+     tree t;
+     void *data ATTRIBUTE_UNUSED;
+{
+  return (TREE_CODE (t) == FUNCTION_DECL) && DECL_VLIST_CTOR_WRAPPER_P (t);
+}
+
+/* Emits a vlist ctor wrapper if necessary.  */
+
+static int
+finish_vlist_ctor_wrapper (t, data)
+     tree *t;
+     void *data ATTRIBUTE_UNUSED;
+{
+  import_export_decl (*t);
+  if (!DECL_EXTERNAL (*t) && !TREE_USED (*t))
+    {
+      mark_used (*t);
+      synthesize_method (*t);
+      return 1;
+    }
+  return 0;
+}
+
 /* This routine is called from the last rule in yyparse ().
    Its job is to create all the code needed to initialize and
    destroy the global aggregates.  We do the destruction
@@ -3682,6 +3733,12 @@ finish_file ()
 			/*data=*/0))
 	reconsider = 1;
       
+      if (walk_globals (vlist_ctor_wrapper_p,
+			finish_vlist_ctor_wrapper,
+			/*data=*/0))
+	reconsider = 1;
+      
+
       /* The list of objects with static storage duration is built up
 	 in reverse order, so we reverse it here.  We also clear
 	 STATIC_AGGREGATES so that any new aggregates added during the
diff -upr -x ChangeLog cp/init.c gcc/cp/init.c
--- cp/init.c	Thu Apr 13 08:10:48 2000
+++ gcc/cp/init.c	Mon Feb  7 16:32:05 2000
@@ -1262,6 +1262,14 @@ no_vlist_base_init (rval, exp, init, bin
   my_friendly_assert (TREE_CODE (func) == CALL_EXPR, 20000131);
   func = TREE_OPERAND (func, 0);
   my_friendly_assert (TREE_CODE (func) == ADDR_EXPR, 20000132);
+  func = TREE_OPERAND (func, 0);
+  my_friendly_assert (TREE_CODE (func) == FUNCTION_DECL, 20000133);  
+
+  /* If we have already seen a definition for the wrapped function,
+     we don't need to declare it weak. Also, declare_weak will complain
+     if we do.  */
+  if (!TREE_ASM_WRITTEN (func))
+    declare_weak (func);
 
   if (init == NULL_TREE
       || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init)))
diff -upr -x ChangeLog cp/method.c gcc/cp/method.c
--- cp/method.c	Thu Apr 13 08:10:48 2000
+++ gcc/cp/method.c	Mon Feb  7 16:32:06 2000
@@ -2241,13 +2241,18 @@ emit_thunk (thunk_fndecl)
 }
 
 void
-make_vlist_ctor_wrapper (fn)
+maybe_vlist_ctor_wrapper (fn, definep)
   tree fn;
+  int definep;
 {
   tree fntype, decl;
   tree arg_types, parms, parm, basetype, pbasetype;
   tree t, ctors;
 
+  if (!flag_vtable_thunks_compat
+      || !DECL_CONSTRUCTOR_FOR_PVBASE_P (fn))
+    return;
+
   arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn));
   pbasetype = TREE_VALUE (arg_types);
   basetype = TREE_TYPE (pbasetype);
@@ -2324,15 +2329,23 @@ make_vlist_ctor_wrapper (fn)
   /* Remember the original function.  */
   DECL_VLIST_CTOR_WRAPPED (decl) = fn;
 
-  /* When fn is declared, DECL_INITIAL is null. When it is defined,
-     DECL_INITIAL will be error_mark_node.  */
-  if (DECL_INITIAL (fn) == error_mark_node)
+  /* If this is called from start_method, definep is -1. Then we
+     are inside the class, and fn is inline by default.  */
+  if (definep)
     {
       /* Record that the ctor is being defined, so we also emit the
-	 wrapper later.  */
-      TREE_USED (decl) = 1;
-      DECL_NOT_REALLY_EXTERN (decl) = 1;
-      DECL_INITIAL (decl) = NULL_TREE;
+	 wrapper later. */
+      if (DECL_THIS_INLINE (fn)  || (definep == -1))
+	{
+	  DECL_THIS_INLINE (decl) = 1;
+	  DECL_INLINE (decl) = 1;
+	  pushdecl_top_level (decl);
+	}
+      else
+	{
+	  TREE_USED (decl) = 1;
+	  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) = 1;
+	}
       mark_inline_for_output (decl);
     }
 }
@@ -2651,6 +2664,3 @@ synthesize_method (fndecl)
   else if (nested)
     pop_cp_function_context (context);
 }
-
-
-

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