Home | History | Annotate | Download | only in include
      1 /* Exception Handling interface routines.
      2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
      3    2007, 2008, 2009, 2010  Free Software Foundation, Inc.
      4    Contributed by Mike Stump <mrs (at) cygnus.com>.
      5 
      6 This file is part of GCC.
      7 
      8 GCC is free software; you can redistribute it and/or modify it under
      9 the terms of the GNU General Public License as published by the Free
     10 Software Foundation; either version 3, or (at your option) any later
     11 version.
     12 
     13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     16 for more details.
     17 
     18 You should have received a copy of the GNU General Public License
     19 along with GCC; see the file COPYING3.  If not see
     20 <http://www.gnu.org/licenses/>.  */
     21 
     22 /* No include guards here, but define an include file marker anyway, so
     23    that the compiler can keep track of where this file is included.  This
     24    is e.g. used to avoid including this file in front-end specific files.  */
     25 #ifndef GCC_EXCEPT_H
     26 #  define GCC_EXCEPT_H
     27 #endif
     28 
     29 #include "hashtab.h"
     30 #include "vecprim.h"
     31 #include "vecir.h"
     32 
     33 struct function;
     34 struct eh_region_d;
     35 struct pointer_map_t;
     36 
     37 /* The type of an exception region.  */
     38 enum eh_region_type
     39 {
     40   /* CLEANUP regions implement e.g. destructors run when exiting a block.
     41      They can be generated from both GIMPLE_TRY_FINALLY and GIMPLE_TRY_CATCH
     42      nodes.  It is expected by the runtime that cleanup regions will *not*
     43      resume normal program flow, but will continue propagation of the
     44      exception.  */
     45   ERT_CLEANUP,
     46 
     47   /* TRY regions implement catching an exception.  The list of types associated
     48      with the attached catch handlers is examined in order by the runtime and
     49      control is transfered to the appropriate handler.  Note that a NULL type
     50      list is a catch-all handler, and that it will catch *all* exceptions
     51      including those originating from a different language.  */
     52   ERT_TRY,
     53 
     54   /* ALLOWED_EXCEPTIONS regions implement exception filtering, e.g. the
     55      throw(type-list) specification that can be added to C++ functions.
     56      The runtime examines the thrown exception vs the type list, and if
     57      the exception does not match, transfers control to the handler.  The
     58      normal handler for C++ calls __cxa_call_unexpected.  */
     59   ERT_ALLOWED_EXCEPTIONS,
     60 
     61   /* MUST_NOT_THROW regions prevent all exceptions from propagating.  This
     62      region type is used in C++ to surround destructors being run inside a
     63      CLEANUP region.  This differs from an ALLOWED_EXCEPTIONS region with
     64      an empty type list in that the runtime is prepared to terminate the
     65      program directly.  We only generate code for MUST_NOT_THROW regions
     66      along control paths that are already handling an exception within the
     67      current function.  */
     68   ERT_MUST_NOT_THROW
     69 };
     70 
     71 
     72 /* A landing pad for a given exception region.  Any transfer of control
     73    from the EH runtime to the function happens at a landing pad.  */
     74 
     75 struct GTY(()) eh_landing_pad_d
     76 {
     77   /* The linked list of all landing pads associated with the region.  */
     78   struct eh_landing_pad_d *next_lp;
     79 
     80   /* The region with which this landing pad is associated.  */
     81   struct eh_region_d *region;
     82 
     83   /* At the gimple level, the location to which control will be transfered
     84      for this landing pad.  There can be both EH and normal edges into the
     85      block containing the post-landing-pad label.  */
     86   tree post_landing_pad;
     87 
     88   /* At the rtl level, the location to which the runtime will transfer
     89      control.  This differs from the post-landing-pad in that the target's
     90      EXCEPTION_RECEIVER pattern will be expanded here, as well as other
     91      bookkeeping specific to exceptions.  There must not be normal edges
     92      into the block containing the landing-pad label.  */
     93   rtx landing_pad;
     94 
     95   /* The index of this landing pad within fun->eh->lp_array.  */
     96   int index;
     97 };
     98 
     99 /* A catch handler associated with an ERT_TRY region.  */
    100 
    101 struct GTY(()) eh_catch_d
    102 {
    103   /* The double-linked list of all catch handlers for the region.  */
    104   struct eh_catch_d *next_catch;
    105   struct eh_catch_d *prev_catch;
    106 
    107   /* A TREE_LIST of runtime type objects that this catch handler
    108      will catch, or NULL if all exceptions are caught.  */
    109   tree type_list;
    110 
    111   /* A TREE_LIST of INTEGER_CSTs that correspond to the type_list entries,
    112      having been mapped by assign_filter_values.  These integers are to be
    113      compared against the __builtin_eh_filter value.  */
    114   tree filter_list;
    115 
    116   /* The code that should be executed if this catch handler matches the
    117      thrown exception.  This label is only maintained until
    118      pass_lower_eh_dispatch, at which point it is cleared.  */
    119   tree label;
    120 };
    121 
    122 /* Describes one exception region.  */
    123 
    124 struct GTY(()) eh_region_d
    125 {
    126   /* The immediately surrounding region.  */
    127   struct eh_region_d *outer;
    128 
    129   /* The list of immediately contained regions.  */
    130   struct eh_region_d *inner;
    131   struct eh_region_d *next_peer;
    132 
    133   /* The index of this region within fun->eh->region_array.  */
    134   int index;
    135 
    136   /* Each region does exactly one thing.  */
    137   enum eh_region_type type;
    138 
    139   /* Holds the action to perform based on the preceding type.  */
    140   union eh_region_u {
    141     struct eh_region_u_try {
    142       /* The double-linked list of all catch handlers for this region.  */
    143       struct eh_catch_d *first_catch;
    144       struct eh_catch_d *last_catch;
    145     } GTY ((tag ("ERT_TRY"))) eh_try;
    146 
    147     struct eh_region_u_allowed {
    148       /* A TREE_LIST of runtime type objects allowed to pass.  */
    149       tree type_list;
    150       /* The code that should be executed if the thrown exception does
    151 	 not match the type list.  This label is only maintained until
    152 	 pass_lower_eh_dispatch, at which point it is cleared.  */
    153       tree label;
    154       /* The integer that will be passed by the runtime to signal that
    155 	 we should execute the code at LABEL.  This integer is assigned
    156 	 by assign_filter_values and is to be compared against the
    157 	 __builtin_eh_filter value.  */
    158       int filter;
    159     } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed;
    160 
    161     struct eh_region_u_must_not_throw {
    162       /* A function decl to be invoked if this region is actually reachable
    163 	 from within the function, rather than implementable from the runtime.
    164 	 The normal way for this to happen is for there to be a CLEANUP region
    165 	 contained within this MUST_NOT_THROW region.  Note that if the
    166 	 runtime handles the MUST_NOT_THROW region, we have no control over
    167 	 what termination function is called; it will be decided by the
    168 	 personality function in effect for this CIE.  */
    169       tree failure_decl;
    170       /* The location assigned to the call of FAILURE_DECL, if expanded.  */
    171       location_t failure_loc;
    172     } GTY ((tag ("ERT_MUST_NOT_THROW"))) must_not_throw;
    173   } GTY ((desc ("%0.type"))) u;
    174 
    175   /* The list of landing pads associated with this region.  */
    176   struct eh_landing_pad_d *landing_pads;
    177 
    178   /* EXC_PTR and FILTER values copied from the runtime for this region.
    179      Each region gets its own psuedos so that if there are nested exceptions
    180      we do not overwrite the values of the first exception.  */
    181   rtx exc_ptr_reg, filter_reg;
    182 
    183   /* True if this region should use __cxa_end_cleanup instead
    184      of _Unwind_Resume.  */
    185   bool use_cxa_end_cleanup;
    186 };
    187 
    188 typedef struct eh_landing_pad_d *eh_landing_pad;
    189 typedef struct eh_catch_d *eh_catch;
    190 typedef struct eh_region_d *eh_region;
    191 
    192 DEF_VEC_P(eh_region);
    193 DEF_VEC_ALLOC_P(eh_region, gc);
    194 DEF_VEC_ALLOC_P(eh_region, heap);
    195 
    196 DEF_VEC_P(eh_landing_pad);
    197 DEF_VEC_ALLOC_P(eh_landing_pad, gc);
    198 
    199 
    200 /* The exception status for each function.  */
    201 
    202 struct GTY(()) eh_status
    203 {
    204   /* The tree of all regions for this function.  */
    205   eh_region region_tree;
    206 
    207   /* The same information as an indexable array.  */
    208   VEC(eh_region,gc) *region_array;
    209 
    210   /* The landing pads as an indexable array.  */
    211   VEC(eh_landing_pad,gc) *lp_array;
    212 
    213   /* At the gimple level, a mapping from gimple statement to landing pad
    214      or must-not-throw region.  See record_stmt_eh_region.  */
    215   htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table;
    216 
    217   /* All of the runtime type data used by the function.  These objects
    218      are emitted to the lang-specific-data-area for the function.  */
    219   VEC(tree,gc) *ttype_data;
    220 
    221   /* The table of all action chains.  These encode the eh_region tree in
    222      a compact form for use by the runtime, and is also emitted to the
    223      lang-specific-data-area.  Note that the ARM EABI uses a different
    224      format for the encoding than all other ports.  */
    225   union eh_status_u {
    226     VEC(tree,gc) * GTY((tag ("1"))) arm_eabi;
    227     VEC(uchar,gc) * GTY((tag ("0"))) other;
    228   } GTY ((desc ("targetm.arm_eabi_unwinder"))) ehspec_data;
    229 };
    230 
    231 
    232 /* Invokes CALLBACK for every exception handler label.  Only used by old
    233    loop hackery; should not be used by new code.  */
    234 extern void for_each_eh_label (void (*) (rtx));
    235 
    236 extern void init_eh_for_function (void);
    237 
    238 extern void remove_eh_landing_pad (eh_landing_pad);
    239 extern void remove_eh_handler (eh_region);
    240 
    241 extern bool current_function_has_exception_handlers (void);
    242 extern void output_function_exception_table (const char *);
    243 
    244 extern rtx expand_builtin_eh_pointer (tree);
    245 extern rtx expand_builtin_eh_filter (tree);
    246 extern rtx expand_builtin_eh_copy_values (tree);
    247 extern void expand_builtin_unwind_init (void);
    248 extern rtx expand_builtin_eh_return_data_regno (tree);
    249 extern rtx expand_builtin_extract_return_addr (tree);
    250 extern void expand_builtin_init_dwarf_reg_sizes (tree);
    251 extern rtx expand_builtin_frob_return_addr (tree);
    252 extern rtx expand_builtin_dwarf_sp_column (void);
    253 extern void expand_builtin_eh_return (tree, tree);
    254 extern void expand_eh_return (void);
    255 extern rtx expand_builtin_extend_pointer (tree);
    256 
    257 typedef tree (*duplicate_eh_regions_map) (tree, void *);
    258 extern struct pointer_map_t *duplicate_eh_regions
    259   (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
    260 
    261 extern void sjlj_emit_function_exit_after (rtx);
    262 
    263 extern eh_region gen_eh_region_cleanup (eh_region);
    264 extern eh_region gen_eh_region_try (eh_region);
    265 extern eh_region gen_eh_region_allowed (eh_region, tree);
    266 extern eh_region gen_eh_region_must_not_throw (eh_region);
    267 
    268 extern eh_catch gen_eh_region_catch (eh_region, tree);
    269 extern eh_landing_pad gen_eh_landing_pad (eh_region);
    270 
    271 extern eh_region get_eh_region_from_number_fn (struct function *, int);
    272 extern eh_region get_eh_region_from_number (int);
    273 extern eh_landing_pad get_eh_landing_pad_from_number_fn (struct function*,int);
    274 extern eh_landing_pad get_eh_landing_pad_from_number (int);
    275 extern eh_region get_eh_region_from_lp_number_fn (struct function *, int);
    276 extern eh_region get_eh_region_from_lp_number (int);
    277 
    278 extern eh_region eh_region_outermost (struct function *, eh_region, eh_region);
    279 
    280 extern void make_reg_eh_region_note (rtx insn, int ecf_flags, int lp_nr);
    281 extern void make_reg_eh_region_note_nothrow_nononlocal (rtx);
    282 
    283 extern void verify_eh_tree (struct function *);
    284 extern void dump_eh_tree (FILE *, struct function *);
    285 void debug_eh_tree (struct function *);
    286 extern void add_type_for_runtime (tree);
    287 extern tree lookup_type_for_runtime (tree);
    288 extern void assign_filter_values (void);
    289 
    290 extern eh_region get_eh_region_from_rtx (const_rtx);
    291 extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
    292 
    293 struct GTY(()) throw_stmt_node {
    294   gimple stmt;
    295   int lp_nr;
    296 };
    297 
    298 extern struct htab *get_eh_throw_stmt_table (struct function *);
    299 extern void set_eh_throw_stmt_table (struct function *, struct htab *);
    300 
    301 enum eh_personality_kind {
    302   eh_personality_none,
    303   eh_personality_any,
    304   eh_personality_lang
    305 };
    306 
    307 extern enum eh_personality_kind
    308 function_needs_eh_personality (struct function *);
    309 
    310 /* Pre-order iteration within the eh_region tree.  */
    311 
    312 static inline eh_region
    313 ehr_next (eh_region r, eh_region start)
    314 {
    315   if (r->inner)
    316     r = r->inner;
    317   else if (r->next_peer && r != start)
    318     r = r->next_peer;
    319   else
    320     {
    321       do
    322 	{
    323 	  r = r->outer;
    324 	  if (r == start)
    325 	    return NULL;
    326 	}
    327       while (r->next_peer == NULL);
    328       r = r->next_peer;
    329     }
    330   return r;
    331 }
    332 
    333 #define FOR_ALL_EH_REGION_AT(R, START) \
    334   for ((R) = (START); (R) != NULL; (R) = ehr_next (R, START))
    335 
    336 #define FOR_ALL_EH_REGION_FN(R, FN) \
    337   for ((R) = (FN)->eh->region_tree; (R) != NULL; (R) = ehr_next (R, NULL))
    338 
    339 #define FOR_ALL_EH_REGION(R) FOR_ALL_EH_REGION_FN (R, cfun)
    340