Commit 0c11ada6 by Jason Merrill Committed by Jason Merrill

decl.c (push_overloaded_decl_1, [...]): Lose.

        * decl.c (push_overloaded_decl_1, auto_function,
        define_function): Lose.
        (build_library_fn_1): New static fn.
        (builtin_function): Use it.
        (get_atexit_node): Use build_library_fn_ptr.
        (build_library_fn, build_cp_library_fn, build_library_fn_ptr,
        build_cp_library_fn_ptr, push_library_fn, push_cp_library_fn,
        push_void_library_fn, push_throw_library_fn): New fns.
        * cp-tree.h: Declare them.
        (cp_tree_index): Remove CPTI_BAD_CAST, CPTI_BAD_TYPEID.
        (throw_bad_cast_node, throw_bad_typeid_node): Lose.
        * except.c (init_exception_processing, call_eh_info, do_pop_exception,
        (expand_end_eh_spec, alloc_eh_object, expand_throw): Use above fns.
        * rtti.c (build_runtime_decl): Lose.
        (throw_bad_cast, throw_bad_typeid, get_tinfo_decl,
        build_dynamic_cast_1, expand_si_desc, expand_class_desc,
        expand_ptr_desc, expand_attr_desc, expand_generic_desc): Use above fns.

        * call.c (build_call): Remove result_type parm.
        Call mark_used on unused artificial fns.
        * init.c, method.c, typeck.c, except.c, rtti.c: Adjust.

From-SVN: r32468
parent c3ab7a40
2000-03-10 Jason Merrill <jason@casey.cygnus.com>
* decl.c (push_overloaded_decl_1, auto_function,
define_function): Lose.
(build_library_fn_1): New static fn.
(builtin_function): Use it.
(get_atexit_node): Use build_library_fn_ptr.
(build_library_fn, build_cp_library_fn, build_library_fn_ptr,
build_cp_library_fn_ptr, push_library_fn, push_cp_library_fn,
push_void_library_fn, push_throw_library_fn): New fns.
* cp-tree.h: Declare them.
(cp_tree_index): Remove CPTI_BAD_CAST, CPTI_BAD_TYPEID.
(throw_bad_cast_node, throw_bad_typeid_node): Lose.
* except.c (init_exception_processing, call_eh_info, do_pop_exception,
(expand_end_eh_spec, alloc_eh_object, expand_throw): Use above fns.
* rtti.c (build_runtime_decl): Lose.
(throw_bad_cast, throw_bad_typeid, get_tinfo_decl,
build_dynamic_cast_1, expand_si_desc, expand_class_desc,
expand_ptr_desc, expand_attr_desc, expand_generic_desc): Use above fns.
* call.c (build_call): Remove result_type parm.
Call mark_used on unused artificial fns.
* init.c, method.c, typeck.c, except.c, rtti.c: Adjust.
2000-03-09 Jason Merrill <jason@casey.cygnus.com> 2000-03-09 Jason Merrill <jason@casey.cygnus.com>
* call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as * call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as
......
...@@ -364,13 +364,14 @@ build_addr_func (function) ...@@ -364,13 +364,14 @@ build_addr_func (function)
(TYPE_PTRMEMFUNC_P) must be handled by our callers. */ (TYPE_PTRMEMFUNC_P) must be handled by our callers. */
tree tree
build_call (function, result_type, parms) build_call (function, parms)
tree function, result_type, parms; tree function, parms;
{ {
int is_constructor = 0; int is_constructor = 0;
int nothrow; int nothrow;
tree tmp; tree tmp;
tree decl; tree decl;
tree result_type;
function = build_addr_func (function); function = build_addr_func (function);
...@@ -380,6 +381,8 @@ build_call (function, result_type, parms) ...@@ -380,6 +381,8 @@ build_call (function, result_type, parms)
return error_mark_node; return error_mark_node;
} }
result_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (function)));
if (TREE_CODE (function) == ADDR_EXPR if (TREE_CODE (function) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
decl = TREE_OPERAND (function, 0); decl = TREE_OPERAND (function, 0);
...@@ -394,8 +397,14 @@ build_call (function, result_type, parms) ...@@ -394,8 +397,14 @@ build_call (function, result_type, parms)
if (decl && DECL_CONSTRUCTOR_P (decl)) if (decl && DECL_CONSTRUCTOR_P (decl))
is_constructor = 1; is_constructor = 1;
if (decl) if (decl && ! TREE_USED (decl))
my_friendly_assert (TREE_USED (decl), 990125); {
/* We invoke build_call directly for several library functions. */
if (DECL_ARTIFICIAL (decl))
mark_used (decl);
else
my_friendly_abort (990125);
}
/* Don't pass empty class objects by value. This is useful /* Don't pass empty class objects by value. This is useful
for tags in STL, which are used to control overload resolution. for tags in STL, which are used to control overload resolution.
...@@ -4157,7 +4166,7 @@ build_over_call (cand, args, flags) ...@@ -4157,7 +4166,7 @@ build_over_call (cand, args, flags)
return exp; return exp;
} }
fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args); fn = build_call (fn, converted_args);
if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE) if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
return fn; return fn;
fn = require_complete_type (fn); fn = require_complete_type (fn);
......
...@@ -577,8 +577,6 @@ enum cp_tree_index ...@@ -577,8 +577,6 @@ enum cp_tree_index
CPTI_TERMINATE, CPTI_TERMINATE,
CPTI_ATEXIT, CPTI_ATEXIT,
CPTI_DSO_HANDLE, CPTI_DSO_HANDLE,
CPTI_BAD_CAST,
CPTI_BAD_TYPEID,
CPTI_DCAST, CPTI_DCAST,
CPTI_MAX CPTI_MAX
...@@ -686,12 +684,6 @@ extern tree cp_global_trees[CPTI_MAX]; ...@@ -686,12 +684,6 @@ extern tree cp_global_trees[CPTI_MAX];
/* A pointer to `__dso_handle'. */ /* A pointer to `__dso_handle'. */
#define dso_handle_node cp_global_trees[CPTI_DSO_HANDLE] #define dso_handle_node cp_global_trees[CPTI_DSO_HANDLE]
/* The declaration of __throw_bad_cast. */
#define throw_bad_cast_node cp_global_trees[CPTI_BAD_CAST]
/* The declaration of __throw_bad_typeid. */
#define throw_bad_typeid_node cp_global_trees[CPTI_BAD_TYPEID]
/* The declaration of the dynamic_cast runtime. */ /* The declaration of the dynamic_cast runtime. */
#define dynamic_cast_node cp_global_trees[CPTI_DCAST] #define dynamic_cast_node cp_global_trees[CPTI_DCAST]
...@@ -3605,7 +3597,7 @@ extern tree build_vfield_ref PARAMS ((tree, tree)); ...@@ -3605,7 +3597,7 @@ extern tree build_vfield_ref PARAMS ((tree, tree));
extern tree resolve_scope_to_name PARAMS ((tree, tree)); extern tree resolve_scope_to_name PARAMS ((tree, tree));
extern tree build_scoped_method_call PARAMS ((tree, tree, tree, tree)); extern tree build_scoped_method_call PARAMS ((tree, tree, tree, tree));
extern tree build_addr_func PARAMS ((tree)); extern tree build_addr_func PARAMS ((tree));
extern tree build_call PARAMS ((tree, tree, tree)); extern tree build_call PARAMS ((tree, tree));
extern tree build_method_call PARAMS ((tree, tree, tree, tree, int)); extern tree build_method_call PARAMS ((tree, tree, tree, tree, int));
extern int null_ptr_cst_p PARAMS ((tree)); extern int null_ptr_cst_p PARAMS ((tree));
extern tree type_decays_to PARAMS ((tree)); extern tree type_decays_to PARAMS ((tree));
...@@ -3753,12 +3745,16 @@ extern tree namespace_ancestor PARAMS ((tree, tree)); ...@@ -3753,12 +3745,16 @@ extern tree namespace_ancestor PARAMS ((tree, tree));
extern tree unqualified_namespace_lookup PARAMS ((tree, int, tree *)); extern tree unqualified_namespace_lookup PARAMS ((tree, int, tree *));
extern int lookup_using_namespace PARAMS ((tree, tree, tree, tree, int, tree *)); extern int lookup_using_namespace PARAMS ((tree, tree, tree, tree, int, tree *));
extern int qualified_lookup_using_namespace PARAMS ((tree, tree, tree, int)); extern int qualified_lookup_using_namespace PARAMS ((tree, tree, tree, int));
extern tree auto_function PARAMS ((tree, tree)); extern tree build_library_fn PARAMS ((tree, tree));
extern tree build_cp_library_fn PARAMS ((tree, tree));
extern tree build_library_fn_ptr PARAMS ((const char *, tree));
extern tree build_cp_library_fn_ptr PARAMS ((const char *, tree));
extern tree push_library_fn PARAMS ((tree, tree));
extern tree push_cp_library_fn PARAMS ((tree, tree));
extern tree push_void_library_fn PARAMS ((tree, tree));
extern tree push_throw_library_fn PARAMS ((tree, tree));
extern void init_decl_processing PARAMS ((void)); extern void init_decl_processing PARAMS ((void));
extern int init_type_desc PARAMS ((void)); extern int init_type_desc PARAMS ((void));
extern tree define_function PARAMS ((const char *, tree,
void (*) (tree),
const char *));
extern tree check_tag_decl PARAMS ((tree)); extern tree check_tag_decl PARAMS ((tree));
extern void shadow_tag PARAMS ((tree)); extern void shadow_tag PARAMS ((tree));
extern tree groktypename PARAMS ((tree)); extern tree groktypename PARAMS ((tree));
......
...@@ -113,7 +113,6 @@ static void declare_namespace_level PARAMS ((void)); ...@@ -113,7 +113,6 @@ static void declare_namespace_level PARAMS ((void));
static void signal_catch PARAMS ((int)) ATTRIBUTE_NORETURN; static void signal_catch PARAMS ((int)) ATTRIBUTE_NORETURN;
static void storedecls PARAMS ((tree)); static void storedecls PARAMS ((tree));
static void require_complete_types_for_parms PARAMS ((tree)); static void require_complete_types_for_parms PARAMS ((tree));
static void push_overloaded_decl_1 PARAMS ((tree));
static int ambi_op_p PARAMS ((tree)); static int ambi_op_p PARAMS ((tree));
static int unary_op_p PARAMS ((tree)); static int unary_op_p PARAMS ((tree));
static tree store_bindings PARAMS ((tree, tree)); static tree store_bindings PARAMS ((tree, tree));
...@@ -133,6 +132,7 @@ static void set_identifier_type_value_with_scope ...@@ -133,6 +132,7 @@ static void set_identifier_type_value_with_scope
PARAMS ((tree, tree, struct binding_level *)); PARAMS ((tree, tree, struct binding_level *));
static void record_builtin_type PARAMS ((enum rid, const char *, tree)); static void record_builtin_type PARAMS ((enum rid, const char *, tree));
static void record_unknown_type PARAMS ((tree, const char *)); static void record_unknown_type PARAMS ((tree, const char *));
static tree build_library_fn_1 PARAMS ((tree, tree));
static int member_function_or_else PARAMS ((tree, tree, enum overload_flags)); static int member_function_or_else PARAMS ((tree, tree, enum overload_flags));
static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int, static void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
int)); int));
...@@ -5937,26 +5937,6 @@ record_unknown_type (type, name) ...@@ -5937,26 +5937,6 @@ record_unknown_type (type, name)
TYPE_MODE (type) = TYPE_MODE (void_type_node); TYPE_MODE (type) = TYPE_MODE (void_type_node);
} }
/* Push overloaded decl, in global scope, with one argument so it
can be used as a callback from define_function. */
static void
push_overloaded_decl_1 (x)
tree x;
{
pushdecl (x);
}
inline tree
auto_function (name, type)
tree name, type;
{
return define_function
(IDENTIFIER_POINTER (name), type, push_overloaded_decl_1,
IDENTIFIER_POINTER (build_decl_overload (name, TYPE_ARG_TYPES (type),
0)));
}
/* Create the predefined scalar types of C, /* Create the predefined scalar types of C,
and some nodes representing standard constants (0, 1, (void *)0). and some nodes representing standard constants (0, 1, (void *)0).
Initialize the global binding level. Initialize the global binding level.
...@@ -6320,15 +6300,15 @@ init_decl_processing () ...@@ -6320,15 +6300,15 @@ init_decl_processing ()
newtype = build_exception_variant newtype = build_exception_variant
(ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1)); (ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
deltype = build_exception_variant (void_ftype_ptr, empty_except_spec); deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
auto_function (ansi_opname[(int) NEW_EXPR], newtype); push_cp_library_fn (ansi_opname[(int) NEW_EXPR], newtype);
auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype); push_cp_library_fn (ansi_opname[(int) VEC_NEW_EXPR], newtype);
global_delete_fndecl = auto_function (ansi_opname[(int) DELETE_EXPR], global_delete_fndecl = push_cp_library_fn (ansi_opname[(int) DELETE_EXPR],
deltype); deltype);
auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype); push_cp_library_fn (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
} }
abort_fndecl abort_fndecl
= define_function ("__pure_virtual", void_ftype, 0, 0); = build_library_fn_ptr ("__pure_virtual", void_ftype);
/* Perform other language dependent initializations. */ /* Perform other language dependent initializations. */
init_class_processing (); init_class_processing ();
...@@ -6461,60 +6441,154 @@ lang_print_error_function (file) ...@@ -6461,60 +6441,154 @@ lang_print_error_function (file)
maybe_print_template_context (); maybe_print_template_context ();
} }
/* Make a definition for a builtin function named NAME and whose data type /* Entry point for the benefit of c_common_nodes_and_builtins.
Make a definition for a builtin function named NAME and whose data type
is TYPE. TYPE should be a function type with argument types. is TYPE. TYPE should be a function type with argument types.
If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, CLASS and CODE tell later passes how to compile calls to this function.
See tree.h for possible values.
If LIBNAME is nonzero, use that for DECL_ASSEMBLER_NAME,
the name to be called if we can't opencode the function. */ the name to be called if we can't opencode the function. */
tree tree
define_function (name, type, pfn, library_name) builtin_function (name, type, code, class, libname)
const char *name; const char *name;
tree type; tree type;
void (*pfn) PARAMS ((tree)); int code;
const char *library_name; enum built_in_class class;
const char *libname;
{ {
tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type); tree decl = build_library_fn_1 (get_identifier (name), type);
DECL_EXTERNAL (decl) = 1; DECL_BUILT_IN_CLASS (decl) = class;
TREE_PUBLIC (decl) = 1; DECL_FUNCTION_CODE (decl) = code;
DECL_ARTIFICIAL (decl) = 1;
/* If no exception specifier was given, assume it doesn't throw. */
if (TYPE_RAISES_EXCEPTIONS (type) == NULL_TREE)
TREE_NOTHROW (decl) = 1;
my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392); my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
/* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME, /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
we cannot change DECL_ASSEMBLER_NAME until we have installed this we cannot change DECL_ASSEMBLER_NAME until we have installed this
function in the namespace. */ function in the namespace. */
if (pfn) (*pfn) (decl); pushdecl (decl);
if (library_name) if (libname)
DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); DECL_ASSEMBLER_NAME (decl) = get_identifier (libname);
make_function_rtl (decl); make_function_rtl (decl);
return decl; return decl;
} }
/* Generate a FUNCTION_DECL with the typical flags for a runtime library
function. Not called directly. */
static tree
build_library_fn_1 (name, type)
tree name;
tree type;
{
tree fn = build_lang_decl (FUNCTION_DECL, name, type);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
return fn;
}
/* Wrapper around define_function, for the benefit of /* Returns the _DECL for a library function with C linkage.
c_common_nodes_and_builtins. We assume that such functions never throw; if this is incorrect,
FUNCTION_CODE tells later passes how to compile calls to this function. callers should unset TREE_NOTHROW. */
See tree.h for its possible values. */
tree tree
builtin_function (name, type, code, class, libname) build_library_fn (name, type)
tree name;
tree type;
{
tree fn = build_library_fn_1 (name, type);
make_function_rtl (fn);
return fn;
}
/* Returns the _DECL for a library function with C++ linkage. */
tree
build_cp_library_fn (name, type)
tree name;
tree type;
{
tree fn = build_library_fn_1 (name, type);
TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
set_mangled_name_for_decl (fn);
make_function_rtl (fn);
return fn;
}
/* Like build_library_fn, but takes a C string instead of an
IDENTIFIER_NODE. */
tree
build_library_fn_ptr (name, type)
const char *name; const char *name;
tree type; tree type;
int code;
enum built_in_class class;
const char *libname;
{ {
tree decl = define_function (name, type, (void (*) PARAMS ((tree)))pushdecl, return build_library_fn (get_identifier (name), type);
libname); }
DECL_BUILT_IN_CLASS (decl) = class;
DECL_FUNCTION_CODE (decl) = code; /* Like build_cp_library_fn, but takes a C string instead of an
return decl; IDENTIFIER_NODE. */
tree
build_cp_library_fn_ptr (name, type)
const char *name;
tree type;
{
return build_cp_library_fn (get_identifier (name), type);
}
/* Like build_library_fn, but also pushes the function so that we will
be able to find it via IDENTIFIER_GLOBAL_VALUE. */
tree
push_library_fn (name, type)
tree name, type;
{
tree fn = build_library_fn (name, type);
pushdecl_top_level (fn);
return fn;
}
/* Like build_cp_library_fn, but also pushes the function so that it
will be found by normal lookup. */
tree
push_cp_library_fn (name, type)
tree name;
tree type;
{
tree fn = build_cp_library_fn (name, type);
pushdecl (fn);
return fn;
}
/* Like push_library_fn, but takes a TREE_LIST of parm types rather than
a FUNCTION_TYPE. */
tree
push_void_library_fn (name, parmtypes)
tree name, parmtypes;
{
tree type = build_function_type (void_type_node, parmtypes);
return push_library_fn (name, type);
}
/* Like push_void_library_fn, but also note that this function throws
and does not return. Used for __throw_foo and the like. */
tree
push_throw_library_fn (name, parmtypes)
tree name, parmtypes;
{
tree fn = push_void_library_fn (name, parmtypes);
TREE_THIS_VOLATILE (fn) = 1;
TREE_NOTHROW (fn) = 0;
return fn;
} }
/* When we call finish_struct for an anonymous union, we create /* When we call finish_struct for an anonymous union, we create
...@@ -7984,7 +8058,7 @@ get_atexit_node () ...@@ -7984,7 +8058,7 @@ get_atexit_node ()
/* Now, build the function declaration. */ /* Now, build the function declaration. */
push_lang_context (lang_name_c); push_lang_context (lang_name_c);
atexit_fndecl = define_function (name, fn_type, /*pfn=*/0, NULL_PTR); atexit_fndecl = build_library_fn_ptr (name, fn_type);
mark_used (atexit_fndecl); mark_used (atexit_fndecl);
pop_lang_context (); pop_lang_context ();
atexit_node = default_conversion (atexit_fndecl); atexit_node = default_conversion (atexit_fndecl);
......
...@@ -173,8 +173,9 @@ init_exception_processing () ...@@ -173,8 +173,9 @@ init_exception_processing ()
if (flag_honor_std) if (flag_honor_std)
push_namespace (get_identifier ("std")); push_namespace (get_identifier ("std"));
terminate_node = auto_function (get_identifier ("terminate"), vtype); terminate_node = build_cp_library_fn_ptr ("terminate", vtype);
TREE_THIS_VOLATILE (terminate_node) = 1; TREE_THIS_VOLATILE (terminate_node) = 1;
TREE_NOTHROW (terminate_node) = 1;
if (flag_honor_std) if (flag_honor_std)
pop_namespace (); pop_namespace ();
...@@ -253,16 +254,8 @@ call_eh_info () ...@@ -253,16 +254,8 @@ call_eh_info ()
t = build_pointer_type (t); t = build_pointer_type (t);
/* And now the function. */ /* And now the function. */
fn = build_lang_decl (FUNCTION_DECL, fn, fn = push_library_fn (fn, build_function_type (t, void_list_node));
build_function_type (t, void_list_node));
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn);
return build_function_call (fn, NULL_TREE); return build_function_call (fn, NULL_TREE);
} }
...@@ -424,18 +417,12 @@ do_pop_exception () ...@@ -424,18 +417,12 @@ do_pop_exception ()
{ {
/* Declare void __cp_pop_exception (void *), /* Declare void __cp_pop_exception (void *),
as defined in exception.cc. */ as defined in exception.cc. */
fn = build_lang_decl fn = push_void_library_fn
(FUNCTION_DECL, fn, (fn, tree_cons (NULL_TREE, ptr_type_node, void_list_node));
build_function_type (void_type_node, tree_cons /* This can throw if the destructor for the exception throws. */
(NULL_TREE, ptr_type_node, void_list_node))); TREE_NOTHROW (fn) = 0;
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn);
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */ /* Arrange to do a dynamically scoped cleanup upon exit from this region. */
cleanup = lookup_name (get_identifier ("__exception_info"), 0); cleanup = lookup_name (get_identifier ("__exception_info"), 0);
cleanup = build_function_call (fn, tree_cons cleanup = build_function_call (fn, tree_cons
...@@ -732,21 +719,13 @@ expand_end_eh_spec (raises, try_block) ...@@ -732,21 +719,13 @@ expand_end_eh_spec (raises, try_block)
tmp = tree_cons tmp = tree_cons
(NULL_TREE, integer_type_node, tree_cons (NULL_TREE, integer_type_node, tree_cons
(NULL_TREE, TREE_TYPE (decl), void_list_node)); (NULL_TREE, TREE_TYPE (decl), void_list_node));
tmp = build_function_type (void_type_node, tmp);
fn = push_throw_library_fn (fn, tmp);
fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_THIS_VOLATILE (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn);
tmp = tree_cons (NULL_TREE, build_int_2 (count, 0), tmp = tree_cons (NULL_TREE, build_int_2 (count, 0),
tree_cons (NULL_TREE, decl, NULL_TREE)); tree_cons (NULL_TREE, decl, NULL_TREE));
tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp); tmp = build_call (fn, tmp);
finish_expr_stmt (tmp); finish_expr_stmt (tmp);
finish_handler (blocks, handler); finish_handler (blocks, handler);
...@@ -799,19 +778,10 @@ alloc_eh_object (type) ...@@ -799,19 +778,10 @@ alloc_eh_object (type)
else else
{ {
/* Declare __eh_alloc (size_t), as defined in exception.cc. */ /* Declare __eh_alloc (size_t), as defined in exception.cc. */
tree tmp; tree tmp = tree_cons (NULL_TREE, sizetype, void_list_node);
tmp = tree_cons (NULL_TREE, sizetype, void_list_node); fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
fn = build_lang_decl (FUNCTION_DECL, fn,
build_function_type (ptr_type_node, tmp));
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn);
exp = build_function_call (fn, tree_cons exp = build_function_call (fn, tree_cons
(NULL_TREE, size_in_bytes (type), NULL_TREE)); (NULL_TREE, size_in_bytes (type), NULL_TREE));
exp = build1 (NOP_EXPR, build_pointer_type (type), exp); exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
...@@ -852,16 +822,11 @@ expand_throw (exp) ...@@ -852,16 +822,11 @@ expand_throw (exp)
{ {
/* Declare _Jv_Throw (void *), as defined in Java's /* Declare _Jv_Throw (void *), as defined in Java's
exception.cc. */ exception.cc. */
tree tmp; tree tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node); tmp = build_function_type (ptr_type_node, tmp);
fn = build_lang_decl (FUNCTION_DECL, fn, fn = push_library_fn (fn, tmp);
build_function_type (ptr_type_node, tmp));
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_THIS_VOLATILE (fn) = 1; TREE_THIS_VOLATILE (fn) = 1;
pushdecl_top_level (fn); TREE_NOTHROW (fn) = 0;
make_function_rtl (fn);
} }
exp = build_function_call (fn, args); exp = build_function_call (fn, args);
...@@ -974,17 +939,9 @@ expand_throw (exp) ...@@ -974,17 +939,9 @@ expand_throw (exp)
(NULL_TREE, ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, cleanup_type, void_list_node))); (NULL_TREE, cleanup_type, void_list_node)));
fn = build_lang_decl (FUNCTION_DECL, fn, fn = push_void_library_fn (fn, tmp);
build_function_type (void_type_node, tmp));
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn);
e = tree_cons (NULL_TREE, exp, tree_cons e = tree_cons (NULL_TREE, exp, tree_cons
(NULL_TREE, throw_type, tree_cons (NULL_TREE, throw_type, tree_cons
(NULL_TREE, cleanup, NULL_TREE))); (NULL_TREE, cleanup, NULL_TREE)));
...@@ -1000,21 +957,10 @@ expand_throw (exp) ...@@ -1000,21 +957,10 @@ expand_throw (exp)
if (IDENTIFIER_GLOBAL_VALUE (fn)) if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn); fn = IDENTIFIER_GLOBAL_VALUE (fn);
else else
{ /* Declare void __uncatch_exception (void)
/* Declare void __uncatch_exception (void) as defined in exception.cc. */
as defined in exception.cc. */ fn = push_void_library_fn (fn, void_list_node);
fn = build_lang_decl (FUNCTION_DECL, fn,
build_function_type (void_type_node,
void_list_node));
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
}
mark_used (fn);
exp = build_function_call (fn, NULL_TREE); exp = build_function_call (fn, NULL_TREE);
} }
......
...@@ -1868,8 +1868,7 @@ build_builtin_delete_call (addr) ...@@ -1868,8 +1868,7 @@ build_builtin_delete_call (addr)
tree addr; tree addr;
{ {
mark_used (global_delete_fndecl); mark_used (global_delete_fndecl);
return build_call (global_delete_fndecl, return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
void_type_node, build_tree_list (NULL_TREE, addr));
} }
/* Generate a C++ "new" expression. DECL is either a TREE_LIST /* Generate a C++ "new" expression. DECL is either a TREE_LIST
......
...@@ -2156,7 +2156,7 @@ emit_thunk (thunk_fndecl) ...@@ -2156,7 +2156,7 @@ emit_thunk (thunk_fndecl)
for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a)) for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
t = tree_cons (NULL_TREE, a, t); t = tree_cons (NULL_TREE, a, t);
t = nreverse (t); t = nreverse (t);
t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t); t = build_call (function, t);
finish_return_stmt (t); finish_return_stmt (t);
expand_body (finish_function (lineno, 0)); expand_body (finish_function (lineno, 0));
......
...@@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA. */ ...@@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA. */
extern struct obstack permanent_obstack; extern struct obstack permanent_obstack;
static tree build_runtime_decl PARAMS((const char *, tree));
static tree build_headof_sub PARAMS((tree)); static tree build_headof_sub PARAMS((tree));
static tree build_headof PARAMS((tree)); static tree build_headof PARAMS((tree));
static tree get_tinfo_var PARAMS((tree)); static tree get_tinfo_var PARAMS((tree));
...@@ -165,35 +164,6 @@ build_headof (exp) ...@@ -165,35 +164,6 @@ build_headof (exp)
cp_convert (ptrdiff_type_node, offset)); cp_convert (ptrdiff_type_node, offset));
} }
/* Build a decl to a runtime entry point taking void and returning TYPE.
Although the entry point may never return, making its return type
consistent is necessary. */
static tree
build_runtime_decl (name, type)
const char *name;
tree type;
{
tree d = get_identifier (name);
if (IDENTIFIER_GLOBAL_VALUE (d))
d = IDENTIFIER_GLOBAL_VALUE (d);
else
{
type = build_function_type (type, void_list_node);
d = build_lang_decl (FUNCTION_DECL, d, type);
DECL_EXTERNAL (d) = 1;
TREE_PUBLIC (d) = 1;
DECL_ARTIFICIAL (d) = 1;
TREE_THIS_VOLATILE (d) = 1;
pushdecl_top_level (d);
make_function_rtl (d);
}
mark_used (d);
return d;
}
/* Get a bad_cast node for the program to throw... /* Get a bad_cast node for the program to throw...
See libstdc++/exception.cc for __throw_bad_cast */ See libstdc++/exception.cc for __throw_bad_cast */
...@@ -201,28 +171,27 @@ build_runtime_decl (name, type) ...@@ -201,28 +171,27 @@ build_runtime_decl (name, type)
static tree static tree
throw_bad_cast () throw_bad_cast ()
{ {
if (!throw_bad_cast_node) tree fn = get_identifier ("__throw_bad_cast");
throw_bad_cast_node = build_runtime_decl if (IDENTIFIER_GLOBAL_VALUE (fn))
("__throw_bad_cast", ptr_type_node); fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
fn = push_throw_library_fn (fn, ptr_type_node);
return build_call (throw_bad_cast_node, return build_call (fn, NULL_TREE);
TREE_TYPE (TREE_TYPE (throw_bad_cast_node)),
NULL_TREE);
} }
static tree static tree
throw_bad_typeid () throw_bad_typeid ()
{ {
if (!throw_bad_typeid_node) tree fn = get_identifier ("__throw_bad_cast");
throw_bad_typeid_node = build_runtime_decl if (IDENTIFIER_GLOBAL_VALUE (fn))
("__throw_bad_typeid", fn = IDENTIFIER_GLOBAL_VALUE (fn);
build_reference_type else
(build_qualified_type fn = push_throw_library_fn (fn, build_reference_type
(type_info_type_node, TYPE_QUAL_CONST))); (build_qualified_type
(type_info_type_node, TYPE_QUAL_CONST)));
return build_call (throw_bad_typeid_node, return build_call (fn, NULL_TREE);
TREE_TYPE (TREE_TYPE (throw_bad_typeid_node)),
NULL_TREE);
} }
/* Return a pointer to type_info function associated with the expression EXP. /* Return a pointer to type_info function associated with the expression EXP.
...@@ -420,17 +389,10 @@ get_tinfo_decl (type) ...@@ -420,17 +389,10 @@ get_tinfo_decl (type)
{ {
/* The tinfo decl is a function returning a reference to the type_info /* The tinfo decl is a function returning a reference to the type_info
object. */ object. */
d = build_lang_decl (FUNCTION_DECL, name, tinfo_decl_type); d = push_library_fn (name, tinfo_decl_type);
DECL_EXTERNAL (d) = 1;
TREE_PUBLIC (d) = 1;
DECL_ARTIFICIAL (d) = 1;
TREE_NOTHROW (d) = 1;
DECL_NOT_REALLY_EXTERN (d) = 1; DECL_NOT_REALLY_EXTERN (d) = 1;
SET_DECL_TINFO_FN_P (d); SET_DECL_TINFO_FN_P (d);
TREE_TYPE (name) = type; TREE_TYPE (name) = type;
pushdecl_top_level (d);
make_function_rtl (d);
mark_inline_for_output (d); mark_inline_for_output (d);
} }
else else
...@@ -468,7 +430,7 @@ tinfo_from_decl (expr) ...@@ -468,7 +430,7 @@ tinfo_from_decl (expr)
tree t; tree t;
if (!new_abi_rtti_p ()) if (!new_abi_rtti_p ())
t = build_call (expr, TREE_TYPE (tinfo_decl_type), NULL_TREE); t = build_call (expr, NULL_TREE);
else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE) else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
t = build_indirect_ref (expr, NULL); t = build_indirect_ref (expr, NULL);
else else
...@@ -814,24 +776,15 @@ build_dynamic_cast_1 (type, expr) ...@@ -814,24 +776,15 @@ build_dynamic_cast_1 (type, expr)
(NULL_TREE, ptrdiff_type_node, void_list_node)))); (NULL_TREE, ptrdiff_type_node, void_list_node))));
} }
tmp = build_function_type (ptr_type_node, tmp); tmp = build_function_type (ptr_type_node, tmp);
dcast_fn = build_lang_decl (FUNCTION_DECL,
get_identifier (name),
tmp);
DECL_EXTERNAL (dcast_fn) = 1;
TREE_PUBLIC (dcast_fn) = 1;
DECL_ARTIFICIAL (dcast_fn) = 1;
TREE_NOTHROW (dcast_fn) = 1;
pushdecl (dcast_fn);
if (new_abi_rtti_p ()) if (new_abi_rtti_p ())
/* We want its name mangling. */ /* We want its name mangling. */
set_mangled_name_for_decl (dcast_fn); dcast_fn = build_cp_library_fn_ptr (name, tmp);
make_function_rtl (dcast_fn); else
dcast_fn = build_library_fn_ptr (name, tmp);
pop_nested_namespace (ns); pop_nested_namespace (ns);
dynamic_cast_node = dcast_fn; dynamic_cast_node = dcast_fn;
} }
mark_used (dcast_fn); result = build_call (dcast_fn, elems);
result = build_call
(dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
if (tc == REFERENCE_TYPE) if (tc == REFERENCE_TYPE)
{ {
...@@ -912,19 +865,10 @@ expand_si_desc (tdecl, type) ...@@ -912,19 +865,10 @@ expand_si_desc (tdecl, type)
(NULL_TREE, const_string_type_node, tree_cons (NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node), (NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node))); void_list_node)));
tmp = build_function_type (void_type_node, tmp); fn = push_void_library_fn (fn, tmp);
fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn); fn = build_call (fn, elems);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn); finish_expr_stmt (fn);
} }
...@@ -1072,19 +1016,11 @@ expand_class_desc (tdecl, type) ...@@ -1072,19 +1016,11 @@ expand_class_desc (tdecl, type)
(NULL_TREE, const_string_type_node, tree_cons (NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons (NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
(NULL_TREE, sizetype, void_list_node)))); (NULL_TREE, sizetype, void_list_node))));
tmp = build_function_type (void_type_node, tmp);
fn = push_void_library_fn (fn, tmp);
fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn); fn = build_call (fn, elems);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn); finish_expr_stmt (fn);
} }
...@@ -1117,19 +1053,10 @@ expand_ptr_desc (tdecl, type) ...@@ -1117,19 +1053,10 @@ expand_ptr_desc (tdecl, type)
(NULL_TREE, const_string_type_node, tree_cons (NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node), (NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node))); void_list_node)));
tmp = build_function_type (void_type_node, tmp); fn = push_void_library_fn (fn, tmp);
fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn); fn = build_call (fn, elems);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn); finish_expr_stmt (fn);
} }
...@@ -1163,19 +1090,10 @@ expand_attr_desc (tdecl, type) ...@@ -1163,19 +1090,10 @@ expand_attr_desc (tdecl, type)
(NULL_TREE, integer_type_node, tree_cons (NULL_TREE, integer_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node), (NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node)))); void_list_node))));
tmp = build_function_type (void_type_node, tmp); fn = push_void_library_fn (fn, tmp);
fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn); fn = build_call (fn, elems);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn); finish_expr_stmt (fn);
} }
...@@ -1201,19 +1119,10 @@ expand_generic_desc (tdecl, type, fnname) ...@@ -1201,19 +1119,10 @@ expand_generic_desc (tdecl, type, fnname)
tmp = tree_cons tmp = tree_cons
(NULL_TREE, ptr_type_node, tree_cons (NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, const_string_type_node, void_list_node)); (NULL_TREE, const_string_type_node, void_list_node));
tmp = build_function_type (void_type_node, tmp); fn = push_void_library_fn (fn, tmp);
fn = build_lang_decl (FUNCTION_DECL, fn, tmp);
DECL_EXTERNAL (fn) = 1;
TREE_PUBLIC (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
TREE_NOTHROW (fn) = 1;
pushdecl_top_level (fn);
make_function_rtl (fn);
} }
mark_used (fn); fn = build_call (fn, elems);
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn); finish_expr_stmt (fn);
} }
......
...@@ -3046,8 +3046,8 @@ build_function_call_real (function, params, require_complete, flags) ...@@ -3046,8 +3046,8 @@ build_function_call_real (function, params, require_complete, flags)
} }
/* C++ */ /* C++ */
value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node; result = build_call (function, coerced_params);
result = build_call (function, value_type, coerced_params); value_type = TREE_TYPE (result);
if (require_complete) if (require_complete)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment