OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / except.h
index b6450d3..5d461d7 100644 (file)
 /* Exception Handling interface routines.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+   2007, 2008, 2009, 2010  Free Software Foundation, Inc.
    Contributed by Mike Stump <mrs@cygnus.com>.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC 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 2, or (at your option)
-any later version.
+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.
 
-GNU CC 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.
+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 GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#if !defined(NULL_RTX) && !defined(rtx)
-typedef struct rtx_def *_except_rtx;
-#define rtx _except_rtx
+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
 #endif
 
-#ifdef TREE_CODE
+#include "hashtab.h"
+#include "vecprim.h"
+#include "vecir.h"
 
-/* A stack of labels. CHAIN points to the next entry in the stack.  */
+struct function;
+struct eh_region_d;
+struct pointer_map_t;
 
-struct label_node {
-  union {
-    rtx rlabel;
-    tree tlabel;
-  } u;
-  struct label_node *chain;
+/* 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
 };
 
-/* An eh_entry is used to describe one exception handling region.
-
-   OUTER_CONTEXT is the label used for rethrowing into the outer context.
-
-   EXCEPTION_HANDLER_LABEL is the label corresponding to the handler
-   for this region.
-
-   LABEL_USED indicates whether a CATCH block has already used this
-   label or not. New ones are needed for additional catch blocks if
-   it has.
-
-   FALSE_LABEL is used when either setjmp/longjmp exceptions are in
-   use, or old style table exceptions. It contains the label for 
-   branching to the next runtime type check as handlers are processed.
-
-   FINALIZATION is the tree codes for the handler, or is NULL_TREE if
-   one hasn't been generated yet, or is integer_zero_node to mark the
-   end of a group of try blocks.  */
-
-struct eh_entry {
-  rtx outer_context;
-  rtx exception_handler_label;
-  tree finalization;
-  int label_used;
-  rtx false_label;
-  rtx rethrow_label;
-  /* If non-zero, this entry is for a handler created when we left an
-     exception-region via goto.  */
-  unsigned goto_entry_p : 1;
-};
-#else
-struct label_node;
-struct eh_entry;
-#endif
 
-/* A list of EH_ENTRYs. ENTRY is the entry; CHAIN points to the next
-   entry in the list, or is NULL if this is the last entry.  */
+/* 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 eh_node {
-  struct eh_entry *entry;
-  struct eh_node *chain;
+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;
 };
 
-/* A stack of EH_ENTRYs. TOP is the topmost entry on the stack. TOP is
-   NULL if the stack is empty.  */
+/* A catch handler associated with an ERT_TRY region.  */
 
-struct eh_stack {
-  struct eh_node *top;
+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;
 };
 
-/* A queue of EH_ENTRYs. HEAD is the front of the queue; TAIL is the
-   end (the latest entry). HEAD and TAIL are NULL if the queue is
-   empty.  */
+/* Describes one exception region.  */
 
-struct eh_queue {
-  struct eh_node *head;
-  struct eh_node *tail;
-  struct eh_queue *next;
-};
-
-/* Used to save exception handling status for each function.  */
-struct eh_status
+struct GTY(()) eh_region_d
 {
-  /* A stack used for keeping track of the currently active exception
-     handling region.  As each exception region is started, an entry
-     describing the region is pushed onto this stack.  The current
-     region can be found by looking at the top of the stack, and as we
-     exit regions, the corresponding entries are popped. 
-
-     Entries cannot overlap; they can be nested. So there is only one
-     entry at most that corresponds to the current instruction, and that
-     is the entry on the top of the stack.  */
-  struct eh_stack x_ehstack;
-  /* This stack is used to represent what the current eh region is
-     for the catch blocks beings processed */
-  struct eh_stack x_catchstack;
-  /* A queue used for tracking which exception regions have closed.
-     As we exit a region, we enqueue a new entry. The entries are then
-     dequeued during expand_leftover_cleanups and
-     expand_start_all_catch.  */
-  struct eh_queue *x_ehqueue;
-  /* Insns for all of the exception handlers for the current function.
-     They are currently emitted by the frontend code.  */
-  rtx x_catch_clauses;
-  /* End of exception handler insn sequence.  */
-  rtx x_catch_clauses_last;
-  /* A random data area for the front end's own use.  */
-  struct label_node *x_false_label_stack;
-  /* Keeps track of the label to resume to should one want to resume
-     normal control flow out of a handler (instead of, say, returning to
-     the caller of the current function or exiting the program).  */
-  struct label_node *x_caught_return_label_stack;
-  /* A stack (TREE_LIST) of lists of handlers.  The TREE_VALUE of each
-     node is itself a TREE_CHAINed list of handlers for regions that
-     are not yet closed. The TREE_VALUE of each entry contains the
-     handler for the corresponding entry on the ehstack.  */
-  union tree_node *x_protect_list;
-  /* The EH context.  Nonzero if the function has already
-     fetched a pointer to the EH context  for exception handling.  */
-  rtx ehc;
-  /* The label generated by expand_builtin_eh_return.  */
-  rtx x_eh_return_stub_label;
+  /* 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;
 };
 
-#define ehstack (cfun->eh->x_ehstack)
-#define catchstack (cfun->eh->x_catchstack)
-#define ehqueue (cfun->eh->x_ehqueue)
-#define catch_clauses (cfun->eh->x_catch_clauses)
-#define catch_clauses_last (cfun->eh->x_catch_clauses_last)
-#define false_label_stack (cfun->eh->x_false_label_stack)
-#define caught_return_label_stack (cfun->eh->x_caught_return_label_stack)
-#define protect_list (cfun->eh->x_protect_list)
-#define current_function_ehc (cfun->eh->ehc)
-#define eh_return_stub_label (cfun->eh->x_eh_return_stub_label)
-
-#ifdef TREE_CODE
-/* Start an exception handling region.  All instructions emitted after
-   this point are considered to be part of the region until
-   expand_eh_region_end () is invoked.  */
-
-extern void expand_eh_region_start             PARAMS ((void));
+typedef struct eh_landing_pad_d *eh_landing_pad;
+typedef struct eh_catch_d *eh_catch;
+typedef struct eh_region_d *eh_region;
 
-/* Just like expand_eh_region_start, except if a cleanup action is
-   entered on the cleanup chain, the TREE_PURPOSE of the element put
-   on the chain is DECL.  DECL should be the associated VAR_DECL, if
-   any, otherwise it should be NULL_TREE.  */
-
-extern void expand_eh_region_start_for_decl    PARAMS ((tree));
-
-/* Start an exception handling region for the given cleanup action.
-   All instructions emitted after this point are considered to be part
-   of the region until expand_eh_region_end () is invoked.  CLEANUP is
-   the cleanup action to perform.  The return value is true if the
-   exception region was optimized away.  If that case,
-   expand_eh_region_end does not need to be called for this cleanup,
-   nor should it be.
-
-   This routine notices one particular common case in C++ code
-   generation, and optimizes it so as to not need the exception
-   region.  */
-
-extern int expand_eh_region_start_tree         PARAMS ((tree, tree));
-
-/* End an exception handling region.  The information about the region
-   is found on the top of ehstack.
-
-   HANDLER is either the cleanup for the exception region, or if we're
-   marking the end of a try block, HANDLER is integer_zero_node.
-
-   HANDLER will be transformed to rtl when expand_leftover_cleanups ()
-   is invoked.  */
-
-extern void expand_eh_region_end               PARAMS ((tree));
-
-/* Push RLABEL or TLABEL onto LABELSTACK. Only one of RLABEL or TLABEL
-   should be set; the other must be NULL.  */
-
-extern void push_label_entry   PARAMS ((struct label_node **labelstack,
-                                        rtx rlabel, tree tlabel));
-
-/* Pop the topmost entry from LABELSTACK and return its value as an
-   rtx node. If LABELSTACK is empty, return NULL.  */
-
-extern rtx pop_label_entry     PARAMS ((struct label_node **labelstack));
-
-/* Return the topmost entry of LABELSTACK as a tree node, or return
-   NULL_TREE if LABELSTACK is empty.  */
-
-extern tree top_label_entry    PARAMS ((struct label_node **labelstack));
-
-#endif
+DEF_VEC_P(eh_region);
+DEF_VEC_ALLOC_P(eh_region, gc);
+DEF_VEC_ALLOC_P(eh_region, heap);
 
-/* Test: is exception handling turned on? */
+DEF_VEC_P(eh_landing_pad);
+DEF_VEC_ALLOC_P(eh_landing_pad, gc);
 
-extern int doing_eh                            PARAMS ((int));
 
-/* Toplevel initialization for EH.  */
+/* The exception status for each function.  */
 
-void set_exception_lang_code                    PARAMS ((int));
-void set_exception_version_code                 PARAMS ((int));
-
-/* A list of handlers asocciated with an exception region. HANDLER_LABEL
-   is the the label that control should be transfered to if the data
-   in TYPE_INFO matches an exception. a value of NULL_TREE for TYPE_INFO
-   means This is a cleanup, and must always be called. A value of
-   CATCH_ALL_TYPE works like a cleanup, but a call to the runtime matcher
-   is still performed to avoid being caught by a different language
-   exception. NEXT is a pointer to the next handler for this region. 
-   NULL means there are no more. */
-
-typedef struct handler_info 
+struct GTY(()) eh_status
 {
-  rtx handler_label;
-  int handler_number;
-  void *type_info;
-  struct handler_info *next;
-} handler_info;
+  /* 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;
+};
 
 
-/* Add new handler information to an exception range. The  first parameter
-   specifies the range number (returned from new_eh_entry()). The second
-   parameter specifies the handler.  By default the handler is inserted at
-   the end of the list. A handler list may contain only ONE NULL_TREE
-   typeinfo entry. Regardless where it is positioned, a NULL_TREE entry
-   is always output as the LAST handler in the exception table for a region. */
+/* 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));
 
-void add_new_handler                   PARAMS ((int, struct handler_info *));
+extern void init_eh_for_function (void);
 
-/* Remove a handler label. The handler label is being deleted, so all
-   regions which reference this handler should have it removed from their
-   list of possible handlers. Any region which has the final handler
-   removed can be deleted. */
+extern void remove_eh_landing_pad (eh_landing_pad);
+extern void remove_eh_handler (eh_region);
 
-void remove_handler                    PARAMS ((rtx));
+extern bool current_function_has_exception_handlers (void);
+extern void output_function_exception_table (const char *);
 
-/* Create a new handler structure initialized with the handler label and
-   typeinfo fields passed in. */
+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);
+extern void expand_dw2_landing_pad_for_region (eh_region);
 
-struct handler_info *get_new_handler            PARAMS ((rtx, void *));
+typedef tree (*duplicate_eh_regions_map) (tree, void *);
+extern struct pointer_map_t *duplicate_eh_regions
+  (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
 
-/* Make a duplicate of an exception region by copying all the handlers
-   for an exception region. Return the new handler index. */
+extern void sjlj_emit_function_exit_after (rtx);
 
-int duplicate_eh_handlers              PARAMS ((int, int, rtx (*)(rtx)));
+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);
 
-/* map symbol refs for rethrow */
+extern eh_catch gen_eh_region_catch (eh_region, tree);
+extern eh_landing_pad gen_eh_landing_pad (eh_region);
 
-rtx rethrow_symbol_map                          PARAMS ((rtx, rtx (*)(rtx)));
+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);
 
-/* Is the rethrow label for a region used? */
+extern eh_region eh_region_outermost (struct function *, eh_region, eh_region);
 
-int rethrow_used                                PARAMS ((int));
+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);
 
-/* Update the rethrow references to reflect rethrows which have been
-   optimized away.  */
+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);
 
-void update_rethrow_references                 PARAMS ((void));
+extern eh_region get_eh_region_from_rtx (const_rtx);
+extern eh_landing_pad get_eh_landing_pad_from_rtx (const_rtx);
 
-/* Get a pointer to the first handler in an exception region's list. */
+struct GTY(()) throw_stmt_node {
+  gimple stmt;
+  int lp_nr;
+};
 
-struct handler_info *get_first_handler          PARAMS ((int));
+extern struct htab *get_eh_throw_stmt_table (struct function *);
+extern void set_eh_throw_stmt_table (struct function *, struct htab *);
 
-/* Find all the runtime handlers type matches currently referenced */
+enum eh_personality_kind {
+  eh_personality_none,
+  eh_personality_any,
+  eh_personality_lang
+};
 
-int find_all_handler_type_matches               PARAMS ((void ***));
+extern enum eh_personality_kind
+function_needs_eh_personality (struct function *);
 
-/* The eh_nesting_info structure is used to find a list of valid handlers
-   for any arbitrary exception region.  When init_eh_nesting_info is called,
-   the information is all pre-calculated and entered in this structure.
-   REGION_INDEX is a vector over all possible region numbers.  Since the
-   number of regions is typically much smaller than the range of block
-   numbers, this is a sparse vector and the other data structures are 
-   represented as dense vectors.  Indexed with an exception region number, this
-   returns the index to use in the other data structures to retreive the
-   correct information.
-   HANDLERS is an array of vectors which point to handler_info structures.
-   when indexed, it gives the list of all possible handlers which can 
-   be reached by a throw from this exception region.
-   NUM_HANDLERS is the equivilent array indicating how many handler
-   pointers there are in the HANDLERS vector.
-   OUTER_INDEX indicates which index represents the information for the
-   outer block.  0 indicates there is no outer context.
-   REGION_COUNT is the number of regions.  */
+/* Pre-order iteration within the eh_region tree.  */
 
-typedef struct eh_nesting 
+static inline eh_region
+ehr_next (eh_region r, eh_region start)
 {
-  int *region_index;
-  handler_info ***handlers;
-  int *num_handlers;
-  int *outer_index;
-  int region_count;
-} eh_nesting_info;
-
-/* Initialize the eh_nesting_info structure.  */
-
-eh_nesting_info *init_eh_nesting_info          PARAMS ((void));
-
-/* Get a list of handlers reachable from a an exception region/insn.  */
-
-int reachable_handlers                         PARAMS ((int, eh_nesting_info *, rtx, 
-                                                handler_info ***handlers));
-
-/* Free the eh_nesting_info structure.  */
-
-void free_eh_nesting_info                      PARAMS ((eh_nesting_info *));
-
-extern void init_eh                            PARAMS ((void));
-
-/* Initialization for the per-function EH data.  */
-
-extern void init_eh_for_function               PARAMS ((void));
-
-/* Generate an exception label. Use instead of gen_label_rtx */
-
-extern rtx gen_exception_label                  PARAMS ((void));
-
-/* Adds an EH table entry for EH entry number N. Called from
-   final_scan_insn for NOTE_INSN_EH_REGION_BEG.  */
-
-extern void add_eh_table_entry                 PARAMS ((int n));
-
-/* Start a catch clause, triggered by runtime value paramter. */
-
-#ifdef TREE_CODE
-extern void start_catch_handler                 PARAMS ((tree));
-#endif
-
-/* End an individual catch clause. */
-
-extern void end_catch_handler                   PARAMS ((void));
-
-/* Returns a non-zero value if we need to output an exception table.  */
-
-extern int exception_table_p                   PARAMS ((void));
-
-/* Outputs the exception table if we have one.  */
-
-extern void output_exception_table             PARAMS ((void));
-extern void output_exception_table_data                PARAMS ((void));
-
-/* Free the exception table.  */
-
-extern void free_exception_table               PARAMS((void));
-
-/* Used by the ia64 unwind format to output data for an individual 
-   function.  */
-
-extern void output_function_exception_table    PARAMS((void));
-
-/* Given a return address in ADDR, determine the address we should use
-   to find the corresponding EH region.  */
-
-extern rtx eh_outer_context                    PARAMS ((rtx addr));
-
-/* Called at the start of a block of try statements for which there is
-   a supplied catch handler.  */
-
-extern void expand_start_try_stmts             PARAMS ((void));
-
-/* Called at the start of a block of catch statements. It terminates the
-   previous set of try statements.  */
-
-extern void expand_start_all_catch             PARAMS ((void));
-
-/* Called at the end of a block of catch statements.  */
-
-extern void expand_end_all_catch               PARAMS ((void));
-
-/* Begin a region that will contain entries created with
-   add_partial_entry.  */
-
-extern void begin_protect_partials              PARAMS ((void));
-
-#ifdef TREE_CODE
-/* Create a new exception region and add the handler for the region
-   onto a list. These regions will be ended (and their handlers
-   emitted) when end_protect_partials is invoked.  */
-
-extern void add_partial_entry                  PARAMS ((tree handler));
-#endif
-
-/* End all of the pending exception regions that have handlers added with
-   push_protect_entry ().  */
-
-extern void end_protect_partials               PARAMS ((void));
-
-/* An internal throw.  */
-
-extern void expand_internal_throw              PARAMS ((void));
-
-/* Called from expand_exception_blocks and expand_end_catch_block to
-   expand and pending handlers.  */
-
-extern void expand_leftover_cleanups           PARAMS ((void));
-
-/* If necessary, emit insns to get EH context for the current
-   function. */
-
-extern void emit_eh_context                    PARAMS ((void));
-
-/* Builds a list of handler labels and puts them in the global
-   variable exception_handler_labels.  */
-
-extern void find_exception_handler_labels      PARAMS ((void));
-
-/* Determine if an arbitrary label is an exception label */
-
-extern int is_exception_handler_label           PARAMS ((int));
-
-/* Performs sanity checking on the check_exception_handler_labels
-   list.  */
-
-extern void check_exception_handler_labels     PARAMS ((void));
-
-/* Keeps track of the label used as the context of a throw to rethrow an
-   exception to the outer exception region.  */
-
-extern struct label_node *outer_context_label_stack;
-
-/* A list of labels used for exception handlers. It is created by
-   find_exception_handler_labels for the optimization passes.  */
-
-extern rtx exception_handler_labels;
-
-/* Determine if the given INSN can throw an exception.  */
-
-extern int can_throw                            PARAMS ((rtx));
-
-/* Return nonzero if nothing in this function can throw.  */
-
-extern int nothrow_function_p                  PARAMS ((void));
-
-/* Performs optimizations for exception handling, such as removing
-   unnecessary exception regions. Invoked from jump_optimize ().  */
-
-extern void exception_optimize                 PARAMS ((void));
-
-/* Return EH context (and set it up once per fn).  */
-extern rtx get_eh_context                      PARAMS ((void));
-
-/* Get the dynamic handler chain.  */
-extern rtx get_dynamic_handler_chain           PARAMS ((void));
-
-/* Get the dynamic cleanup chain.  */
-extern rtx get_dynamic_cleanup_chain           PARAMS ((void));
-
-/* Throw an exception.  */
-
-extern void emit_throw                         PARAMS ((void));
-
-/* Save away the current ehqueue.  */
-extern void push_ehqueue                        PARAMS ((void));
-
-/* Restore a previously pushed ehqueue.  */
-extern void pop_ehqueue                         PARAMS ((void));
-
-/* One to use setjmp/longjmp method of generating code.  */
-
-extern int exceptions_via_longjmp;
-
-/* One to enable asynchronous exception support.  */
-
-extern int asynchronous_exceptions;
-
-/* One to protect cleanup actions with a handler that calls
-   __terminate, zero otherwise.  */
-
-extern int protect_cleanup_actions_with_terminate;
-
-#ifdef TREE_CODE
-extern tree protect_with_terminate             PARAMS ((tree));
-#endif
-
-extern void expand_fixup_region_start  PARAMS ((void));
-#ifdef TREE_CODE
-extern void expand_fixup_region_end    PARAMS ((tree));
-#endif
-
-/* Various hooks for the DWARF 2 __throw routine.  */
-
-void expand_builtin_unwind_init                PARAMS ((void));
-rtx expand_builtin_dwarf_fp_regnum     PARAMS ((void));
-#ifdef TREE_CODE
-rtx expand_builtin_frob_return_addr    PARAMS ((tree));
-rtx expand_builtin_extract_return_addr PARAMS ((tree));
-void expand_builtin_init_dwarf_reg_sizes       PARAMS ((tree));
-void expand_builtin_eh_return          PARAMS ((tree, tree, tree));
-#endif
-void expand_eh_return                  PARAMS ((void));
-
-
-/* Checking whether 2 instructions are within the same exception region. */
-
-int in_same_eh_region                   PARAMS ((rtx, rtx));
-void free_insn_eh_region                PARAMS ((void));
-void init_insn_eh_region                PARAMS ((rtx, int));
-
-#ifdef rtx
-#undef rtx
-#endif
+  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)