OSDN Git Service

* cp-tree.h (expand_throw): Remove prototype.
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 27 Sep 1999 01:27:18 +0000 (01:27 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 27 Sep 1999 01:27:18 +0000 (01:27 +0000)
* except.c (expand_throw): Make it static.  Use tree-generation
functions, rather than RTL-generation functions.
(build_throw): Use it.
* expr.c: Include except.h.
(cplus_expand_expr): Don't call expand_throw here.
* Makefile.in (expr.o): Depend on except.h.
* ir.texi: Update documentation for THROW_EXPR.

* decl.c (start_function): Set x_dont_save_pending_sizes rather
than calling get_pending_sizes.
* init.c (build_new): Don't save and restore
immediate_size_expand; instead, assert that it has the expected
value already.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29671 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/Makefile.in
gcc/cp/cp-tree.h
gcc/cp/except.c
gcc/cp/expr.c
gcc/cp/ir.texi

index 0b30ff3..19e4dd3 100644 (file)
@@ -1,5 +1,14 @@
 1999-09-26  Mark Mitchell  <mark@codesourcery.com>
 
+       * cp-tree.h (expand_throw): Remove prototype.
+       * except.c (expand_throw): Make it static.  Use tree-generation
+       functions, rather than RTL-generation functions.
+       (build_throw): Use it.
+       * expr.c: Include except.h.
+       (cplus_expand_expr): Don't call expand_throw here.
+       * Makefile.in (expr.o): Depend on except.h.
+       * ir.texi: Update documentation for THROW_EXPR.
+       
        * decl.c (start_function): Set x_dont_save_pending_sizes rather
        than calling get_pending_sizes.
        * init.c (build_new): Don't save and restore
index 5f0b118..047f391 100644 (file)
@@ -282,7 +282,7 @@ rtti.o : rtti.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
 except.o : except.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
   $(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h
 expr.o : expr.c $(CONFIG_H) $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \
-  $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h
+  $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../except.h
 xref.o : xref.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../input.h \
   $(srcdir)/../system.h $(srcdir)/../toplev.h
 pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H) lex.h \
index 15c5099..3abea7d 100644 (file)
@@ -3456,7 +3456,6 @@ extern void expand_end_eh_spec                    PROTO((tree, tree));
 extern void expand_exception_blocks            PROTO((void));
 extern tree start_anon_func                    PROTO((void));
 extern void end_anon_func                      PROTO((void));
-extern void expand_throw                       PROTO((tree));
 extern tree build_throw                                PROTO((tree));
 extern void mark_all_runtime_matches            PROTO((void));
 
index a078e65..eec0d7c 100644 (file)
@@ -54,6 +54,7 @@ static tree build_terminate_handler PROTO((void));
 static tree alloc_eh_object PROTO((tree));
 static int complete_ptr_ref_or_void_ptr_p PROTO((tree, tree));
 static void initialize_handler_parm PROTO((tree));
+static tree expand_throw PROTO((tree));
 
 #if 0
 /* This is the startup, and finish stuff per exception table.  */
@@ -825,19 +826,24 @@ alloc_eh_object (type)
                generate a label for the throw block
        4. jump to the throw block label.  */
 
-void
+tree
 expand_throw (exp)
      tree exp;
 {
   tree fn;
 
   if (! doing_eh (1))
-    return;
+    return error_mark_node;
 
   if (exp)
     {
       tree throw_type;
       tree cleanup = NULL_TREE, e;
+      tree stmt_expr;
+      tree compound_stmt;
+      tree try_block;
+
+      begin_init_stmts (&stmt_expr, &compound_stmt);
 
       /* throw expression */
       /* First, decay it.  */
@@ -846,15 +852,11 @@ expand_throw (exp)
       /* cleanup_type is void (*)(void *, int),
         the internal type of a destructor. */
       if (cleanup_type == NULL_TREE)
-       {
-         push_permanent_obstack ();
-         cleanup_type = build_pointer_type
-           (build_function_type
-            (void_type_node, tree_cons
-             (NULL_TREE, ptr_type_node, tree_cons
-              (NULL_TREE, integer_type_node, void_list_node))));
-         pop_obstacks ();
-       }
+       cleanup_type = build_pointer_type
+         (build_function_type
+          (void_type_node, tree_cons
+           (NULL_TREE, ptr_type_node, tree_cons
+            (NULL_TREE, integer_type_node, void_list_node))));
 
       if (TYPE_PTR_P (TREE_TYPE (exp)))
        throw_type = build_eh_type (exp);
@@ -876,12 +878,8 @@ expand_throw (exp)
             first.  Since there could be temps in the expression, we need
             to handle that, too.  */
 
-         expand_start_target_temps ();
+         my_friendly_assert (stmts_are_full_exprs_p == 1, 19990926);
 
-#if 0
-         /* Unfortunately, this doesn't work.  */
-         preexpand_calls (exp);
-#else
          /* Store the throw expression into a temp.  This can be less
             efficient than storing it into the allocated space directly, but
             oh well.  To do this efficiently we would need to insinuate
@@ -893,23 +891,21 @@ expand_throw (exp)
              cp_finish_decl (temp, exp, NULL_TREE, 0, LOOKUP_ONLYCONVERTING);
              exp = temp;
            }
-#endif
 
          /* Allocate the space for the exception.  */
          ptr = save_expr (alloc_eh_object (TREE_TYPE (exp)));
-         expand_expr (ptr, const0_rtx, VOIDmode, 0);
-
-         expand_eh_region_start ();
+         finish_expr_stmt (ptr);
 
+         try_block = begin_try_block ();
          object = build_indirect_ref (ptr, NULL_PTR);
          exp = build_modify_expr (object, INIT_EXPR, exp);
 
          if (exp == error_mark_node)
            error ("  in thrown expression");
 
-         expand_expr (exp, const0_rtx, VOIDmode, 0);
-         expand_eh_region_end (build_terminate_handler ());
-         expand_end_target_temps ();
+         finish_expr_stmt (exp);
+         finish_cleanup_try_block (try_block);
+         finish_cleanup (build_terminate_handler (), try_block);
 
          throw_type = build_eh_type (object);
 
@@ -964,8 +960,9 @@ expand_throw (exp)
       e = tree_cons (NULL_TREE, exp, tree_cons
                     (NULL_TREE, throw_type, tree_cons
                      (NULL_TREE, cleanup, NULL_TREE)));
-      e = build_function_call (fn, e);
-      expand_expr (e, const0_rtx, VOIDmode, 0);
+      finish_expr_stmt (build_function_call (fn, e));
+
+      exp = finish_init_stmts (stmt_expr, compound_stmt);
     }
   else
     {
@@ -992,10 +989,9 @@ expand_throw (exp)
 
       mark_used (fn);
       exp = build_function_call (fn, NULL_TREE);
-      expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
     }
 
-  expand_internal_throw ();
+  return exp;
 }
 
 /* Build a throw expression.  */
@@ -1019,6 +1015,7 @@ build_throw (e)
         return error_mark_node;
     }
 
+  e = expand_throw (e);
   e = build1 (THROW_EXPR, void_type_node, e);
   TREE_SIDE_EFFECTS (e) = 1;
   TREE_USED (e) = 1;
index 741174e..5b5352e 100644 (file)
@@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA.  */
 #include "expr.h"
 #include "cp-tree.h"
 #include "toplev.h"
+#include "except.h"
 
 #if 0
 static tree extract_aggr_init PROTO((tree, tree));
@@ -228,7 +229,8 @@ cplus_expand_expr (exp, target, tmode, modifier)
       return DECL_RTL (exp);
 
     case THROW_EXPR:
-      expand_throw (TREE_OPERAND (exp, 0));
+      expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, 0);
+      expand_internal_throw ();
       return NULL;
 
     case VEC_INIT_EXPR:
index 26f4058..32a0bf3 100644 (file)
@@ -1621,11 +1621,13 @@ function calls are made explicit.
 
 @item THROW_EXPR
 These nodes represent @code{throw} expressions.  The single operand is
-the expression to be thrown.  If the throw expression is of the form 
-@example
-throw;
-@end example
-then the operand is @code{NULL_TREE}.
+an expression for the code that should be executed to throw the
+exception.  However, there is one implicit action not represented in
+that expression; namely the call to @code{__throw}.  This function takes
+no arguments.  If @code{setjmp}/@code{longjmp} exceptiosn are used, the
+function @code{__sjthrow} is called instead.  The normal G++ back-end
+uses the function @code{emit_throw} to generate this code; you can
+examine this function to see what needs to be done.
 
 @item LSHIFT_EXPR
 @itemx RSHIFT_EXPR