This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
A thunks patch for the stable branch
- To: egcs-patches at egcs dot cygnus dot com
- Subject: A thunks patch for the stable branch
- From: "H . J . Lu" <hjl at valinux dot com>
- Date: Wed, 19 Apr 2000 09:15:03 -0700
- Cc: loewis at informatik dot hu-berlin dot de
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);
}
-
-
-