OSDN Git Service

* fixlib.c (load_file_data): Use XRESIZVEC in lieu of xrealloc.
[pf3gnuchains/gcc-fork.git] / gcc / tree-eh.c
index 3bf5830..7d83746 100644 (file)
@@ -84,19 +84,10 @@ struct_ptr_hash (const void *a)
 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
@@ -120,6 +111,12 @@ add_stmt_to_eh_region_fn (struct function *ifun, tree t, int num)
   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
@@ -143,6 +140,12 @@ remove_stmt_from_eh_region_fn (struct function *ifun, tree t)
   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
@@ -320,7 +323,7 @@ struct leh_tf_state
   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*,
@@ -501,18 +504,18 @@ maybe_record_in_goto_queue (struct leh_state *state, tree stmt)
 
        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;
@@ -996,7 +999,7 @@ lower_try_finally_onedest (struct leh_state *state, struct leh_tf_state *tf)
        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
@@ -1060,10 +1063,7 @@ lower_try_finally_copy (struct leh_state *state, struct leh_tf_state *tf)
        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;
@@ -1152,10 +1152,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
   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;
@@ -1389,10 +1386,7 @@ lower_try_finally (struct leh_state *state, tree *tp)
      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;
@@ -1424,6 +1418,7 @@ lower_try_finally (struct leh_state *state, tree *tp)
       append_to_statement_list (x, tp);
     }
 
+  VEC_free (tree, heap, this_tf.dest_array);
   if (this_tf.goto_queue)
     free (this_tf.goto_queue);
 }
@@ -1618,17 +1613,8 @@ lower_eh_constructs_1 (struct leh_state *state, tree *tp)
       /* 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;
 
@@ -1689,9 +1675,6 @@ lower_eh_constructs (void)
   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);
 
@@ -2025,7 +2008,12 @@ tree_could_throw_p (tree t)
 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);
@@ -2034,10 +2022,16 @@ tree_can_throw_internal (tree stmt)
 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