OSDN Git Service

2014-04-01 Richard Biener <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / except.h
index d8e7ace..5d461d7 100644 (file)
@@ -1,13 +1,13 @@
 /* Exception Handling interface routines.
 /* Exception Handling interface routines.
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
-   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 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
    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 2, or (at your option) any later
+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
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,163 +16,325 @@ 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
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
+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
 
 
+#include "hashtab.h"
+#include "vecprim.h"
+#include "vecir.h"
 
 struct function;
 
 struct function;
+struct eh_region_d;
+struct pointer_map_t;
+
+/* 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
+};
+
+
+/* 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 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 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;
+
+DEF_VEC_P(eh_region);
+DEF_VEC_ALLOC_P(eh_region, gc);
+DEF_VEC_ALLOC_P(eh_region, heap);
+
+DEF_VEC_P(eh_landing_pad);
+DEF_VEC_ALLOC_P(eh_landing_pad, gc);
+
+
+/* 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,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;
+};
 
 
-struct inline_remap;
-
-/* Per-function EH data.  Used only in except.c, but GC and others
-   manipulate pointers to the opaque type.  */
-struct eh_status;
-
-/* Internal structure describing a region.  */
-struct eh_region;
-
-/* Test: is exception handling turned on?  */
-extern int doing_eh                            PARAMS ((int));
-
-/* Start an exception handling region.  All instructions emitted after
-   this point are considered to be part of the region until an
-   expand_eh_region_end variant is invoked.  */
-extern void expand_eh_region_start             PARAMS ((void));
-
-/* End an exception handling region for a cleanup.  HANDLER is an
-   expression to expand for the cleanup.  */
-extern void expand_eh_region_end_cleanup       PARAMS ((tree));
-
-/* End an exception handling region for a try block, and prepares
-   for subsequent calls to expand_start_catch.  */
-extern void expand_start_all_catch             PARAMS ((void));
-
-/* Begin a catch clause.  TYPE is an object to be matched by the
-   runtime, or a list of such objects, or null if this is a catch-all
-   clause.  */
-extern void expand_start_catch                 PARAMS ((tree));
-
-/* End a catch clause.  Control will resume after the try/catch block.  */
-extern void expand_end_catch                   PARAMS ((void));
-
-/* End a sequence of catch handlers for a try block.  */
-extern void expand_end_all_catch               PARAMS ((void));
-
-/* End an exception region for an exception type filter.  ALLOWED is a
-   TREE_LIST of TREE_VALUE objects to be matched by the runtime.
-   FAILURE is a function to invoke if a mismatch occurs.  */
-extern void expand_eh_region_end_allowed       PARAMS ((tree, tree));
-
-/* End an exception region for a must-not-throw filter.  FAILURE is a
-   function to invoke if an uncaught exception propagates this far.  */
-extern void expand_eh_region_end_must_not_throw        PARAMS ((tree));
-
-/* End an exception region for a throw.  No handling goes on here,
-   but it's the easiest way for the front-end to indicate what type
-   is being thrown.  */
-extern void expand_eh_region_end_throw         PARAMS ((tree));
-
-/* End a fixup region.  Within this region the cleanups for the immediately
-   enclosing region are _not_ run.  This is used for goto cleanup to avoid
-   destroying an object twice.  */
-extern void expand_eh_region_end_fixup         PARAMS ((tree));
-
-/* Note that the current EH region (if any) may contain a throw, or a
-   call to a function which itself may contain a throw.  */
-extern void note_eh_region_may_contain_throw    PARAMS ((void));
 
 /* Invokes CALLBACK for every exception handler label.  Only used by old
    loop hackery; should not be used by new code.  */
 
 /* 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                  PARAMS ((void (*) (rtx)));
-
-/* Determine if the given INSN can throw an exception.  */
-extern bool can_throw_internal                 PARAMS ((rtx));
-extern bool can_throw_external                 PARAMS ((rtx));
-
-/* Set current_function_nothrow and cfun->all_throwers_are_sibcalls.  */
-extern void set_nothrow_function_flags         PARAMS ((void));
-
-/* After initial rtl generation, call back to finish generating
-   exception support code.  */
-extern void finish_eh_generation               PARAMS ((void));
-
-extern void init_eh                            PARAMS ((void));
-extern void init_eh_for_function               PARAMS ((void));
-
-extern rtx reachable_handlers                  PARAMS ((rtx));
-extern void maybe_remove_eh_handler            PARAMS ((rtx));
-
-extern void convert_from_eh_region_ranges      PARAMS ((void));
-extern void convert_to_eh_region_ranges                PARAMS ((void));
-extern void find_exception_handler_labels      PARAMS ((void));
-extern bool current_function_has_exception_handlers PARAMS ((void));
-extern void output_function_exception_table    PARAMS ((void));
-
-extern void expand_builtin_unwind_init         PARAMS ((void));
-extern rtx expand_builtin_eh_return_data_regno PARAMS ((tree));
-extern rtx expand_builtin_extract_return_addr  PARAMS ((tree));
-extern void expand_builtin_init_dwarf_reg_sizes PARAMS ((tree));
-extern rtx expand_builtin_frob_return_addr     PARAMS ((tree));
-extern rtx expand_builtin_dwarf_sp_column      PARAMS ((void));
-extern void expand_builtin_eh_return           PARAMS ((tree, tree));
-extern void expand_eh_return                   PARAMS ((void));
-extern rtx get_exception_pointer               PARAMS ((struct function *));
-extern int duplicate_eh_regions                        PARAMS ((struct function *,
-                                                struct inline_remap *));
-
-extern void sjlj_emit_function_exit_after      PARAMS ((rtx));
-
-
-/* If non-NULL, this is a function that returns an expression to be
-   executed if an unhandled exception is propagated out of a cleanup
-   region.  For example, in C++, an exception thrown by a destructor
-   during stack unwinding is required to result in a call to
-   `std::terminate', so the C++ version of this function returns a
-   CALL_EXPR for `std::terminate'.  */
-extern tree (*lang_protect_cleanup_actions) PARAMS ((void));
-
-/* Return true if type A catches type B.  */
-extern int (*lang_eh_type_covers) PARAMS ((tree a, tree b));
-
-/* Map a type to a runtime object to match type.  */
-extern tree (*lang_eh_runtime_type) PARAMS ((tree));
-
-
-/* Just because the user configured --with-sjlj-exceptions=no doesn't
-   mean that we can use call frame exceptions.  Detect that the target
-   has appropriate support.  */
-
-#if ! (defined (EH_RETURN_DATA_REGNO)                  \
-       && (defined (IA64_UNWIND_INFO)                  \
-          || (DWARF2_UNWIND_INFO                       \
-              && defined (EH_RETURN_STACKADJ_RTX)      \
-              && (defined (EH_RETURN_HANDLER_RTX)      \
-                  || defined (HAVE_eh_return)))))
-#define MUST_USE_SJLJ_EXCEPTIONS       1
-#else
-#define MUST_USE_SJLJ_EXCEPTIONS       0
-#endif
-
-#ifdef CONFIG_SJLJ_EXCEPTIONS
-# if CONFIG_SJLJ_EXCEPTIONS == 1
-#  define USING_SJLJ_EXCEPTIONS                1
-# endif
-# if CONFIG_SJLJ_EXCEPTIONS == 0
-#  define USING_SJLJ_EXCEPTIONS                0
-#  ifndef EH_RETURN_DATA_REGNO
-    #error "EH_RETURN_DATA_REGNO required"
-#  endif
-#  ifndef EH_RETURN_STACKADJ_RTX
-    #error "EH_RETURN_STACKADJ_RTX required"
-#  endif
-#  if !defined(EH_RETURN_HANDLER_RTX) && !defined(HAVE_eh_return)
-    #error "EH_RETURN_HANDLER_RTX or eh_return required"
-#  endif
-#  if !defined(DWARF2_UNWIND_INFO) && !defined(IA64_UNWIND_INFO)
-    #error "{DWARF2,IA64}_UNWIND_INFO required"
-#  endif
-# endif
-#else
-# define USING_SJLJ_EXCEPTIONS         MUST_USE_SJLJ_EXCEPTIONS
-#endif
+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 bool current_function_has_exception_handlers (void);
+extern void output_function_exception_table (const char *);
+
+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);
+
+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 *);
+
+extern void sjlj_emit_function_exit_after (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);
+
+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, int ecf_flags, int lp_nr);
+extern void make_reg_eh_region_note_nothrow_nononlocal (rtx);
+
+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);
+
+struct GTY(()) throw_stmt_node {
+  gimple stmt;
+  int lp_nr;
+};
+
+extern struct htab *get_eh_throw_stmt_table (struct function *);
+extern void set_eh_throw_stmt_table (struct function *, struct htab *);
+
+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)