Implemented project structure
This commit is contained in:
@@ -0,0 +1,334 @@
|
||||
/* Exception Handling interface routines.
|
||||
Copyright (C) 1996-2023 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. */
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user