]>
Commit | Line | Data |
---|---|---|
4956d07c | 1 | /* Exception Handling interface routines. |
9dcd6f09 | 2 | Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |
66647d44 | 3 | 2007, 2008 Free Software Foundation, Inc. |
4956d07c MS |
4 | Contributed by Mike Stump <mrs@cygnus.com>. |
5 | ||
1322177d | 6 | This file is part of GCC. |
4956d07c | 7 | |
1322177d LB |
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 | |
9dcd6f09 | 10 | Software Foundation; either version 3, or (at your option) any later |
1322177d | 11 | version. |
4956d07c | 12 | |
1322177d LB |
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. | |
4956d07c MS |
17 | |
18 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
4956d07c | 21 | |
a8da523f JH |
22 | #include "sbitmap.h" |
23 | #include "vecprim.h" | |
9a0d1e1b | 24 | |
f9f6b7df GS |
25 | struct function; |
26 | ||
9994a182 | 27 | /* Describes one exception region. */ |
d1b38208 | 28 | struct GTY(()) eh_region |
9994a182 DN |
29 | { |
30 | /* The immediately surrounding region. */ | |
31 | struct eh_region *outer; | |
32 | ||
33 | /* The list of immediately contained regions. */ | |
34 | struct eh_region *inner; | |
35 | struct eh_region *next_peer; | |
36 | ||
496a4ef5 JH |
37 | /* List of regions sharing label. */ |
38 | struct eh_region *next_region_sharing_label; | |
39 | ||
9994a182 DN |
40 | /* An identifier for this region. */ |
41 | int region_number; | |
42 | ||
43 | /* When a region is deleted, its parents inherit the REG_EH_REGION | |
44 | numbers already assigned. */ | |
45 | bitmap aka; | |
46 | ||
47 | /* Each region does exactly one thing. */ | |
48 | enum eh_region_type | |
49 | { | |
50 | ERT_UNKNOWN = 0, | |
51 | ERT_CLEANUP, | |
52 | ERT_TRY, | |
53 | ERT_CATCH, | |
54 | ERT_ALLOWED_EXCEPTIONS, | |
55 | ERT_MUST_NOT_THROW, | |
56 | ERT_THROW | |
57 | } type; | |
58 | ||
59 | /* Holds the action to perform based on the preceding type. */ | |
60 | union eh_region_u { | |
61 | /* A list of catch blocks, a surrounding try block, | |
62 | and the label for continuing after a catch. */ | |
63 | struct eh_region_u_try { | |
64 | struct eh_region *eh_catch; | |
65 | struct eh_region *last_catch; | |
66 | } GTY ((tag ("ERT_TRY"))) eh_try; | |
67 | ||
68 | /* The list through the catch handlers, the list of type objects | |
69 | matched, and the list of associated filters. */ | |
70 | struct eh_region_u_catch { | |
71 | struct eh_region *next_catch; | |
72 | struct eh_region *prev_catch; | |
73 | tree type_list; | |
74 | tree filter_list; | |
75 | } GTY ((tag ("ERT_CATCH"))) eh_catch; | |
76 | ||
77 | /* A tree_list of allowed types. */ | |
78 | struct eh_region_u_allowed { | |
79 | tree type_list; | |
80 | int filter; | |
81 | } GTY ((tag ("ERT_ALLOWED_EXCEPTIONS"))) allowed; | |
82 | ||
83 | /* The type given by a call to "throw foo();", or discovered | |
84 | for a throw. */ | |
85 | struct eh_region_u_throw { | |
86 | tree type; | |
87 | } GTY ((tag ("ERT_THROW"))) eh_throw; | |
9994a182 DN |
88 | } GTY ((desc ("%0.type"))) u; |
89 | ||
90 | /* Entry point for this region's handler before landing pads are built. */ | |
91 | rtx label; | |
92 | tree tree_label; | |
93 | ||
94 | /* Entry point for this region's handler from the runtime eh library. */ | |
95 | rtx landing_pad; | |
96 | ||
97 | /* Entry point for this region's handler from an inner region. */ | |
98 | rtx post_landing_pad; | |
99 | ||
100 | /* The RESX insn for handing off control to the next outermost handler, | |
101 | if appropriate. */ | |
102 | rtx resume; | |
103 | ||
104 | /* True if something in this region may throw. */ | |
105 | unsigned may_contain_throw : 1; | |
106 | }; | |
107 | ||
108 | typedef struct eh_region *eh_region; | |
109 | DEF_VEC_P(eh_region); | |
110 | DEF_VEC_ALLOC_P(eh_region, gc); | |
111 | DEF_VEC_ALLOC_P(eh_region, heap); | |
112 | ||
113 | /* Per-function EH data. Used to save exception status for each | |
114 | function. */ | |
d1b38208 | 115 | struct GTY(()) eh_status |
9994a182 DN |
116 | { |
117 | /* The tree of all regions for this function. */ | |
118 | struct eh_region *region_tree; | |
119 | ||
120 | /* The same information as an indexable array. */ | |
121 | VEC(eh_region,gc) *region_array; | |
122 | int last_region_number; | |
123 | ||
124 | htab_t GTY((param_is (struct throw_stmt_node))) throw_stmt_table; | |
125 | }; | |
911fdd58 | 126 | |
ce152ef8 | 127 | |
52a11cbf | 128 | /* Test: is exception handling turned on? */ |
502b8322 | 129 | extern int doing_eh (int); |
ce152ef8 | 130 | |
b2dd096b MM |
131 | /* Note that the current EH region (if any) may contain a throw, or a |
132 | call to a function which itself may contain a throw. */ | |
6de9cd9a | 133 | extern void note_eh_region_may_contain_throw (struct eh_region *); |
b2dd096b | 134 | |
6a58eee9 RH |
135 | /* Invokes CALLBACK for every exception handler label. Only used by old |
136 | loop hackery; should not be used by new code. */ | |
502b8322 | 137 | extern void for_each_eh_label (void (*) (rtx)); |
4956d07c | 138 | |
f698d217 SB |
139 | /* Invokes CALLBACK for every exception region in the current function. */ |
140 | extern void for_each_eh_region (void (*) (struct eh_region *)); | |
141 | ||
0519ce30 | 142 | /* Determine if the given INSN can throw an exception. */ |
a8ee227c | 143 | extern bool can_throw_internal_1 (int, bool, bool); |
ed7a4b4b | 144 | extern bool can_throw_internal (const_rtx); |
a8ee227c | 145 | extern bool can_throw_external_1 (int, bool, bool); |
ed7a4b4b | 146 | extern bool can_throw_external (const_rtx); |
0519ce30 | 147 | |
97b0ade3 | 148 | /* Set TREE_NOTHROW and cfun->all_throwers_are_sibcalls. */ |
c2924966 | 149 | extern unsigned int set_nothrow_function_flags (void); |
fb13d4d0 | 150 | |
502b8322 AJ |
151 | extern void init_eh (void); |
152 | extern void init_eh_for_function (void); | |
911fdd58 | 153 | |
502b8322 | 154 | extern rtx reachable_handlers (rtx); |
496a4ef5 JH |
155 | extern void remove_eh_region (int); |
156 | extern void remove_eh_region_and_replace_by_outer_of (int, int); | |
e976b8b2 | 157 | |
502b8322 | 158 | extern void convert_from_eh_region_ranges (void); |
c2924966 | 159 | extern unsigned int convert_to_eh_region_ranges (void); |
502b8322 AJ |
160 | extern void find_exception_handler_labels (void); |
161 | extern bool current_function_has_exception_handlers (void); | |
22ba88ef | 162 | extern void output_function_exception_table (const char *); |
154bba13 | 163 | |
502b8322 AJ |
164 | extern void expand_builtin_unwind_init (void); |
165 | extern rtx expand_builtin_eh_return_data_regno (tree); | |
166 | extern rtx expand_builtin_extract_return_addr (tree); | |
167 | extern void expand_builtin_init_dwarf_reg_sizes (tree); | |
168 | extern rtx expand_builtin_frob_return_addr (tree); | |
169 | extern rtx expand_builtin_dwarf_sp_column (void); | |
170 | extern void expand_builtin_eh_return (tree, tree); | |
171 | extern void expand_eh_return (void); | |
c76362b4 | 172 | extern rtx expand_builtin_extend_pointer (tree); |
69c32ec8 JH |
173 | extern rtx get_exception_pointer (void); |
174 | extern rtx get_exception_filter (void); | |
98f464e0 | 175 | typedef tree (*duplicate_eh_regions_map) (tree, void *); |
fad41cd7 RH |
176 | extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, |
177 | void *, int, int); | |
e976b8b2 | 178 | |
502b8322 | 179 | extern void sjlj_emit_function_exit_after (rtx); |
617a1b71 | 180 | extern void default_init_unwind_resume_libfunc (void); |
e976b8b2 | 181 | |
f08a18d0 | 182 | extern struct eh_region *gen_eh_region_cleanup (struct eh_region *); |
6de9cd9a DN |
183 | extern struct eh_region *gen_eh_region_try (struct eh_region *); |
184 | extern struct eh_region *gen_eh_region_catch (struct eh_region *, tree); | |
185 | extern struct eh_region *gen_eh_region_allowed (struct eh_region *, tree); | |
186 | extern struct eh_region *gen_eh_region_must_not_throw (struct eh_region *); | |
187 | extern int get_eh_region_number (struct eh_region *); | |
188 | extern bool get_eh_region_may_contain_throw (struct eh_region *); | |
4e6d1743 | 189 | extern tree get_eh_region_no_tree_label (int); |
6de9cd9a DN |
190 | extern tree get_eh_region_tree_label (struct eh_region *); |
191 | extern void set_eh_region_tree_label (struct eh_region *, tree); | |
192 | ||
a8ee227c | 193 | extern void foreach_reachable_handler (int, bool, bool, |
6de9cd9a DN |
194 | void (*) (struct eh_region *, void *), |
195 | void *); | |
196 | ||
197 | extern void collect_eh_region_array (void); | |
198 | extern void expand_resx_expr (tree); | |
cc7220fd JH |
199 | extern void verify_eh_tree (struct function *); |
200 | extern void dump_eh_tree (FILE *, struct function *); | |
9994a182 | 201 | void debug_eh_tree (struct function *); |
7e2df4a1 | 202 | extern int eh_region_outermost (struct function *, int, int); |
9994a182 DN |
203 | extern void add_type_for_runtime (tree); |
204 | extern tree lookup_type_for_runtime (tree); | |
6de9cd9a | 205 | |
e6855a2d | 206 | /* If non-NULL, this is a function that returns an expression to be |
a1f300c0 | 207 | executed if an unhandled exception is propagated out of a cleanup |
e6855a2d MM |
208 | region. For example, in C++, an exception thrown by a destructor |
209 | during stack unwinding is required to result in a call to | |
210 | `std::terminate', so the C++ version of this function returns a | |
211 | CALL_EXPR for `std::terminate'. */ | |
726a989a | 212 | extern gimple (*lang_protect_cleanup_actions) (void); |
f54a7f6f | 213 | |
52a11cbf | 214 | /* Return true if type A catches type B. */ |
502b8322 | 215 | extern int (*lang_eh_type_covers) (tree a, tree b); |
e976b8b2 | 216 | |
52a11cbf | 217 | /* Map a type to a runtime object to match type. */ |
502b8322 | 218 | extern tree (*lang_eh_runtime_type) (tree); |
e976b8b2 | 219 | |
531073e7 RH |
220 | |
221 | /* Just because the user configured --with-sjlj-exceptions=no doesn't | |
222 | mean that we can use call frame exceptions. Detect that the target | |
223 | has appropriate support. */ | |
224 | ||
c14aea87 | 225 | #ifndef MUST_USE_SJLJ_EXCEPTIONS |
c427220a | 226 | # if defined (EH_RETURN_DATA_REGNO) \ |
951120ea | 227 | && (defined (TARGET_UNWIND_INFO) \ |
84fc8b47 | 228 | || (DWARF2_UNWIND_INFO \ |
2a1ee410 | 229 | && (defined (EH_RETURN_HANDLER_RTX) \ |
c427220a | 230 | || defined (HAVE_eh_return)))) |
c14aea87 | 231 | # define MUST_USE_SJLJ_EXCEPTIONS 0 |
c427220a NS |
232 | # else |
233 | # define MUST_USE_SJLJ_EXCEPTIONS 1 | |
5748beec | 234 | # endif |
52a11cbf RH |
235 | #endif |
236 | ||
531073e7 RH |
237 | #ifdef CONFIG_SJLJ_EXCEPTIONS |
238 | # if CONFIG_SJLJ_EXCEPTIONS == 1 | |
239 | # define USING_SJLJ_EXCEPTIONS 1 | |
240 | # endif | |
241 | # if CONFIG_SJLJ_EXCEPTIONS == 0 | |
242 | # define USING_SJLJ_EXCEPTIONS 0 | |
c427220a | 243 | # if !defined(EH_RETURN_DATA_REGNO) |
52a11cbf RH |
244 | #error "EH_RETURN_DATA_REGNO required" |
245 | # endif | |
c427220a NS |
246 | # if ! (defined(TARGET_UNWIND_INFO) || DWARF2_UNWIND_INFO) |
247 | #error "{DWARF2,TARGET}_UNWIND_INFO required" | |
248 | # endif | |
249 | # if !defined(TARGET_UNWIND_INFO) \ | |
250 | && !(defined(EH_RETURN_HANDLER_RTX) || defined(HAVE_eh_return)) | |
52a11cbf RH |
251 | #error "EH_RETURN_HANDLER_RTX or eh_return required" |
252 | # endif | |
c427220a NS |
253 | /* Usually the above error checks will have already triggered an |
254 | error, but backends may set MUST_USE_SJLJ_EXCEPTIONS for their own | |
255 | reasons. */ | |
256 | # if MUST_USE_SJLJ_EXCEPTIONS | |
257 | #error "Must use SJLJ exceptions but configured not to" | |
531073e7 RH |
258 | # endif |
259 | # endif | |
260 | #else | |
52a11cbf | 261 | # define USING_SJLJ_EXCEPTIONS MUST_USE_SJLJ_EXCEPTIONS |
531073e7 | 262 | #endif |
b4660e5a | 263 | |
d1b38208 | 264 | struct GTY(()) throw_stmt_node { |
726a989a | 265 | gimple stmt; |
b4660e5a JH |
266 | int region_nr; |
267 | }; | |
268 | ||
269 | extern struct htab *get_eh_throw_stmt_table (struct function *); | |
270 | extern void set_eh_throw_stmt_table (struct function *, struct htab *); | |
a8da523f JH |
271 | extern void remove_unreachable_regions (sbitmap, sbitmap); |
272 | extern VEC(int,heap) * label_to_region_map (void); | |
273 | extern int num_eh_regions (void); | |
a3710436 | 274 | extern struct eh_region *redirect_eh_edge_to_label (struct edge_def *, tree, bool, bool, int); |
496a4ef5 | 275 | extern int get_next_region_sharing_label (int); |