aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-09-27 01:27:18 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-09-27 01:27:18 +0000
commit59ccf49da343eb034258f5fe6282da6ed6751cf4 (patch)
tree1b29796b2aee3f4dfa3db27106f7aebfefc0e732 /gcc/cp
parentbfcccecc564752b7ef55ac9ca32ab8df0c5ba1dc (diff)
downloadgcc-59ccf49da343eb034258f5fe6282da6ed6751cf4.zip
gcc-59ccf49da343eb034258f5fe6282da6ed6751cf4.tar.gz
gcc-59ccf49da343eb034258f5fe6282da6ed6751cf4.tar.bz2
cp-tree.h (expand_throw): Remove prototype.
* 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 immediate_size_expand; instead, assert that it has the expected value already. From-SVN: r29671
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/Makefile.in2
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/except.c51
-rw-r--r--gcc/cp/expr.c4
-rw-r--r--gcc/cp/ir.texi12
6 files changed, 44 insertions, 35 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0b30ff3..19e4dd3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in
index 5f0b118..047f391 100644
--- a/gcc/cp/Makefile.in
+++ b/gcc/cp/Makefile.in
@@ -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 \
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 15c5099..3abea7d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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));
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index a078e65..eec0d7c 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -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;
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 741174e..5b5352e 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -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:
diff --git a/gcc/cp/ir.texi b/gcc/cp/ir.texi
index 26f4058..32a0bf3 100644
--- a/gcc/cp/ir.texi
+++ b/gcc/cp/ir.texi
@@ -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