123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- /* Exception Handling interface routines.
- Copyright (C) 1996-2019 Free Software Foundation, Inc.
- Contributed by Mike Stump <mrs@cygnus.com>.
- This file is part of GCC.
- GCC is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 3, or (at your option) any later
- version.
- GCC is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
- /* 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
- struct function;
- struct eh_region_d;
- /* 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 transferred 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
- };
- /* A landing pad for a given exception region. Any transfer of control
- from the EH runtime to the function happens at a landing pad. */
- 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 transferred
- 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_code_label *landing_pad;
- /* The index of this landing pad within fun->eh->lp_array. */
- int index;
- };
- /* A catch handler associated with an ERT_TRY 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;
- };
- /* Describes one exception region. */
- 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;
- /* 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, va_gc> *region_array;
- /* The landing pads as an indexable array. */
- vec<eh_landing_pad, va_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. */
- hash_map<gimple *, int> *GTY(()) 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, va_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, va_gc> *GTY((tag ("1"))) arm_eabi;
- vec<uchar, va_gc> *GTY((tag ("0"))) other;
- } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
- };
- /* 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 void remove_eh_landing_pad (eh_landing_pad);
- extern void remove_eh_handler (eh_region);
- extern void remove_unreachable_eh_regions (sbitmap);
- extern bool current_function_has_exception_handlers (void);
- extern void output_function_exception_table (int);
- 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);
- extern void expand_builtin_init_dwarf_reg_sizes (tree);
- extern rtx expand_builtin_frob_return_addr (tree);
- 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);
- typedef tree (*duplicate_eh_regions_map) (tree, void *);
- extern hash_map<void *, void *> *duplicate_eh_regions
- (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
- extern void sjlj_emit_function_exit_after (rtx_insn *);
- extern void update_sjlj_context (void);
- 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 *insn, int ecf_flags, int lp_nr);
- extern void make_reg_eh_region_note_nothrow_nononlocal (rtx_insn *);
- extern void verify_eh_tree (struct function *);
- extern void dump_eh_tree (FILE *, struct function *);
- 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);
- extern eh_region get_eh_region_from_rtx (const_rtx);
- extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
- extern void finish_eh_generation (void);
- struct GTY(()) throw_stmt_node {
- gimple *stmt;
- int lp_nr;
- };
- extern hash_map<gimple *, int> *get_eh_throw_stmt_table (struct function *);
- extern void set_eh_throw_stmt_table (function *, hash_map<gimple *, int> *);
- 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)
- #endif
|