static void
record_stmt_eh_region (struct eh_region *region, tree t)
{
- struct throw_stmt_node *n;
- void **slot;
-
if (!region)
return;
- n = ggc_alloc (sizeof (*n));
- n->stmt = t;
- n->region_nr = get_eh_region_number (region);
-
- slot = htab_find_slot (get_eh_throw_stmt_table (cfun), n, INSERT);
- gcc_assert (!*slot);
- *slot = n;
+ add_stmt_to_eh_region (t, get_eh_region_number (region));
}
void
slot = htab_find_slot (get_eh_throw_stmt_table (ifun), n, INSERT);
gcc_assert (!*slot);
*slot = n;
+ /* ??? For the benefit of calls.c, converting all this to rtl,
+ we need to record the call expression, not just the outer
+ modify statement. */
+ if (TREE_CODE (t) == MODIFY_EXPR
+ && (t = get_call_expr_in (t)))
+ add_stmt_to_eh_region_fn (ifun, t, num);
}
void
if (slot)
{
htab_clear_slot (get_eh_throw_stmt_table (ifun), slot);
+ /* ??? For the benefit of calls.c, converting all this to rtl,
+ we need to record the call expression, not just the outer
+ modify statement. */
+ if (TREE_CODE (t) == MODIFY_EXPR
+ && (t = get_call_expr_in (t)))
+ remove_stmt_from_eh_region_fn (ifun, t);
return true;
}
else
size_t goto_queue_active;
/* The set of unique labels seen as entries in the goto queue. */
- varray_type dest_array;
+ VEC(tree,heap) *dest_array;
/* A label to be added at the end of the completed transformed
sequence. It will be set if may_fallthru was true *at one time*,
if (! tf->dest_array)
{
- VARRAY_TREE_INIT (tf->dest_array, 10, "dest_array");
- VARRAY_PUSH_TREE (tf->dest_array, lab);
+ tf->dest_array = VEC_alloc (tree, heap, 10);
+ VEC_quick_push (tree, tf->dest_array, lab);
index = 0;
}
else
{
- int n = VARRAY_ACTIVE_SIZE (tf->dest_array);
+ int n = VEC_length (tree, tf->dest_array);
for (index = 0; index < n; ++index)
- if (VARRAY_TREE (tf->dest_array, index) == lab)
+ if (VEC_index (tree, tf->dest_array, index) == lab)
break;
if (index == n)
- VARRAY_PUSH_TREE (tf->dest_array, lab);
+ VEC_safe_push (tree, heap, tf->dest_array, lab);
}
}
break;
do_goto_redirection (q, finally_label, NULL);
replace_goto_queue (tf);
- if (VARRAY_TREE (tf->dest_array, 0) == tf->fallthru_label)
+ if (VEC_index (tree, tf->dest_array, 0) == tf->fallthru_label)
{
/* Reachable by goto to fallthru label only. Redirect it
to the new label (already created, sadly), and do not
tree label;
} *labels;
- if (tf->dest_array)
- return_index = VARRAY_ACTIVE_SIZE (tf->dest_array);
- else
- return_index = 0;
+ return_index = VEC_length (tree, tf->dest_array);
labels = xcalloc (sizeof (*labels), return_index + 1);
q = tf->goto_queue;
lower_eh_constructs_1 (state, &finally);
/* Prepare for switch statement generation. */
- if (tf->dest_array)
- nlabels = VARRAY_ACTIVE_SIZE (tf->dest_array);
- else
- nlabels = 0;
+ nlabels = VEC_length (tree, tf->dest_array);
return_index = nlabels;
eh_index = return_index + tf->may_return;
fallthru_index = eh_index + tf->may_throw;
how many destinations are reached by the finally block. Use this to
determine how we process the finally block itself. */
- if (this_tf.dest_array)
- ndests = VARRAY_ACTIVE_SIZE (this_tf.dest_array);
- else
- ndests = 0;
+ ndests = VEC_length (tree, this_tf.dest_array);
ndests += this_tf.may_fallthru;
ndests += this_tf.may_return;
ndests += this_tf.may_throw;
append_to_statement_list (x, tp);
}
+ VEC_free (tree, heap, this_tf.dest_array);
if (this_tf.goto_queue)
free (this_tf.goto_queue);
}
/* Look for things that can throw exceptions, and record them. */
if (state->cur_region && tree_could_throw_p (t))
{
- tree op;
-
record_stmt_eh_region (state->cur_region, t);
note_eh_region_may_contain_throw (state->cur_region);
-
- /* ??? For the benefit of calls.c, converting all this to rtl,
- we need to record the call expression, not just the outer
- modify statement. */
- op = get_call_expr_in (t);
- if (op)
- record_stmt_eh_region (state->cur_region, op);
}
break;
tree *tp = &DECL_SAVED_TREE (current_function_decl);
finally_tree = htab_create (31, struct_ptr_hash, struct_ptr_eq, free);
- set_eh_throw_stmt_table (cfun, htab_create_ggc (31, struct_ptr_hash,
- struct_ptr_eq,
- ggc_free));
collect_finally_tree (*tp, NULL);
bool
tree_can_throw_internal (tree stmt)
{
- int region_nr = lookup_stmt_eh_region (stmt);
+ int region_nr;
+
+ if (TREE_CODE (stmt) == RESX_EXPR)
+ region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+ else
+ region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
return false;
return can_throw_internal_1 (region_nr);
bool
tree_can_throw_external (tree stmt)
{
- int region_nr = lookup_stmt_eh_region (stmt);
+ int region_nr;
+
+ if (TREE_CODE (stmt) == RESX_EXPR)
+ region_nr = TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0));
+ else
+ region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
- return false;
- return can_throw_external_1 (region_nr);
+ return tree_could_throw_p (stmt);
+ else
+ return can_throw_external_1 (region_nr);
}
bool