aboutsummaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-09-13 19:40:33 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-09-13 19:40:33 +0000
commitf9417da1a250b18ea0ee2d493c0750e58aa87ab8 (patch)
tree5e937f9960fc5af8114c7b2d8943ecdd565debb2 /gcc/except.c
parent22f3450401afc7a025eec24ede6a947ffd7ad0f7 (diff)
downloadgcc-f9417da1a250b18ea0ee2d493c0750e58aa87ab8.zip
gcc-f9417da1a250b18ea0ee2d493c0750e58aa87ab8.tar.gz
gcc-f9417da1a250b18ea0ee2d493c0750e58aa87ab8.tar.bz2
langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
2009-09-13 Richard Guenther <rguenther@suse.de> Rafael Avila de Espindola <espindola@google.com> * langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define. (LANG_HOOKS_EH_PERSONALITY): Likewise. (LANG_HOOKS_INITIALIZER): Adjust. (lhd_pass_through_t): Declare. * langhooks.h (struct lang_hooks): Add eh_runtime_type and eh_personality. * langhooks.c (lhd_pass_through_t): New function. * dwarf2out.c (output_call_frame_info, dwarf2out_do_cfi_startproc, dwarf2out_begin_prologue): Use personality from current_function_decl. * expr.h (get_personality_function): Declare. * expr.c (get_personality_function): New function. (build_personality_function): Likewise. * libfuncs.h (libfunc_index): Remove LTI_eh_personality. (eh_personality_libfunc): Remove. * optabs.c (build_libfunc_function): New function split out from ... (init_one_libfunc): ... here. * tree.h (DECL_FUNCTION_PERSONALITY): New. (tree_function_decl): Add personality. (lhd_gcc_personality): Declare. (build_personality_function): Likewise. * tree.c (gcc_eh_personality_decl): New. (lhd_gcc_personality): New function. * except.h (lang_eh_runtime_type): Remove. (enum eh_personality_kind): New. (build_personality_function): Declare. (function_needs_eh_personality): Declare. * except.c (lang_eh_runtime_type): Remove. (function_needs_eh_personality): New function. (add_type_for_runtime): Call lang_hooks.type_for_runtime instead. (sjlj_emit_function_enter, output_function_exception_table): Use personality from current_function_decl. * tree-eh.c (lower_eh_constructs): Set DECL_FUNCTION_PERSONALITY. * tree-inline.c (tree_can_inline_p): Do not inline across different EH personalities. (expand_call_inline): Likewise. Adjust the callers EH personality. (tree_function_versioning): Copy DECL_FUNCTION_PERSONALITY. * cgraph.c (cgraph_add_new_function): Set DECL_FUNCTION_PERSONALITY. * Makefile.in (cgraph.o): Add $(EXCEPT_H) dependency. (c-parser.o): Likewise * c-tree.h (c_eh_initialized_p): Remove. (c_maybe_initialize_eh): Likewise. * c-decl.c (finish_decl): Don't call c_maybe_initialize_eh. (finish_decl): Don't call c_maybe_initialize_eh. (c_eh_initialized_p): Remove. (c_maybe_initialize_eh): Likewise. * c-parser.c (c_parser_omp_construct): Likewise. (c_parse_file): Initialize exception handling. objc/ * objc-act.c (objc_eh_runtime_type): Export. (objc_init_exceptions): Remove. Move warning code ... (objc_begin_try_stmt): ... here (objc_build_throw_stmt): ... and here. (objc_eh_personality_decl): New. (objc_eh_personality): New function. * objc-act.h (objc_eh_runtime_type): Declare. (objc_eh_personality): Likewise. * objc-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define. (LANG_HOOKS_EH_PERSONALITY): Likewise. cp/ * except.c (init_exception_processing): Do not set lang_eh_runtime_type. (choose_personality_routine): Do not set eh_personality_decl, set pragma_java_exceptions. * cp-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define. (LANG_HOOKS_EH_PERSONALITY): Likewise. (cp_eh_personality_decl): New. (cp_eh_personality): Likewise. * Make-lang.in (cp-lang.o): Add $(EXPR_H) and $(EXCEPT_H) dependencies. java/ * decl.c (do_nothing): Remove. (java_init_decl_processing): Do not set lang_eh_runtime_type. * Make-lang.in (lang.o): Add $(EXCEPT_H) dependency. * lang.c (java_eh_personality): New. (java_eh_personality_decl): Likewise. (LANG_HOOKS_EH_PERSONALITY): Define. ada/ * gcc-interface/misc.c (gnat_init_gcc_eh): Do not set lang_eh_runtime_type. (LANG_HOOKS_EH_PERSONALITY): Define. (gnat_eh_personality_decl): New. (gnat_eh_personality): Likewise. * Make-lang.in (misc.o): Add gt-ada-misc.h dependency. * config-lang.in (gtfiles): Add misc.c. fortran/ * f95-lang.c (gfc_maybe_initialize_eh): Do not init eh_personality_libfunc. Co-Authored-By: Rafael Avila de Espindola <espindola@google.com> From-SVN: r151676
Diffstat (limited to 'gcc/except.c')
-rw-r--r--gcc/except.c88
1 files changed, 76 insertions, 12 deletions
diff --git a/gcc/except.c b/gcc/except.c
index c97928e..9b6c24e 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -92,9 +92,6 @@ gimple (*lang_protect_cleanup_actions) (void);
/* Return true if type A catches type B. */
int (*lang_eh_type_covers) (tree a, tree b);
-/* Map a type to a runtime object to match type. */
-tree (*lang_eh_runtime_type) (tree);
-
/* A hash table of label to region number. */
struct GTY(()) ehl_map_entry {
@@ -1696,7 +1693,7 @@ add_type_for_runtime (tree type)
TREE_HASH (type), INSERT);
if (*slot == NULL)
{
- tree runtime = (*lang_eh_runtime_type) (type);
+ tree runtime = lang_hooks.eh_runtime_type (type);
*slot = tree_cons (type, runtime, NULL_TREE);
}
}
@@ -2424,6 +2421,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
{
rtx fn_begin, fc, mem, seq;
bool fn_begin_outside_block;
+ rtx personality = get_personality_function (current_function_decl);
fc = crtl->eh.sjlj_fc;
@@ -2432,9 +2430,9 @@ sjlj_emit_function_enter (rtx dispatch_label)
/* We're storing this libcall's address into memory instead of
calling it directly. Thus, we must call assemble_external_libcall
here, as we can not depend on emit_library_call to do it for us. */
- assemble_external_libcall (eh_personality_libfunc);
+ assemble_external_libcall (personality);
mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
- emit_move_insn (mem, eh_personality_libfunc);
+ emit_move_insn (mem, personality);
mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
if (crtl->uses_eh_lsda)
@@ -4394,7 +4392,7 @@ output_ttype (tree type, int tt_format, int tt_format_size)
static void
output_one_function_exception_table (const char * ARG_UNUSED (fnname),
- int section)
+ int section, rtx ARG_UNUSED (personality))
{
int tt_format, cs_format, lp_format, i, n;
#ifdef HAVE_AS_LEB128
@@ -4410,7 +4408,7 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
#ifdef TARGET_UNWIND_INFO
/* TODO: Move this into target file. */
fputs ("\t.personality\t", asm_out_file);
- output_addr_const (asm_out_file, eh_personality_libfunc);
+ output_addr_const (asm_out_file, personality);
fputs ("\n\t.handlerdata\n", asm_out_file);
/* Note that varasm still thinks we're in the function's code section.
The ".endp" directive that will immediately follow will take us back. */
@@ -4580,16 +4578,18 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
void
output_function_exception_table (const char * ARG_UNUSED (fnname))
{
+ rtx personality = get_personality_function (current_function_decl);
+
/* Not all functions need anything. */
if (! crtl->uses_eh_lsda)
return;
- if (eh_personality_libfunc)
- assemble_external_libcall (eh_personality_libfunc);
+ if (personality)
+ assemble_external_libcall (personality);
- output_one_function_exception_table (fnname, 0);
+ output_one_function_exception_table (fnname, 0, personality);
if (crtl->eh.call_site_record[1] != NULL)
- output_one_function_exception_table (fnname, 1);
+ output_one_function_exception_table (fnname, 1, personality);
switch_to_section (current_function_section ());
}
@@ -4606,6 +4606,70 @@ get_eh_throw_stmt_table (struct function *fun)
return fun->eh->throw_stmt_table;
}
+/* Return true if the function deeds a EH personality function. */
+
+enum eh_personality_kind
+function_needs_eh_personality (struct function *fn)
+{
+ struct eh_region_d *i;
+ int depth = 0;
+ enum eh_personality_kind kind = eh_personality_none;
+
+ i = fn->eh->region_tree;
+ if (!i)
+ return eh_personality_none;
+
+ while (1)
+ {
+ switch (i->type)
+ {
+ case ERT_TRY:
+ case ERT_THROW:
+ /* Do not need a EH personality function. */
+ break;
+
+ case ERT_MUST_NOT_THROW:
+ /* Always needs a EH personality function. */
+ return eh_personality_lang;
+
+ case ERT_CLEANUP:
+ /* Can do with any personality including the generic C one. */
+ kind = eh_personality_any;
+ break;
+
+ case ERT_CATCH:
+ case ERT_ALLOWED_EXCEPTIONS:
+ /* Always needs a EH personality function. The generic C
+ personality doesn't handle these even for empty type lists. */
+ return eh_personality_lang;
+
+ case ERT_UNKNOWN:
+ return eh_personality_lang;
+ }
+ /* If there are sub-regions, process them. */
+ if (i->inner)
+ i = i->inner, depth++;
+ /* If there are peers, process them. */
+ else if (i->next_peer)
+ i = i->next_peer;
+ /* Otherwise, step back up the tree to the next peer. */
+ else
+ {
+ do
+ {
+ i = i->outer;
+ depth--;
+ if (i == NULL)
+ return kind;
+ }
+ while (i->next_peer == NULL);
+ i = i->next_peer;
+ }
+ }
+
+ return kind;
+}
+
/* Dump EH information to OUT. */
void