From 59ccf49da343eb034258f5fe6282da6ed6751cf4 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 27 Sep 1999 01:27:18 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/Makefile.in | 2 +- gcc/cp/cp-tree.h | 1 - gcc/cp/except.c | 51 ++++++++++++++++++++++++--------------------------- gcc/cp/expr.c | 4 +++- gcc/cp/ir.texi | 12 +++++++----- 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 + * 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 -- 2.7.4