patch: TRY_FINALLY_EXPR checked in

Per Bothner bothner@cygnus.com
Fri Feb 19 11:23:00 GMT 1999


This is a slight revision (mainly comments) of my Feb 8 patch,
but without the Java-specific part.  It is now checked in (except
the Java-specific aprt, which I will check in soon).

	--Per Bothner
Cygnus Solutions     bothner@cygnus.com     http://www.cygnus.com/~bothner


Thu Feb 18 16:36:58 1999  Per Bothner  <bothner@cygnus.com>

	* tree.def (TRY_FINALLY_EXPR, GOTO_SUBROUTINE_EXPR):  New tree nodes,
	* expr.c (expand_expr):  Support new tree nodes.

Index: tree.def
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/tree.def,v
retrieving revision 1.17
diff -u -p -r1.17 tree.def
--- tree.def	1999/01/06 20:51:18	1.17
+++ tree.def	1999/02/19 19:17:56
@@ -702,6 +702,27 @@ DEFTREECODE (POSTINCREMENT_EXPR, "postin
    evaluated unless an exception is throw.  */
 DEFTREECODE (TRY_CATCH_EXPR, "try_catch_expr", 'e', 2)
 
+/* Evaluate the first operand.
+   The second operand is a a cleanup expression which is evaluated
+   before an exit (normal, exception, or jump out) from this expression.
+
+   Like a CLEANUP_POINT_EXPR/WITH_CLEANUP_EXPR combination, but those
+   always copy the cleanup expression where needed.  In contrast,
+   TRY_FINALLY_EXPR generates a jump to a cleanup subroutine.
+   (At least conceptually; the optimizer could inline the cleanup
+   subroutine in the same way it could inline normal subroutines.)
+   TRY_FINALLY_EXPR should be used when the cleanup is actual statements
+   in the source of the current function (which people might want to
+   set breakpoints in).  */
+DEFTREECODE (TRY_FINALLY_EXPR, "try_finally", 'e', 2)
+
+/* Used internally for cleanups in the implementation of TRY_FINALLY_EXPR.
+   (Specifically, it is created by expand_expr, not front-ends.)
+   Operand 0 is the rtx for the start of the subroutine we need to call.
+   Operand 1 is the rtx for a variable in which to store the address
+   of where the subroutine should return to.  */
+DEFTREECODE (GOTO_SUBROUTINE_EXPR, "goto_subroutine", 'e', 2)
+
 /* Pop the top element off the dynamic handler chain.  Used in
    conjunction with setjmp/longjmp based exception handling, see
    except.c for more details.  This is meant to be used only by the
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.127
diff -u -p -r1.127 expr.c
--- expr.c	1999/02/14 20:08:35	1.127
+++ expr.c	1999/02/19 19:17:57
@@ -6720,7 +6720,6 @@ expand_expr (exp, target, tmode, modifie
 
     case CLEANUP_POINT_EXPR:
       {
-	extern int temp_slot_level;
 	/* Start a new binding layer that will keep track of all cleanup
 	   actions to be performed.  */
 	expand_start_bindings (0);
@@ -8086,6 +8085,47 @@ expand_expr (exp, target, tmode, modifie
 	expand_eh_region_end (handler);
 
 	return op0;
+      }
+
+    case TRY_FINALLY_EXPR:
+      {
+	tree try_block = TREE_OPERAND (exp, 0);
+	tree finally_block = TREE_OPERAND (exp, 1);
+	rtx finally_label = gen_label_rtx ();
+	rtx done_label = gen_label_rtx ();
+	rtx return_link = gen_reg_rtx (Pmode);
+	tree cleanup = build (GOTO_SUBROUTINE_EXPR, void_type_node,
+			      (tree) finally_label, (tree) return_link);
+	TREE_SIDE_EFFECTS (cleanup) = 1;
+
+	/* Start a new binding layer that will keep track of all cleanup
+	   actions to be performed.  */
+	expand_start_bindings (0);
+
+	target_temp_slot_level = temp_slot_level;
+
+	expand_decl_cleanup (NULL_TREE, cleanup);
+	op0 = expand_expr (try_block, target, tmode, modifier);
+
+	preserve_temp_slots (op0);
+	expand_end_bindings (NULL_TREE, 0, 0);
+	emit_jump (done_label);
+	emit_label (finally_label);
+	expand_expr (finally_block, const0_rtx, VOIDmode, 0);
+	emit_indirect_jump (return_link);
+	emit_label (done_label);
+	return op0;
+      }
+
+      case GOTO_SUBROUTINE_EXPR:
+      {
+	rtx subr = (rtx) TREE_OPERAND (exp, 0);
+	rtx return_link = *(rtx *) &TREE_OPERAND (exp, 1);
+	rtx return_address = gen_label_rtx ();
+	emit_move_insn (return_link, gen_rtx_LABEL_REF (Pmode, return_address));
+	emit_jump (subr);
+	emit_label (return_address);
+	return const0_rtx;
       }
 
     case POPDCC_EXPR:


More information about the Gcc-patches mailing list