X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fexcept.h;h=5d461d7000b651e1016561a8f2e44ffeccf487f9;hb=42f4cf9571f5131e674b578c4634979ea727b137;hp=ba6f5929dd2da08a9df40fef4922e5a57a78fac5;hpb=4dd3de56566eb6af21e30145dcb9668d195a53d0;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/except.h b/gcc/except.h index ba6f5929dd2..5d461d7000b 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -1,6 +1,6 @@ /* Exception Handling interface routines. Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - 2007 Free Software Foundation, Inc. + 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Mike Stump . This file is part of GCC. @@ -19,55 +19,231 @@ You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ +/* No include guards here, but define an include file marker anyway, so + that the compiler can keep track of where this file is included. This + is e.g. used to avoid including this file in front-end specific files. */ +#ifndef GCC_EXCEPT_H +# define GCC_EXCEPT_H +#endif + +#include "hashtab.h" +#include "vecprim.h" +#include "vecir.h" struct function; +struct eh_region_d; +struct pointer_map_t; -/* Per-function EH data. Used only in except.c, but GC and others - manipulate pointers to the opaque type. */ -struct eh_status; +/* The type of an exception region. */ +enum eh_region_type +{ + /* CLEANUP regions implement e.g. destructors run when exiting a block. + They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH + nodes. It is expected by the runtime that cleanup regions will *not* + resume normal program flow, but will continue propagation of the + exception. */ + ERT_CLEANUP, + + /* TRY regions implement catching an exception. The list of types associated + with the attached catch handlers is examined in order by the runtime and + control is transfered to the appropriate handler. Note that a NULL type + list is a catch-all handler, and that it will catch *all* exceptions + including those originating from a different language. */ + ERT_TRY, + + /* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the + throw(type-list) specification that can be added to C++ functions. + The runtime examines the thrown exception vs the type list, and if + the exception does not match, transfers control to the handler. The + normal handler for C++ calls __cxa_call_unexpected. */ + ERT_ALLOWED_EXCEPTIONS, + + /* MUST_NOT_THROW regions prevent all exceptions from propagating. This + region type is used in C++ to surround destructors being run inside a + CLEANUP region. This differs from an ALLOWED_EXCEPTIONS region with + an empty type list in that the runtime is prepared to terminate the + program directly. We only generate code for MUST_NOT_THROW regions + along control paths that are already handling an exception within the + current function. */ + ERT_MUST_NOT_THROW +}; -/* Internal structure describing a region. */ -struct eh_region; -/* Test: is exception handling turned on? */ -extern int doing_eh (int); +/* A landing pad for a given exception region. Any transfer of control + from the EH runtime to the function happens at a landing pad. */ -/* Note that the current EH region (if any) may contain a throw, or a - call to a function which itself may contain a throw. */ -extern void note_eh_region_may_contain_throw (struct eh_region *); +struct GTY(()) eh_landing_pad_d +{ + /* The linked list of all landing pads associated with the region. */ + struct eh_landing_pad_d *next_lp; + + /* The region with which this landing pad is associated. */ + struct eh_region_d *region; + + /* At the gimple level, the location to which control will be transfered + for this landing pad. There can be both EH and normal edges into the + block containing the post-landing-pad label. */ + tree post_landing_pad; + + /* At the rtl level, the location to which the runtime will transfer + control. This differs from the post-landing-pad in that the target's + EXCEPTION_RECEIVER pattern will be expanded here, as well as other + bookkeeping specific to exceptions. There must not be normal edges + into the block containing the landing-pad label. */ + rtx landing_pad; + + /* The index of this landing pad within fun->eh->lp_array. */ + int index; +}; -/* Invokes CALLBACK for every exception handler label. Only used by old - loop hackery; should not be used by new code. */ -extern void for_each_eh_label (void (*) (rtx)); +/* A catch handler associated with an ERT_TRY region. */ -/* Invokes CALLBACK for every exception region in the current function. */ -extern void for_each_eh_region (void (*) (struct eh_region *)); +struct GTY(()) eh_catch_d +{ + /* The double-linked list of all catch handlers for the region. */ + struct eh_catch_d *next_catch; + struct eh_catch_d *prev_catch; + + /* A TREE_LIST of runtime type objects that this catch handler + will catch, or NULL if all exceptions are caught. */ + tree type_list; + + /* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries, + having been mapped by assign_filter_values. These integers are to be + compared against the __builtin_eh_filter value. */ + tree filter_list; + + /* The code that should be executed if this catch handler matches the + thrown exception. This label is only maintained until + pass_lower_eh_dispatch, at which point it is cleared. */ + tree label; +}; -/* Determine if the given INSN can throw an exception. */ -extern bool can_throw_internal_1 (int, bool); -extern bool can_throw_internal (const_rtx); -extern bool can_throw_external_1 (int, bool); -extern bool can_throw_external (const_rtx); +/* Describes one exception region. */ -/* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */ -extern unsigned int set_nothrow_function_flags (void); +struct GTY(()) eh_region_d +{ + /* The immediately surrounding region. */ + struct eh_region_d *outer; + + /* The list of immediately contained regions. */ + struct eh_region_d *inner; + struct eh_region_d *next_peer; + + /* The index of this region within fun->eh->region_array. */ + int index; + + /* Each region does exactly one thing. */ + enum eh_region_type type; + + /* Holds the action to perform based on the preceding type. */ + union eh_region_u { + struct eh_region_u_try { + /* The double-linked list of all catch handlers for this region. */ + struct eh_catch_d *first_catch; + struct eh_catch_d *last_catch; + } GTY ((tag ("ERT_TRY"))) eh_try; + + struct eh_region_u_allowed { + /* A TREE_LIST of runtime type objects allowed to pass. */ + tree type_list; + /* The code that should be executed if the thrown exception does + not match the type list. This label is only maintained until + pass_lower_eh_dispatch, at which point it is cleared. */ + tree label; + /* The integer that will be passed by the runtime to signal that + we should execute the code at LABEL. This integer is assigned + by assign_filter_values and is to be compared against the + __builtin_eh_filter value. */ + int filter; + } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed; + + struct eh_region_u_must_not_throw { + /* A function decl to be invoked if this region is actually reachable + from within the function, rather than implementable from the runtime. + The normal way for this to happen is for there to be a CLEANUP region + contained within this MUST_NOT_THROW region. Note that if the + runtime handles the MUST_NOT_THROW region, we have no control over + what termination function is called; it will be decided by the + personality function in effect for this CIE. */ + tree failure_decl; + /* The location assigned to the call of FAILURE_DECL, if expanded. */ + location_t failure_loc; + } GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw; + } GTY ((desc ("%0.type"))) u; + + /* The list of landing pads associated with this region. */ + struct eh_landing_pad_d *landing_pads; + + /* EXC_PTR and FILTER values copied from the runtime for this region. + Each region gets its own psuedos so that if there are nested exceptions + we do not overwrite the values of the first exception. */ + rtx exc_ptr_reg, filter_reg; + + /* True if this region should use __cxa_end_cleanup instead + of _Unwind_Resume. */ + bool use_cxa_end_cleanup; +}; + +typedef struct eh_landing_pad_d *eh_landing_pad; +typedef struct eh_catch_d *eh_catch; +typedef struct eh_region_d *eh_region; + +DEF_VEC_P(eh_region); +DEF_VEC_ALLOC_P(eh_region, gc); +DEF_VEC_ALLOC_P(eh_region, heap); + +DEF_VEC_P(eh_landing_pad); +DEF_VEC_ALLOC_P(eh_landing_pad, gc); + + +/* The exception status for each function. */ + +struct GTY(()) eh_status +{ + /* The tree of all regions for this function. */ + eh_region region_tree; + + /* The same information as an indexable array. */ + VEC(eh_region,gc) *region_array; + + /* The landing pads as an indexable array. */ + VEC(eh_landing_pad,gc) *lp_array; + + /* At the gimple level, a mapping from gimple statement to landing pad + or must-not-throw region. See record_stmt_eh_region. */ + htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table; + + /* All of the runtime type data used by the function. These objects + are emitted to the lang-specific-data-area for the function. */ + VEC(tree,gc) *ttype_data; + + /* The table of all action chains. These encode the eh_region tree in + a compact form for use by the runtime, and is also emitted to the + lang-specific-data-area. Note that the ARM EABI uses a different + format for the encoding than all other ports. */ + union eh_status_u { + VEC(tree,gc) * GTY((tag ("1"))) arm_eabi; + VEC(uchar,gc) * GTY((tag ("0"))) other; + } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data; +}; -/* After initial rtl generation, call back to finish generating - exception support code. */ -extern void finish_eh_generation (void); -extern void init_eh (void); +/* Invokes CALLBACK for every exception handler label. Only used by old + loop hackery; should not be used by new code. */ +extern void for_each_eh_label (void (*) (rtx)); + extern void init_eh_for_function (void); -extern rtx reachable_handlers (rtx); -extern void maybe_remove_eh_handler (rtx); +extern void remove_eh_landing_pad (eh_landing_pad); +extern void remove_eh_handler (eh_region); -extern void convert_from_eh_region_ranges (void); -extern unsigned int convert_to_eh_region_ranges (void); -extern void find_exception_handler_labels (void); extern bool current_function_has_exception_handlers (void); extern void output_function_exception_table (const char *); +extern rtx expand_builtin_eh_pointer (tree); +extern rtx expand_builtin_eh_filter (tree); +extern rtx expand_builtin_eh_copy_values (tree); extern void expand_builtin_unwind_init (void); extern rtx expand_builtin_eh_return_data_regno (tree); extern rtx expand_builtin_extract_return_addr (tree); @@ -77,100 +253,88 @@ extern rtx expand_builtin_dwarf_sp_column (void); extern void expand_builtin_eh_return (tree, tree); extern void expand_eh_return (void); extern rtx expand_builtin_extend_pointer (tree); -extern rtx get_exception_pointer (void); -extern rtx get_exception_filter (void); +extern void expand_dw2_landing_pad_for_region (eh_region); + typedef tree (*duplicate_eh_regions_map) (tree, void *); -extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, - void *, int, int); +extern struct pointer_map_t *duplicate_eh_regions + (struct function *, eh_region, int, duplicate_eh_regions_map, void *); extern void sjlj_emit_function_exit_after (rtx); -extern void default_init_unwind_resume_libfunc (void); - -extern struct eh_region *gen_eh_region_cleanup (struct eh_region *, - struct eh_region *); -extern struct eh_region *gen_eh_region_try (struct eh_region *); -extern struct eh_region *gen_eh_region_catch (struct eh_region *, tree); -extern struct eh_region *gen_eh_region_allowed (struct eh_region *, tree); -extern struct eh_region *gen_eh_region_must_not_throw (struct eh_region *); -extern int get_eh_region_number (struct eh_region *); -extern bool get_eh_region_may_contain_throw (struct eh_region *); -extern tree get_eh_region_tree_label (struct eh_region *); -extern void set_eh_region_tree_label (struct eh_region *, tree); - -extern void foreach_reachable_handler (int, bool, - void (*) (struct eh_region *, void *), - void *); - -extern void collect_eh_region_array (void); -extern void expand_resx_expr (tree); + +extern eh_region gen_eh_region_cleanup (eh_region); +extern eh_region gen_eh_region_try (eh_region); +extern eh_region gen_eh_region_allowed (eh_region, tree); +extern eh_region gen_eh_region_must_not_throw (eh_region); + +extern eh_catch gen_eh_region_catch (eh_region, tree); +extern eh_landing_pad gen_eh_landing_pad (eh_region); + +extern eh_region get_eh_region_from_number_fn (struct function *, int); +extern eh_region get_eh_region_from_number (int); +extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int); +extern eh_landing_pad get_eh_landing_pad_from_number (int); +extern eh_region get_eh_region_from_lp_number_fn (struct function *, int); +extern eh_region get_eh_region_from_lp_number (int); + +extern eh_region eh_region_outermost (struct function *, eh_region, eh_region); + +extern void make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr); +extern void make_reg_eh_region_note_nothrow_nononlocal (rtx); + extern void verify_eh_tree (struct function *); extern void dump_eh_tree (FILE *, struct function *); -extern bool eh_region_outer_p (struct function *, int, int); -extern int eh_region_outermost (struct function *, int, int); - -/* tree-eh.c */ -extern void add_stmt_to_eh_region_fn (struct function *, tree, int); -extern bool remove_stmt_from_eh_region_fn (struct function *, tree); -extern int lookup_stmt_eh_region_fn (struct function *, const_tree); -extern int lookup_stmt_eh_region (const_tree); -extern bool verify_eh_edges (tree); - -/* If non-NULL, this is a function that returns an expression to be - executed if an unhandled exception is propagated out of a cleanup - region. For example, in C++, an exception thrown by a destructor - during stack unwinding is required to result in a call to - `std::terminate', so the C++ version of this function returns a - CALL_EXPR for `std::terminate'. */ -extern tree (*lang_protect_cleanup_actions) (void); - -/* Return true if type A catches type B. */ -extern int (*lang_eh_type_covers) (tree a, tree b); - -/* Map a type to a runtime object to match type. */ -extern tree (*lang_eh_runtime_type) (tree); - - -/* Just because the user configured --with-sjlj-exceptions=no doesn't - mean that we can use call frame exceptions. Detect that the target - has appropriate support. */ - -#ifndef MUST_USE_SJLJ_EXCEPTIONS -# if !(defined (EH_RETURN_DATA_REGNO) \ - && (defined (TARGET_UNWIND_INFO) \ - || (DWARF2_UNWIND_INFO \ - && (defined (EH_RETURN_HANDLER_RTX) \ - || defined (HAVE_eh_return))))) -# define MUST_USE_SJLJ_EXCEPTIONS 1 -# else -# define MUST_USE_SJLJ_EXCEPTIONS 0 -# endif -#endif +void debug_eh_tree (struct function *); +extern void add_type_for_runtime (tree); +extern tree lookup_type_for_runtime (tree); +extern void assign_filter_values (void); -#ifdef CONFIG_SJLJ_EXCEPTIONS -# if CONFIG_SJLJ_EXCEPTIONS == 1 -# define USING_SJLJ_EXCEPTIONS 1 -# endif -# if CONFIG_SJLJ_EXCEPTIONS == 0 -# define USING_SJLJ_EXCEPTIONS 0 -# ifndef EH_RETURN_DATA_REGNO - #error "EH_RETURN_DATA_REGNO required" -# endif -# if !defined(EH_RETURN_HANDLER_RTX) && !defined(HAVE_eh_return) - #error "EH_RETURN_HANDLER_RTX or eh_return required" -# endif -# if !defined(DWARF2_UNWIND_INFO) && !defined(TARGET_UNWIND_INFO) - #error "{DWARF2,TARGET}_UNWIND_INFO required" -# endif -# endif -#else -# define USING_SJLJ_EXCEPTIONS MUST_USE_SJLJ_EXCEPTIONS -#endif +extern eh_region get_eh_region_from_rtx (const_rtx); +extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx); -struct throw_stmt_node GTY(()) -{ - tree stmt; - int region_nr; +struct GTY(()) throw_stmt_node { + gimple stmt; + int lp_nr; }; extern struct htab *get_eh_throw_stmt_table (struct function *); extern void set_eh_throw_stmt_table (struct function *, struct htab *); + +enum eh_personality_kind { + eh_personality_none, + eh_personality_any, + eh_personality_lang +}; + +extern enum eh_personality_kind +function_needs_eh_personality (struct function *); + +/* Pre-order iteration within the eh_region tree. */ + +static inline eh_region +ehr_next (eh_region r, eh_region start) +{ + if (r->inner) + r = r->inner; + else if (r->next_peer && r != start) + r = r->next_peer; + else + { + do + { + r = r->outer; + if (r == start) + return NULL; + } + while (r->next_peer == NULL); + r = r->next_peer; + } + return r; +} + +#define FOR_ALL_EH_REGION_AT(R, START) \ + for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START)) + +#define FOR_ALL_EH_REGION_FN(R, FN) \ + for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL)) + +#define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun)