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
This commit is contained in:
parent
c3ab7a40d7
commit
0c11ada67b
@ -1,3 +1,27 @@
|
||||
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>
|
||||
|
||||
* call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as
|
||||
|
@ -364,13 +364,14 @@ build_addr_func (function)
|
||||
(TYPE_PTRMEMFUNC_P) must be handled by our callers. */
|
||||
|
||||
tree
|
||||
build_call (function, result_type, parms)
|
||||
tree function, result_type, parms;
|
||||
build_call (function, parms)
|
||||
tree function, parms;
|
||||
{
|
||||
int is_constructor = 0;
|
||||
int nothrow;
|
||||
tree tmp;
|
||||
tree decl;
|
||||
tree result_type;
|
||||
|
||||
function = build_addr_func (function);
|
||||
|
||||
@ -380,6 +381,8 @@ build_call (function, result_type, parms)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
result_type = TREE_TYPE (TREE_TYPE (TREE_TYPE (function)));
|
||||
|
||||
if (TREE_CODE (function) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL)
|
||||
decl = TREE_OPERAND (function, 0);
|
||||
@ -394,8 +397,14 @@ build_call (function, result_type, parms)
|
||||
if (decl && DECL_CONSTRUCTOR_P (decl))
|
||||
is_constructor = 1;
|
||||
|
||||
if (decl)
|
||||
my_friendly_assert (TREE_USED (decl), 990125);
|
||||
if (decl && ! TREE_USED (decl))
|
||||
{
|
||||
/* 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
|
||||
for tags in STL, which are used to control overload resolution.
|
||||
@ -4157,7 +4166,7 @@ build_over_call (cand, args, flags)
|
||||
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)
|
||||
return fn;
|
||||
fn = require_complete_type (fn);
|
||||
|
@ -577,8 +577,6 @@ enum cp_tree_index
|
||||
CPTI_TERMINATE,
|
||||
CPTI_ATEXIT,
|
||||
CPTI_DSO_HANDLE,
|
||||
CPTI_BAD_CAST,
|
||||
CPTI_BAD_TYPEID,
|
||||
CPTI_DCAST,
|
||||
|
||||
CPTI_MAX
|
||||
@ -686,12 +684,6 @@ extern tree cp_global_trees[CPTI_MAX];
|
||||
/* A pointer to `__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. */
|
||||
#define dynamic_cast_node cp_global_trees[CPTI_DCAST]
|
||||
|
||||
@ -3605,7 +3597,7 @@ extern tree build_vfield_ref 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_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 int null_ptr_cst_p PARAMS ((tree));
|
||||
extern tree type_decays_to PARAMS ((tree));
|
||||
@ -3753,12 +3745,16 @@ extern tree namespace_ancestor PARAMS ((tree, tree));
|
||||
extern tree unqualified_namespace_lookup PARAMS ((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 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 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 void shadow_tag PARAMS ((tree));
|
||||
extern tree groktypename PARAMS ((tree));
|
||||
|
208
gcc/cp/decl.c
208
gcc/cp/decl.c
@ -113,7 +113,6 @@ static void declare_namespace_level PARAMS ((void));
|
||||
static void signal_catch PARAMS ((int)) ATTRIBUTE_NORETURN;
|
||||
static void storedecls 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 unary_op_p PARAMS ((tree));
|
||||
static tree store_bindings PARAMS ((tree, tree));
|
||||
@ -133,6 +132,7 @@ static void set_identifier_type_value_with_scope
|
||||
PARAMS ((tree, tree, struct binding_level *));
|
||||
static void record_builtin_type PARAMS ((enum rid, const char *, tree));
|
||||
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 void bad_specifiers PARAMS ((tree, const char *, int, int, int, int,
|
||||
int));
|
||||
@ -5937,26 +5937,6 @@ record_unknown_type (type, name)
|
||||
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,
|
||||
and some nodes representing standard constants (0, 1, (void *)0).
|
||||
Initialize the global binding level.
|
||||
@ -6320,15 +6300,15 @@ init_decl_processing ()
|
||||
newtype = build_exception_variant
|
||||
(ptr_ftype_sizetype, add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1));
|
||||
deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);
|
||||
auto_function (ansi_opname[(int) NEW_EXPR], newtype);
|
||||
auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype);
|
||||
global_delete_fndecl = auto_function (ansi_opname[(int) DELETE_EXPR],
|
||||
deltype);
|
||||
auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
|
||||
push_cp_library_fn (ansi_opname[(int) NEW_EXPR], newtype);
|
||||
push_cp_library_fn (ansi_opname[(int) VEC_NEW_EXPR], newtype);
|
||||
global_delete_fndecl = push_cp_library_fn (ansi_opname[(int) DELETE_EXPR],
|
||||
deltype);
|
||||
push_cp_library_fn (ansi_opname[(int) VEC_DELETE_EXPR], deltype);
|
||||
}
|
||||
|
||||
abort_fndecl
|
||||
= define_function ("__pure_virtual", void_ftype, 0, 0);
|
||||
= build_library_fn_ptr ("__pure_virtual", void_ftype);
|
||||
|
||||
/* Perform other language dependent initializations. */
|
||||
init_class_processing ();
|
||||
@ -6461,47 +6441,17 @@ lang_print_error_function (file)
|
||||
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.
|
||||
|
||||
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. */
|
||||
|
||||
tree
|
||||
define_function (name, type, pfn, library_name)
|
||||
const char *name;
|
||||
tree type;
|
||||
void (*pfn) PARAMS ((tree));
|
||||
const char *library_name;
|
||||
{
|
||||
tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type);
|
||||
DECL_EXTERNAL (decl) = 1;
|
||||
TREE_PUBLIC (decl) = 1;
|
||||
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);
|
||||
DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
|
||||
|
||||
/* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
|
||||
we cannot change DECL_ASSEMBLER_NAME until we have installed this
|
||||
function in the namespace. */
|
||||
if (pfn) (*pfn) (decl);
|
||||
if (library_name)
|
||||
DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name);
|
||||
make_function_rtl (decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
||||
/* Wrapper around define_function, for the benefit of
|
||||
c_common_nodes_and_builtins.
|
||||
FUNCTION_CODE tells later passes how to compile calls to this function.
|
||||
See tree.h for its possible values. */
|
||||
|
||||
tree
|
||||
builtin_function (name, type, code, class, libname)
|
||||
const char *name;
|
||||
@ -6510,12 +6460,136 @@ builtin_function (name, type, code, class, libname)
|
||||
enum built_in_class class;
|
||||
const char *libname;
|
||||
{
|
||||
tree decl = define_function (name, type, (void (*) PARAMS ((tree)))pushdecl,
|
||||
libname);
|
||||
tree decl = build_library_fn_1 (get_identifier (name), type);
|
||||
DECL_BUILT_IN_CLASS (decl) = class;
|
||||
DECL_FUNCTION_CODE (decl) = code;
|
||||
|
||||
my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
|
||||
|
||||
/* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME,
|
||||
we cannot change DECL_ASSEMBLER_NAME until we have installed this
|
||||
function in the namespace. */
|
||||
pushdecl (decl);
|
||||
if (libname)
|
||||
DECL_ASSEMBLER_NAME (decl) = get_identifier (libname);
|
||||
make_function_rtl (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;
|
||||
}
|
||||
|
||||
/* Returns the _DECL for a library function with C linkage.
|
||||
We assume that such functions never throw; if this is incorrect,
|
||||
callers should unset TREE_NOTHROW. */
|
||||
|
||||
tree
|
||||
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;
|
||||
tree type;
|
||||
{
|
||||
return build_library_fn (get_identifier (name), type);
|
||||
}
|
||||
|
||||
/* Like build_cp_library_fn, but takes a C string instead of an
|
||||
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
|
||||
default copy constructors and such. But, an anonymous union
|
||||
@ -7984,7 +8058,7 @@ get_atexit_node ()
|
||||
|
||||
/* Now, build the function declaration. */
|
||||
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);
|
||||
pop_lang_context ();
|
||||
atexit_node = default_conversion (atexit_fndecl);
|
||||
|
@ -173,8 +173,9 @@ init_exception_processing ()
|
||||
|
||||
if (flag_honor_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_NOTHROW (terminate_node) = 1;
|
||||
if (flag_honor_std)
|
||||
pop_namespace ();
|
||||
|
||||
@ -253,16 +254,8 @@ call_eh_info ()
|
||||
t = build_pointer_type (t);
|
||||
|
||||
/* And now the function. */
|
||||
fn = build_lang_decl (FUNCTION_DECL, fn,
|
||||
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);
|
||||
fn = push_library_fn (fn, build_function_type (t, void_list_node));
|
||||
}
|
||||
mark_used (fn);
|
||||
return build_function_call (fn, NULL_TREE);
|
||||
}
|
||||
|
||||
@ -424,18 +417,12 @@ do_pop_exception ()
|
||||
{
|
||||
/* Declare void __cp_pop_exception (void *),
|
||||
as defined in exception.cc. */
|
||||
fn = build_lang_decl
|
||||
(FUNCTION_DECL, fn,
|
||||
build_function_type (void_type_node, tree_cons
|
||||
(NULL_TREE, ptr_type_node, void_list_node)));
|
||||
DECL_EXTERNAL (fn) = 1;
|
||||
TREE_PUBLIC (fn) = 1;
|
||||
DECL_ARTIFICIAL (fn) = 1;
|
||||
pushdecl_top_level (fn);
|
||||
make_function_rtl (fn);
|
||||
fn = push_void_library_fn
|
||||
(fn, tree_cons (NULL_TREE, ptr_type_node, void_list_node));
|
||||
/* This can throw if the destructor for the exception throws. */
|
||||
TREE_NOTHROW (fn) = 0;
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
/* Arrange to do a dynamically scoped cleanup upon exit from this region. */
|
||||
cleanup = lookup_name (get_identifier ("__exception_info"), 0);
|
||||
cleanup = build_function_call (fn, tree_cons
|
||||
@ -732,21 +719,13 @@ expand_end_eh_spec (raises, try_block)
|
||||
tmp = tree_cons
|
||||
(NULL_TREE, integer_type_node, tree_cons
|
||||
(NULL_TREE, TREE_TYPE (decl), void_list_node));
|
||||
tmp = build_function_type (void_type_node, 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);
|
||||
|
||||
fn = push_throw_library_fn (fn, tmp);
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
tmp = tree_cons (NULL_TREE, build_int_2 (count, 0),
|
||||
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_handler (blocks, handler);
|
||||
@ -799,19 +778,10 @@ alloc_eh_object (type)
|
||||
else
|
||||
{
|
||||
/* Declare __eh_alloc (size_t), as defined in exception.cc. */
|
||||
tree tmp;
|
||||
tmp = tree_cons (NULL_TREE, sizetype, void_list_node);
|
||||
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);
|
||||
tree tmp = tree_cons (NULL_TREE, sizetype, void_list_node);
|
||||
fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
exp = build_function_call (fn, tree_cons
|
||||
(NULL_TREE, size_in_bytes (type), NULL_TREE));
|
||||
exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
|
||||
@ -852,16 +822,11 @@ expand_throw (exp)
|
||||
{
|
||||
/* Declare _Jv_Throw (void *), as defined in Java's
|
||||
exception.cc. */
|
||||
tree tmp;
|
||||
tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
|
||||
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 tmp = tree_cons (NULL_TREE, ptr_type_node, void_list_node);
|
||||
tmp = build_function_type (ptr_type_node, tmp);
|
||||
fn = push_library_fn (fn, tmp);
|
||||
TREE_THIS_VOLATILE (fn) = 1;
|
||||
pushdecl_top_level (fn);
|
||||
make_function_rtl (fn);
|
||||
TREE_NOTHROW (fn) = 0;
|
||||
}
|
||||
|
||||
exp = build_function_call (fn, args);
|
||||
@ -974,17 +939,9 @@ expand_throw (exp)
|
||||
(NULL_TREE, ptr_type_node, tree_cons
|
||||
(NULL_TREE, ptr_type_node, tree_cons
|
||||
(NULL_TREE, cleanup_type, void_list_node)));
|
||||
fn = build_lang_decl (FUNCTION_DECL, fn,
|
||||
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);
|
||||
fn = push_void_library_fn (fn, tmp);
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
e = tree_cons (NULL_TREE, exp, tree_cons
|
||||
(NULL_TREE, throw_type, tree_cons
|
||||
(NULL_TREE, cleanup, NULL_TREE)));
|
||||
@ -1000,21 +957,10 @@ expand_throw (exp)
|
||||
if (IDENTIFIER_GLOBAL_VALUE (fn))
|
||||
fn = IDENTIFIER_GLOBAL_VALUE (fn);
|
||||
else
|
||||
{
|
||||
/* Declare void __uncatch_exception (void)
|
||||
as defined in exception.cc. */
|
||||
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);
|
||||
}
|
||||
/* Declare void __uncatch_exception (void)
|
||||
as defined in exception.cc. */
|
||||
fn = push_void_library_fn (fn, void_list_node);
|
||||
|
||||
mark_used (fn);
|
||||
exp = build_function_call (fn, NULL_TREE);
|
||||
}
|
||||
|
||||
|
@ -1868,8 +1868,7 @@ build_builtin_delete_call (addr)
|
||||
tree addr;
|
||||
{
|
||||
mark_used (global_delete_fndecl);
|
||||
return build_call (global_delete_fndecl,
|
||||
void_type_node, build_tree_list (NULL_TREE, addr));
|
||||
return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
|
||||
}
|
||||
|
||||
/* Generate a C++ "new" expression. DECL is either a TREE_LIST
|
||||
|
@ -2156,7 +2156,7 @@ emit_thunk (thunk_fndecl)
|
||||
for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
|
||||
t = tree_cons (NULL_TREE, a, t);
|
||||
t = nreverse (t);
|
||||
t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t);
|
||||
t = build_call (function, t);
|
||||
finish_return_stmt (t);
|
||||
|
||||
expand_body (finish_function (lineno, 0));
|
||||
|
155
gcc/cp/rtti.c
155
gcc/cp/rtti.c
@ -45,7 +45,6 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
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 PARAMS((tree));
|
||||
static tree get_tinfo_var PARAMS((tree));
|
||||
@ -165,35 +164,6 @@ build_headof (exp)
|
||||
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...
|
||||
|
||||
See libstdc++/exception.cc for __throw_bad_cast */
|
||||
@ -201,28 +171,27 @@ build_runtime_decl (name, type)
|
||||
static tree
|
||||
throw_bad_cast ()
|
||||
{
|
||||
if (!throw_bad_cast_node)
|
||||
throw_bad_cast_node = build_runtime_decl
|
||||
("__throw_bad_cast", ptr_type_node);
|
||||
tree fn = get_identifier ("__throw_bad_cast");
|
||||
if (IDENTIFIER_GLOBAL_VALUE (fn))
|
||||
fn = IDENTIFIER_GLOBAL_VALUE (fn);
|
||||
else
|
||||
fn = push_throw_library_fn (fn, ptr_type_node);
|
||||
|
||||
return build_call (throw_bad_cast_node,
|
||||
TREE_TYPE (TREE_TYPE (throw_bad_cast_node)),
|
||||
NULL_TREE);
|
||||
return build_call (fn, NULL_TREE);
|
||||
}
|
||||
|
||||
static tree
|
||||
throw_bad_typeid ()
|
||||
{
|
||||
if (!throw_bad_typeid_node)
|
||||
throw_bad_typeid_node = build_runtime_decl
|
||||
("__throw_bad_typeid",
|
||||
build_reference_type
|
||||
(build_qualified_type
|
||||
(type_info_type_node, TYPE_QUAL_CONST)));
|
||||
tree fn = get_identifier ("__throw_bad_cast");
|
||||
if (IDENTIFIER_GLOBAL_VALUE (fn))
|
||||
fn = IDENTIFIER_GLOBAL_VALUE (fn);
|
||||
else
|
||||
fn = push_throw_library_fn (fn, build_reference_type
|
||||
(build_qualified_type
|
||||
(type_info_type_node, TYPE_QUAL_CONST)));
|
||||
|
||||
return build_call (throw_bad_typeid_node,
|
||||
TREE_TYPE (TREE_TYPE (throw_bad_typeid_node)),
|
||||
NULL_TREE);
|
||||
return build_call (fn, NULL_TREE);
|
||||
}
|
||||
|
||||
/* Return a pointer to type_info function associated with the expression EXP.
|
||||
@ -420,17 +389,10 @@ get_tinfo_decl (type)
|
||||
{
|
||||
/* The tinfo decl is a function returning a reference to the type_info
|
||||
object. */
|
||||
d = build_lang_decl (FUNCTION_DECL, name, tinfo_decl_type);
|
||||
DECL_EXTERNAL (d) = 1;
|
||||
TREE_PUBLIC (d) = 1;
|
||||
DECL_ARTIFICIAL (d) = 1;
|
||||
TREE_NOTHROW (d) = 1;
|
||||
d = push_library_fn (name, tinfo_decl_type);
|
||||
DECL_NOT_REALLY_EXTERN (d) = 1;
|
||||
SET_DECL_TINFO_FN_P (d);
|
||||
TREE_TYPE (name) = type;
|
||||
|
||||
pushdecl_top_level (d);
|
||||
make_function_rtl (d);
|
||||
mark_inline_for_output (d);
|
||||
}
|
||||
else
|
||||
@ -468,7 +430,7 @@ tinfo_from_decl (expr)
|
||||
tree t;
|
||||
|
||||
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)
|
||||
t = build_indirect_ref (expr, NULL);
|
||||
else
|
||||
@ -814,24 +776,15 @@ build_dynamic_cast_1 (type, expr)
|
||||
(NULL_TREE, ptrdiff_type_node, void_list_node))));
|
||||
}
|
||||
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 ())
|
||||
/* We want its name mangling. */
|
||||
set_mangled_name_for_decl (dcast_fn);
|
||||
make_function_rtl (dcast_fn);
|
||||
/* We want its name mangling. */
|
||||
dcast_fn = build_cp_library_fn_ptr (name, tmp);
|
||||
else
|
||||
dcast_fn = build_library_fn_ptr (name, tmp);
|
||||
pop_nested_namespace (ns);
|
||||
dynamic_cast_node = dcast_fn;
|
||||
}
|
||||
mark_used (dcast_fn);
|
||||
result = build_call
|
||||
(dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems);
|
||||
result = build_call (dcast_fn, elems);
|
||||
|
||||
if (tc == REFERENCE_TYPE)
|
||||
{
|
||||
@ -912,19 +865,10 @@ expand_si_desc (tdecl, type)
|
||||
(NULL_TREE, const_string_type_node, tree_cons
|
||||
(NULL_TREE, build_pointer_type (type_info_type_node),
|
||||
void_list_node)));
|
||||
tmp = build_function_type (void_type_node, 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);
|
||||
fn = push_void_library_fn (fn, tmp);
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
fn = build_call (fn, elems);
|
||||
finish_expr_stmt (fn);
|
||||
}
|
||||
|
||||
@ -1072,19 +1016,11 @@ expand_class_desc (tdecl, type)
|
||||
(NULL_TREE, const_string_type_node, tree_cons
|
||||
(NULL_TREE, build_pointer_type (base_desc_type_node), tree_cons
|
||||
(NULL_TREE, sizetype, void_list_node))));
|
||||
tmp = build_function_type (void_type_node, 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);
|
||||
|
||||
fn = push_void_library_fn (fn, tmp);
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
fn = build_call (fn, elems);
|
||||
finish_expr_stmt (fn);
|
||||
}
|
||||
|
||||
@ -1117,19 +1053,10 @@ expand_ptr_desc (tdecl, type)
|
||||
(NULL_TREE, const_string_type_node, tree_cons
|
||||
(NULL_TREE, build_pointer_type (type_info_type_node),
|
||||
void_list_node)));
|
||||
tmp = build_function_type (void_type_node, 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);
|
||||
fn = push_void_library_fn (fn, tmp);
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
fn = build_call (fn, elems);
|
||||
finish_expr_stmt (fn);
|
||||
}
|
||||
|
||||
@ -1163,19 +1090,10 @@ expand_attr_desc (tdecl, type)
|
||||
(NULL_TREE, integer_type_node, tree_cons
|
||||
(NULL_TREE, build_pointer_type (type_info_type_node),
|
||||
void_list_node))));
|
||||
tmp = build_function_type (void_type_node, 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);
|
||||
fn = push_void_library_fn (fn, tmp);
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
fn = build_call (fn, elems);
|
||||
finish_expr_stmt (fn);
|
||||
}
|
||||
|
||||
@ -1201,19 +1119,10 @@ expand_generic_desc (tdecl, type, fnname)
|
||||
tmp = tree_cons
|
||||
(NULL_TREE, ptr_type_node, tree_cons
|
||||
(NULL_TREE, const_string_type_node, void_list_node));
|
||||
tmp = build_function_type (void_type_node, 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);
|
||||
fn = push_void_library_fn (fn, tmp);
|
||||
}
|
||||
|
||||
mark_used (fn);
|
||||
fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
|
||||
fn = build_call (fn, elems);
|
||||
finish_expr_stmt (fn);
|
||||
}
|
||||
|
||||
|
@ -3046,8 +3046,8 @@ build_function_call_real (function, params, require_complete, flags)
|
||||
}
|
||||
|
||||
/* C++ */
|
||||
value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
|
||||
result = build_call (function, value_type, coerced_params);
|
||||
result = build_call (function, coerced_params);
|
||||
value_type = TREE_TYPE (result);
|
||||
|
||||
if (require_complete)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user