+Fri Jun 9 17:55:08 2000 Jeffrey A Law (law@cygnus.com)
+
+ 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.
+
2000-03-08 Nathan Sidwell <nathan@codesourcery.com>
* exception.cc (__cp_pop_exception): Cleanup the original object.
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)
{
parmtype = TREE_VALUE (parmtypes);
}
+ maybe_vlist_ctor_wrapper (decl, 0);
+
/* [class.copy]
A non-template constructor for class X is a copy constructor if
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;
}
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.
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);
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
/*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
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)))
}
\f
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);
/* 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);
}
}
else if (nested)
pop_cp_function_context (context);
}
-
-
-