of space by only allocating memory for those that can throw. */
static void
-record_stmt_eh_region (struct eh_region *region, gimple t)
+record_stmt_eh_region (struct eh_region_d *region, gimple t)
{
if (!region)
return;
/* What's "current" while constructing the eh region tree. These
correspond to variables of the same name in cfun->eh, which we
don't have easy access to. */
- struct eh_region *cur_region;
+ struct eh_region_d *cur_region;
/* Processing of TRY_FINALLY requires a bit more state. This is
split out into a separate structure so that we don't have to
struct leh_state *outer;
/* The exception region created for it. */
- struct eh_region *region;
+ struct eh_region_d *region;
/* The goto queue. */
struct goto_queue_node *goto_queue;
tree label;
gimple_seq new_seq;
treemple temp;
+ location_t loc = gimple_location (gsi_stmt (*gsi));
temp.tp = tp;
new_seq = find_goto_replacement (tf, temp);
return;
}
- label = create_artificial_label ();
+ label = create_artificial_label (loc);
/* Set the new label for the GIMPLE_COND */
*tp = label;
{
gimple x;
gimple_seq cleanup, result;
+ location_t loc = gimple_location (tp);
cleanup = gimple_try_cleanup (tp);
result = gimple_try_eval (tp);
if (gimple_seq_may_fallthru (result))
{
if (!over)
- over = create_artificial_label ();
+ over = create_artificial_label (loc);
x = gimple_build_goto (over);
gimple_seq_add_stmt (&result, x);
}
if (!label)
{
- label = create_artificial_label ();
+ label = create_artificial_label (gimple_location (tf->try_finally_expr));
tf->fallthru_label = label;
if (tf->outer->tf)
{
if (tf->may_throw)
lab = tf->eh_label;
else
- lab = create_artificial_label ();
+ lab = create_artificial_label (gimple_location (tf->try_finally_expr));
/* We expect that tf->top_p is a GIMPLE_TRY. */
finally = gimple_try_cleanup (tf->top_p);
gimple x;
gimple_seq finally;
tree finally_label;
+ location_t loc = gimple_location (tf->try_finally_expr);
finally = gimple_try_cleanup (tf->top_p);
tf->top_p_seq = gimple_try_eval (tf->top_p);
return;
}
- finally_label = create_artificial_label ();
+ finally_label = create_artificial_label (loc);
x = gimple_build_label (finally_label);
gimple_seq_add_stmt (&tf->top_p_seq, x);
gimple_seq seq;
gimple x;
tree tmp;
+ location_t tf_loc = gimple_location (tf->try_finally_expr);
finally = gimple_try_cleanup (tf->top_p);
tf->top_p_seq = gimple_try_eval (tf->top_p);
if (! q)
continue;
- lab = labels[index].label = create_artificial_label ();
+ lab = labels[index].label
+ = create_artificial_label (tf_loc);
if (index == return_index)
do_return_redirection (q, lab, NULL, &return_val);
gimple switch_stmt;
gimple_seq finally;
struct pointer_map_t *cont_map = NULL;
+ /* The location of the TRY_FINALLY stmt. */
+ location_t tf_loc = gimple_location (tf->try_finally_expr);
+ /* The location of the finally block. */
+ location_t finally_loc;
switch_body = gimple_seq_alloc ();
finally = gimple_try_cleanup (tf->top_p);
tf->top_p_seq = gimple_try_eval (tf->top_p);
+ /* The location of the finally is either the last stmt in the finally
+ block or the location of the TRY_FINALLY itself. */
+ finally_loc = gimple_seq_last_stmt (tf->top_p_seq) != NULL ?
+ gimple_location (gimple_seq_last_stmt (tf->top_p_seq))
+ : tf_loc;
+
/* Lower the finally block itself. */
lower_eh_constructs_1 (state, finally);
ndests = fallthru_index + tf->may_fallthru;
finally_tmp = create_tmp_var (integer_type_node, "finally_tmp");
- finally_label = create_artificial_label ();
+ finally_label = create_artificial_label (finally_loc);
/* We use VEC_quick_push on case_label_vec throughout this function,
since we know the size in advance and allocate precisely as muce
last_case = build3 (CASE_LABEL_EXPR, void_type_node,
build_int_cst (NULL_TREE, fallthru_index), NULL,
- create_artificial_label ());
+ create_artificial_label (tf_loc));
VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
last_case = build3 (CASE_LABEL_EXPR, void_type_node,
build_int_cst (NULL_TREE, eh_index), NULL,
- create_artificial_label ());
+ create_artificial_label (tf_loc));
VEC_quick_push (tree, case_label_vec, last_case);
last_case_index++;
gcc_assert (slot);
cont_stmt = *(gimple *) slot;
- label = create_artificial_label ();
+ label = create_artificial_label (tf_loc);
CASE_LABEL (last_case) = label;
x = gimple_build_label (label);
label. */
switch_stmt = gimple_build_switch_vec (finally_tmp, last_case,
case_label_vec);
+ gimple_set_location (switch_stmt, finally_loc);
/* Need to link SWITCH_STMT after running replace_goto_queue
due to not wanting to process the same goto stmts twice. */
struct leh_tf_state this_tf;
struct leh_state this_state;
int ndests;
+ location_t tf_loc = gimple_location (tp);
/* Process the try block. */
this_tf.may_throw = get_eh_region_may_contain_throw (this_tf.region);
if (this_tf.may_throw)
{
- this_tf.eh_label = create_artificial_label ();
+ this_tf.eh_label = create_artificial_label (tf_loc);
set_eh_region_tree_label (this_tf.region, this_tf.eh_label);
honor_protect_cleanup_actions (state, &this_state, &this_tf);
}
static gimple_seq
lower_catch (struct leh_state *state, gimple tp)
{
- struct eh_region *try_region;
+ struct eh_region_d *try_region;
struct leh_state this_state;
gimple_stmt_iterator gsi;
tree out_label;
+ location_t try_catch_loc = gimple_location (tp);
try_region = gen_eh_region_try (state->cur_region);
this_state.cur_region = try_region;
out_label = NULL;
for (gsi = gsi_start (gimple_try_cleanup (tp)); !gsi_end_p (gsi); )
{
- struct eh_region *catch_region;
+ struct eh_region_d *catch_region;
tree eh_label;
gimple x, gcatch;
this_state.cur_region = catch_region;
lower_eh_constructs_1 (&this_state, gimple_catch_handler (gcatch));
- eh_label = create_artificial_label ();
+ eh_label = create_artificial_label (try_catch_loc);
set_eh_region_tree_label (catch_region, eh_label);
x = gimple_build_label (eh_label);
if (gimple_seq_may_fallthru (gimple_catch_handler (gcatch)))
{
if (!out_label)
- out_label = create_artificial_label ();
+ out_label = create_artificial_label (try_catch_loc);
x = gimple_build_goto (out_label);
gimple_seq_add_stmt (gimple_catch_handler_ptr (gcatch), x);
lower_eh_filter (struct leh_state *state, gimple tp)
{
struct leh_state this_state;
- struct eh_region *this_region;
+ struct eh_region_d *this_region;
gimple inner;
tree eh_label;
lower_eh_constructs_1 (state, gimple_eh_filter_failure (inner));
gimple_try_set_cleanup (tp, gimple_eh_filter_failure (inner));
- eh_label = create_artificial_label ();
+ eh_label = create_artificial_label (gimple_location (inner));
set_eh_region_tree_label (this_region, eh_label);
return frob_into_branch_around (tp, eh_label, NULL);
lower_cleanup (struct leh_state *state, gimple tp)
{
struct leh_state this_state;
- struct eh_region *this_region;
+ struct eh_region_d *this_region;
struct leh_tf_state fake_tf;
gimple_seq result;
/* Build enough of a try-finally state so that we can reuse
honor_protect_cleanup_actions. */
memset (&fake_tf, 0, sizeof (fake_tf));
- fake_tf.top_p = tp;
+ fake_tf.top_p = fake_tf.try_finally_expr = tp;
fake_tf.outer = state;
fake_tf.region = this_region;
fake_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
fake_tf.may_throw = true;
- fake_tf.eh_label = create_artificial_label ();
+ fake_tf.eh_label = create_artificial_label (gimple_location (tp));
set_eh_region_tree_label (this_region, fake_tf.eh_label);
honor_protect_cleanup_actions (state, NULL, &fake_tf);
/* Construct EH edges for STMT. */
static void
-make_eh_edge (struct eh_region *region, void *data)
+make_eh_edge (struct eh_region_d *region, void *data)
{
gimple stmt;
tree lab;
bool is_resx;
bool inlinable = false;
tree label = gimple_block_label (new_bb);
- struct eh_region *r;
+ struct eh_region_d *r;
if (gimple_code (stmt) == GIMPLE_RESX)
{
field, output error if something goes wrong. */
static void
-mark_eh_edge (struct eh_region *region, void *data)
+mark_eh_edge (struct eh_region_d *region, void *data)
{
gimple stmt;
tree lab;
operands from DATA->bb_to_remove. */
static void
-make_eh_edge_and_update_phi (struct eh_region *region, void *data)
+make_eh_edge_and_update_phi (struct eh_region_d *region, void *data)
{
struct update_info *info = (struct update_info *) data;
edge e, e2;