This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
(C++) patch to reorganize internal FUNCTION_DECL generation
- To: gcc-patches at gcc dot gnu dot org
- Subject: (C++) patch to reorganize internal FUNCTION_DECL generation
- From: Jason Merrill <jason at cygnus dot com>
- Date: Fri, 10 Mar 2000 01:23:23 -0800
The last patch caused me to notice how many different places in the
compiler are generating FUNCTION_DECLs. This patch commonizes the
code in question.
I also deleted the middle parameter to build_call, since it can always be
extracted from the first parm.
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.
Index: call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.202
diff -c -p -r1.202 call.c
*** call.c 2000/03/09 20:34:51 1.202
--- call.c 2000/03/10 09:14:19
*************** build_addr_func (function)
*** 364,376 ****
(TYPE_PTRMEMFUNC_P) must be handled by our callers. */
tree
! build_call (function, result_type, parms)
! tree function, result_type, parms;
{
int is_constructor = 0;
int nothrow;
tree tmp;
tree decl;
function = build_addr_func (function);
--- 364,377 ----
(TYPE_PTRMEMFUNC_P) must be handled by our callers. */
tree
! 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);
*************** build_call (function, result_type, parms
*** 380,385 ****
--- 381,388 ----
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);
*************** build_call (function, result_type, parms
*** 394,401 ****
if (decl && DECL_CONSTRUCTOR_P (decl))
is_constructor = 1;
! if (decl)
! my_friendly_assert (TREE_USED (decl), 990125);
/* Don't pass empty class objects by value. This is useful
for tags in STL, which are used to control overload resolution.
--- 397,410 ----
if (decl && DECL_CONSTRUCTOR_P (decl))
is_constructor = 1;
! 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.
*************** build_over_call (cand, args, flags)
*** 4157,4163 ****
return exp;
}
! fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args);
if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
return fn;
fn = require_complete_type (fn);
--- 4166,4172 ----
return exp;
}
! fn = build_call (fn, converted_args);
if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE)
return fn;
fn = require_complete_type (fn);
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.413
diff -c -p -r1.413 cp-tree.h
*** cp-tree.h 2000/03/05 10:22:16 1.413
--- cp-tree.h 2000/03/10 09:14:23
*************** enum cp_tree_index
*** 577,584 ****
CPTI_TERMINATE,
CPTI_ATEXIT,
CPTI_DSO_HANDLE,
- CPTI_BAD_CAST,
- CPTI_BAD_TYPEID,
CPTI_DCAST,
CPTI_MAX
--- 577,582 ----
*************** extern tree cp_global_trees[CPTI_MAX];
*** 686,697 ****
/* 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]
--- 684,689 ----
*************** extern tree build_vfield_ref PARAMS ((
*** 3605,3611 ****
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_method_call PARAMS ((tree, tree, tree, tree, int));
extern int null_ptr_cst_p PARAMS ((tree));
extern tree type_decays_to PARAMS ((tree));
--- 3597,3603 ----
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));
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));
*************** extern tree namespace_ancestor PARAMS
*** 3753,3764 ****
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 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));
--- 3745,3760 ----
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 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 check_tag_decl PARAMS ((tree));
extern void shadow_tag PARAMS ((tree));
extern tree groktypename PARAMS ((tree));
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.561
diff -c -p -r1.561 decl.c
*** decl.c 2000/03/09 20:34:51 1.561
--- decl.c 2000/03/10 09:14:34
*************** static void declare_namespace_level PARA
*** 113,119 ****
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));
--- 113,118 ----
*************** static void set_identifier_type_value_wi
*** 133,138 ****
--- 132,138 ----
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));
*************** record_unknown_type (type, name)
*** 5937,5962 ****
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.
--- 5937,5942 ----
*************** init_decl_processing ()
*** 6320,6334 ****
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);
}
abort_fndecl
! = define_function ("__pure_virtual", void_ftype, 0, 0);
/* Perform other language dependent initializations. */
init_class_processing ();
--- 6300,6314 ----
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);
! 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
! = build_library_fn_ptr ("__pure_virtual", void_ftype);
/* Perform other language dependent initializations. */
init_class_processing ();
*************** lang_print_error_function (file)
*** 6461,6520 ****
maybe_print_template_context ();
}
! /* 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,
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;
tree type;
- int code;
- enum built_in_class class;
- const char *libname;
{
! tree decl = define_function (name, type, (void (*) PARAMS ((tree)))pushdecl,
! libname);
! DECL_BUILT_IN_CLASS (decl) = class;
! DECL_FUNCTION_CODE (decl) = code;
! return decl;
}
/* When we call finish_struct for an anonymous union, we create
--- 6441,6594 ----
maybe_print_template_context ();
}
! /* 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.
+
+ 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
! builtin_function (name, type, code, class, libname)
const char *name;
tree type;
! int code;
! enum built_in_class class;
! const char *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
*************** get_atexit_node ()
*** 7984,7990 ****
/* Now, build the function declaration. */
push_lang_context (lang_name_c);
! atexit_fndecl = define_function (name, fn_type, /*pfn=*/0, NULL_PTR);
mark_used (atexit_fndecl);
pop_lang_context ();
atexit_node = default_conversion (atexit_fndecl);
--- 8058,8064 ----
/* Now, build the function declaration. */
push_lang_context (lang_name_c);
! atexit_fndecl = build_library_fn_ptr (name, fn_type);
mark_used (atexit_fndecl);
pop_lang_context ();
atexit_node = default_conversion (atexit_fndecl);
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/except.c,v
retrieving revision 1.99
diff -c -p -r1.99 except.c
*** except.c 2000/03/09 20:34:52 1.99
--- except.c 2000/03/10 09:14:39
*************** init_exception_processing ()
*** 173,180 ****
if (flag_honor_std)
push_namespace (get_identifier ("std"));
! terminate_node = auto_function (get_identifier ("terminate"), vtype);
TREE_THIS_VOLATILE (terminate_node) = 1;
if (flag_honor_std)
pop_namespace ();
--- 173,181 ----
if (flag_honor_std)
push_namespace (get_identifier ("std"));
! 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 ();
*************** call_eh_info ()
*** 253,268 ****
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);
}
- mark_used (fn);
return build_function_call (fn, NULL_TREE);
}
--- 254,261 ----
t = build_pointer_type (t);
/* And now the function. */
! fn = push_library_fn (fn, build_function_type (t, void_list_node));
}
return build_function_call (fn, NULL_TREE);
}
*************** do_pop_exception ()
*** 424,441 ****
{
/* 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);
}
- 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
--- 417,428 ----
{
/* Declare void __cp_pop_exception (void *),
as defined in exception.cc. */
! 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;
}
/* 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
*************** expand_end_eh_spec (raises, try_block)
*** 732,752 ****
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);
}
- 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);
finish_expr_stmt (tmp);
finish_handler (blocks, handler);
--- 719,731 ----
tmp = tree_cons
(NULL_TREE, integer_type_node, tree_cons
(NULL_TREE, TREE_TYPE (decl), void_list_node));
!
! fn = push_throw_library_fn (fn, tmp);
}
tmp = tree_cons (NULL_TREE, build_int_2 (count, 0),
tree_cons (NULL_TREE, decl, NULL_TREE));
! tmp = build_call (fn, tmp);
finish_expr_stmt (tmp);
finish_handler (blocks, handler);
*************** alloc_eh_object (type)
*** 799,817 ****
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);
}
- 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);
--- 778,787 ----
else
{
/* Declare __eh_alloc (size_t), as defined in exception.cc. */
! tree tmp = tree_cons (NULL_TREE, sizetype, void_list_node);
! fn = push_library_fn (fn, build_function_type (ptr_type_node, tmp));
}
exp = build_function_call (fn, tree_cons
(NULL_TREE, size_in_bytes (type), NULL_TREE));
exp = build1 (NOP_EXPR, build_pointer_type (type), exp);
*************** expand_throw (exp)
*** 852,867 ****
{
/* 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_THIS_VOLATILE (fn) = 1;
! pushdecl_top_level (fn);
! make_function_rtl (fn);
}
exp = build_function_call (fn, args);
--- 822,832 ----
{
/* Declare _Jv_Throw (void *), as defined in Java's
exception.cc. */
! 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;
! TREE_NOTHROW (fn) = 0;
}
exp = build_function_call (fn, args);
*************** expand_throw (exp)
*** 974,990 ****
(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);
}
- mark_used (fn);
e = tree_cons (NULL_TREE, exp, tree_cons
(NULL_TREE, throw_type, tree_cons
(NULL_TREE, cleanup, NULL_TREE)));
--- 939,947 ----
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, cleanup_type, void_list_node)));
! fn = push_void_library_fn (fn, tmp);
}
e = tree_cons (NULL_TREE, exp, tree_cons
(NULL_TREE, throw_type, tree_cons
(NULL_TREE, cleanup, NULL_TREE)));
*************** expand_throw (exp)
*** 1000,1020 ****
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);
! }
- mark_used (fn);
exp = build_function_call (fn, NULL_TREE);
}
--- 957,966 ----
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
! /* Declare void __uncatch_exception (void)
! as defined in exception.cc. */
! fn = push_void_library_fn (fn, void_list_node);
exp = build_function_call (fn, NULL_TREE);
}
Index: init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.173
diff -c -p -r1.173 init.c
*** init.c 2000/03/07 11:41:21 1.173
--- init.c 2000/03/10 09:16:44
*************** build_builtin_delete_call (addr)
*** 1868,1875 ****
tree addr;
{
mark_used (global_delete_fndecl);
! return build_call (global_delete_fndecl,
! void_type_node, build_tree_list (NULL_TREE, addr));
}
/* Generate a C++ "new" expression. DECL is either a TREE_LIST
--- 1868,1874 ----
tree addr;
{
mark_used (global_delete_fndecl);
! return build_call (global_delete_fndecl, build_tree_list (NULL_TREE, addr));
}
/* Generate a C++ "new" expression. DECL is either a TREE_LIST
Index: method.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/method.c,v
retrieving revision 1.140
diff -c -p -r1.140 method.c
*** method.c 2000/03/07 20:39:07 1.140
--- method.c 2000/03/10 09:16:45
*************** emit_thunk (thunk_fndecl)
*** 2156,2162 ****
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);
finish_return_stmt (t);
expand_body (finish_function (lineno, 0));
--- 2156,2162 ----
for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a))
t = tree_cons (NULL_TREE, a, t);
t = nreverse (t);
! t = build_call (function, t);
finish_return_stmt (t);
expand_body (finish_function (lineno, 0));
Index: rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.64
diff -c -p -r1.64 rtti.c
*** rtti.c 2000/03/09 20:34:52 1.64
--- rtti.c 2000/03/10 09:16:47
*************** Boston, MA 02111-1307, USA. */
*** 45,51 ****
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));
--- 45,50 ----
*************** build_headof (exp)
*** 165,199 ****
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 */
--- 164,169 ----
*************** build_runtime_decl (name, type)
*** 201,228 ****
static tree
throw_bad_cast ()
{
! if (!throw_bad_cast_node)
! throw_bad_cast_node = build_runtime_decl
! ("__throw_bad_cast", ptr_type_node);
! return build_call (throw_bad_cast_node,
! TREE_TYPE (TREE_TYPE (throw_bad_cast_node)),
! 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)));
! return build_call (throw_bad_typeid_node,
! TREE_TYPE (TREE_TYPE (throw_bad_typeid_node)),
! NULL_TREE);
}
/* Return a pointer to type_info function associated with the expression EXP.
--- 171,197 ----
static tree
throw_bad_cast ()
{
! 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 (fn, NULL_TREE);
}
static tree
throw_bad_typeid ()
{
! 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 (fn, NULL_TREE);
}
/* Return a pointer to type_info function associated with the expression EXP.
*************** get_tinfo_decl (type)
*** 420,436 ****
{
/* 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;
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
--- 389,398 ----
{
/* The tinfo decl is a function returning a reference to the type_info
object. */
! d = push_library_fn (name, tinfo_decl_type);
DECL_NOT_REALLY_EXTERN (d) = 1;
SET_DECL_TINFO_FN_P (d);
TREE_TYPE (name) = type;
mark_inline_for_output (d);
}
else
*************** tinfo_from_decl (expr)
*** 468,474 ****
tree t;
if (!new_abi_rtti_p ())
! t = build_call (expr, TREE_TYPE (tinfo_decl_type), NULL_TREE);
else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
t = build_indirect_ref (expr, NULL);
else
--- 430,436 ----
tree t;
if (!new_abi_rtti_p ())
! t = build_call (expr, NULL_TREE);
else if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE)
t = build_indirect_ref (expr, NULL);
else
*************** build_dynamic_cast_1 (type, expr)
*** 814,837 ****
(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);
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);
if (tc == REFERENCE_TYPE)
{
--- 776,790 ----
(NULL_TREE, ptrdiff_type_node, void_list_node))));
}
tmp = build_function_type (ptr_type_node, tmp);
if (new_abi_rtti_p ())
! /* 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;
}
! result = build_call (dcast_fn, elems);
if (tc == REFERENCE_TYPE)
{
*************** expand_si_desc (tdecl, type)
*** 912,930 ****
(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);
}
! mark_used (fn);
! fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn);
}
--- 865,874 ----
(NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node)));
! fn = push_void_library_fn (fn, tmp);
}
! fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
*************** expand_class_desc (tdecl, type)
*** 1072,1090 ****
(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);
}
! mark_used (fn);
! fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn);
}
--- 1016,1026 ----
(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))));
!
! fn = push_void_library_fn (fn, tmp);
}
! fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
*************** expand_ptr_desc (tdecl, type)
*** 1117,1135 ****
(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);
}
! mark_used (fn);
! fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn);
}
--- 1053,1062 ----
(NULL_TREE, const_string_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node)));
! fn = push_void_library_fn (fn, tmp);
}
! fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
*************** expand_attr_desc (tdecl, type)
*** 1163,1181 ****
(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);
}
! mark_used (fn);
! fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn);
}
--- 1090,1099 ----
(NULL_TREE, integer_type_node, tree_cons
(NULL_TREE, build_pointer_type (type_info_type_node),
void_list_node))));
! fn = push_void_library_fn (fn, tmp);
}
! fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
*************** expand_generic_desc (tdecl, type, fnname
*** 1201,1219 ****
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);
}
! mark_used (fn);
! fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
finish_expr_stmt (fn);
}
--- 1119,1128 ----
tmp = tree_cons
(NULL_TREE, ptr_type_node, tree_cons
(NULL_TREE, const_string_type_node, void_list_node));
! fn = push_void_library_fn (fn, tmp);
}
! fn = build_call (fn, elems);
finish_expr_stmt (fn);
}
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.261
diff -c -p -r1.261 typeck.c
*** typeck.c 2000/03/08 11:21:28 1.261
--- typeck.c 2000/03/10 09:16:53
*************** build_function_call_real (function, para
*** 3046,3053 ****
}
/* C++ */
! value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node;
! result = build_call (function, value_type, coerced_params);
if (require_complete)
{
--- 3046,3053 ----
}
/* C++ */
! result = build_call (function, coerced_params);
! value_type = TREE_TYPE (result);
if (require_complete)
{