aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@casey.cygnus.com>2000-03-10 09:25:45 +0000
committerJason Merrill <jason@gcc.gnu.org>2000-03-10 04:25:45 -0500
commit0c11ada67b89f4103c6c4abf680149bc3dee0959 (patch)
tree2abf6c15ae84cc0615afb845f3b88512998cf097 /gcc/cp
parentc3ab7a40d76cac8bca2e4b9592321156557c7278 (diff)
downloadgcc-0c11ada67b89f4103c6c4abf680149bc3dee0959.zip
gcc-0c11ada67b89f4103c6c4abf680149bc3dee0959.tar.gz
gcc-0c11ada67b89f4103c6c4abf680149bc3dee0959.tar.bz2
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
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog24
-rw-r--r--gcc/cp/call.c19
-rw-r--r--gcc/cp/cp-tree.h22
-rw-r--r--gcc/cp/decl.c190
-rw-r--r--gcc/cp/except.c94
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/rtti.c155
-rw-r--r--gcc/cp/typeck.c4
9 files changed, 235 insertions, 278 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 27b823e..e549057 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e15d4f0..40cd43d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -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);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9086292..f7baceb 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index b16d9d8..7133190 100644
--- a/gcc/cp/decl.c
+++ b/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,60 +6441,154 @@ 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)
+builtin_function (name, type, code, class, libname)
const char *name;
tree type;
- void (*pfn) PARAMS ((tree));
- const char *library_name;
+ int code;
+ enum built_in_class class;
+ const char *libname;
{
- 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;
+ 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);
- 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);
+ 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;
+}
-/* 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. */
+/* 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
-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;
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;
+ 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
@@ -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);
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index b8d4fa2..ae64e78 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -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);
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index a2e0d22..e448218 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 6e869f1..38e9c58 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -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));
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index f29da8c..15e4617 100644
--- a/gcc/cp/rtti.c
+++ b/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);
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 868ebec..aed8bb3 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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)
{