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