This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Move IF_STMT, CLEANUP_STMT out of C front end


I wanted to remove IF_STMT completely in favour of COND_EXPR,
but ran into trouble with C++ templates.  So I've retained the
code privately in the C++ front end.

The CLEANUP_STMT code was only needed in the C++ front end to
begin with, so it and it's lowering code has been moved.

c-gimplify.c is getting smaller and smaller...


r~


        * c-common.def (IF_STMT, CLEANUP_STMT): Move to cp-tree.def.
        * c-common.h (IF_COND, THEN_CLAUSE, ELSE_CLAUSE, CLEANUP_BODY,
        CLEANUP_EXPR, CLEANUP_DECL): Move to cp-tree.h.
        (c_common_stmt_codes): Remove IF_STMT, CLEANUP_STMT.
        * c-dump.c (c_dump_tree): Move IF_STMT, CLEANUP_STMT to cp_dump_tree.
        * c-pretty-print.c (pp_c_statement): Similarly.
        * c-gimplify.c (gimplify_cleanup_stmt, gimplify_cleanup_stmts,
        gimplify_if_stmt): Move to cp-gimplify.c.
        (c_genericize, c_gimplify_expr): Don't call them.
        * c-semantics.c (push_cleanup): Move to cp/semantics.c.
        * c-typeck.c (push_cleanup): New.
        (c_begin_if_stmt, c_finish_if_cond, c_finish_then, c_finish_else,
        c_finish_if_stmt): Use COND_EXPR.
        * tree.h (CLEANUP_EH_ONLY): Update documentation.
cp/
        * cp-tree.def (CLEANUP_STMT, IF_STMT): Move from c-common.def.
        * cp-gimplify.c (gimplify_if_stmt): Move from c-gimplify.c.
        (cp_gimplify_expr): Call it.
        (gimplify_cleanup_stmt): Move from c-gimplify.c.
        (cp_genericize): New.
        * decl.c (finish_function): Call it.
        * cp-tree.h (cp_stmt_codes): Add CLEANUP_STMT, IF_STMT.
        (CLEANUP_BODY, CLEANUP_EXPR, CLEANUP_DECL): Move from c-common.h.
        (IF_COND, THEN_CLAUSE, ELSE_CLAUSE): Likewise.
        (cp_genericize): Declare.
        * cxx-pretty-print.c (pp_cxx_statement): Add CLEANUP_STMT, IF_STMT.
        * dump.c (cp_dump_tree): Likewise.
        * semantics.c (push_cleanup): Move from c-semantics.c.

Index: gcc/c-common.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.def,v
retrieving revision 1.20
diff -u -p -u -r1.20 c-common.def
--- gcc/c-common.def	17 Jun 2004 01:23:57 -0000	1.20
+++ gcc/c-common.def	20 Jun 2004 09:02:58 -0000
@@ -37,10 +37,6 @@ DEFTREECODE (EXPR_STMT, "expr_stmt", 'e'
    DECL_STMT_DECL.  */
 DEFTREECODE (DECL_STMT, "decl_stmt", 'e', 1)
 
-/* Represents an 'if' statement. The operands are IF_COND,
-   THEN_CLAUSE, and ELSE_CLAUSE, respectively.  */
-DEFTREECODE (IF_STMT, "if_stmt", 'e', 3)
-
 /* Used to represent a `for' statement. The operands are
    FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively.  */
 DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4)
@@ -78,11 +74,6 @@ DEFTREECODE (STMT_EXPR, "stmt_expr", 'e'
    the compound literal.  */
 DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", 'e', 1)
 
-/* A CLEANUP_STMT marks the point at which a declaration is fully
-   constructed.  The CLEANUP_EXPR is run on behalf of CLEANUP_DECL
-   when CLEANUP_BODY completes.  */
-DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 3)
-
 /*
 Local variables:
 mode:c
Index: gcc/c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.239
diff -u -p -u -r1.239 c-common.h
--- gcc/c-common.h	20 Jun 2004 08:34:43 -0000	1.239
+++ gcc/c-common.h	20 Jun 2004 09:02:58 -0000
@@ -922,13 +922,6 @@ extern void finish_file	(void);
 #define STATEMENT_LIST_STMT_EXPR(NODE) \
   TREE_LANG_FLAG_1 (STATEMENT_LIST_CHECK (NODE))
 
-/* IF_STMT accessors. These give access to the condition of the if
-   statement, the then block of the if statement, and the else block
-   of the if statement if it exists.  */
-#define IF_COND(NODE)           TREE_OPERAND (IF_STMT_CHECK (NODE), 0)
-#define THEN_CLAUSE(NODE)       TREE_OPERAND (IF_STMT_CHECK (NODE), 1)
-#define ELSE_CLAUSE(NODE)       TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
-
 /* WHILE_STMT accessors. These give access to the condition of the
    while statement and the body of the while statement, respectively.  */
 #define WHILE_COND(NODE)        TREE_OPERAND (WHILE_STMT_CHECK (NODE), 0)
@@ -975,16 +968,6 @@ extern void finish_file	(void);
 #define COMPOUND_LITERAL_EXPR_DECL(NODE)			\
   DECL_STMT_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE))
 
-/* The body of the CLEANUP_STMT.  */
-#define CLEANUP_BODY(NODE) \
-  TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0)
-/* The cleanup to run in a CLEANUP_STMT.  */
-#define CLEANUP_EXPR(NODE) \
-  TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1)
-/* The VAR_DECL to clean up in a CLEANUP_STMT.  */
-#define CLEANUP_DECL(NODE) \
-  TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 2)
-
 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
 
 enum c_tree_code {
@@ -996,8 +979,7 @@ enum c_tree_code {
 #undef DEFTREECODE
 
 #define c_common_stmt_codes				\
-   CLEANUP_STMT,	EXPR_STMT,			\
-   DECL_STMT,		IF_STMT,	FOR_STMT,	\
+   EXPR_STMT,		DECL_STMT,	FOR_STMT,	\
    WHILE_STMT,		DO_STMT,	RETURN_STMT,	\
    BREAK_STMT,		CONTINUE_STMT,	SWITCH_STMT
 
Index: gcc/c-dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-dump.c,v
retrieving revision 1.23
diff -u -p -u -r1.23 c-dump.c
--- gcc/c-dump.c	17 Jun 2004 01:23:58 -0000	1.23
+++ gcc/c-dump.c	20 Jun 2004 09:02:58 -0000
@@ -69,13 +69,6 @@ c_dump_tree (void *dump_info, tree t)
       dump_next_stmt (di, t);
       break;
 
-    case CLEANUP_STMT:
-      dump_stmt (di, t);
-      dump_child ("decl", CLEANUP_DECL (t));
-      dump_child ("expr", CLEANUP_EXPR (t));
-      dump_next_stmt (di, t);
-      break;
-
     case DECL_STMT:
       dump_stmt (di, t);
       dump_child ("decl", DECL_STMT_DECL (t));
@@ -104,14 +97,6 @@ c_dump_tree (void *dump_info, tree t)
       dump_next_stmt (di, t);
       break;
 
-    case IF_STMT:
-      dump_stmt (di, t);
-      dump_child ("cond", IF_COND (t));
-      dump_child ("then", THEN_CLAUSE (t));
-      dump_child ("else", ELSE_CLAUSE (t));
-      dump_next_stmt (di, t);
-      break;
-
     case RETURN_STMT:
       dump_stmt (di, t);
       dump_child ("expr", RETURN_STMT_EXPR (t));
Index: gcc/c-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-gimplify.c,v
retrieving revision 2.11
diff -u -p -u -r2.11 c-gimplify.c
--- gcc/c-gimplify.c	19 Jun 2004 19:34:20 -0000	2.11
+++ gcc/c-gimplify.c	20 Jun 2004 09:02:58 -0000
@@ -72,8 +72,6 @@ Software Foundation, 59 Temple Place - S
 
 /* Local declarations.  */
 
-static void gimplify_cleanup_stmts (tree);
-
 enum bc_t { bc_break = 0, bc_continue = 1 };
 
 static struct c_gimplify_ctx
@@ -137,7 +135,6 @@ c_genericize (tree fndecl)
 
   /* Go ahead and gimplify for now.  */
   push_context ();
-  gimplify_cleanup_stmts (fndecl);
   gimplify_function_tree (fndecl);
   pop_context ();
 
@@ -152,30 +149,6 @@ c_genericize (tree fndecl)
     c_genericize (cgn->decl);
 }
 
-/* Genericize a CLEANUP_STMT.  This just turns into a TRY_FINALLY or
-   TRY_CATCH depending on whether it's EH-only.  */
-
-static tree
-gimplify_cleanup_stmt (tree *stmt_p, int *walk_subtrees,
-		       void *data ATTRIBUTE_UNUSED)
-{
-  tree stmt = *stmt_p;
-
-  if (DECL_P (stmt) || TYPE_P (stmt))
-    *walk_subtrees = 0;
-  else if (TREE_CODE (stmt) == CLEANUP_STMT)
-    *stmt_p = build (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR,
-		     void_type_node, CLEANUP_BODY (stmt), CLEANUP_EXPR (stmt));
-
-  return NULL;
-}
-
-static void
-gimplify_cleanup_stmts (tree fndecl)
-{
-  walk_tree (&DECL_SAVED_TREE (fndecl), gimplify_cleanup_stmt, NULL, NULL);
-}
-
 static void
 add_block_to_enclosing (tree block)
 {
@@ -479,28 +452,6 @@ gimplify_do_stmt (tree *stmt_p)
   return GS_ALL_DONE;
 }
 
-/* Genericize an IF_STMT by turning it into a COND_EXPR.  */
-
-static enum gimplify_status
-gimplify_if_stmt (tree *stmt_p)
-{
-  tree stmt, then_, else_;
-
-  stmt = *stmt_p;
-  then_ = THEN_CLAUSE (stmt);
-  else_ = ELSE_CLAUSE (stmt);
-
-  if (!then_)
-    then_ = build_empty_stmt ();
-  if (!else_)
-    else_ = build_empty_stmt ();
-
-  stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
-  *stmt_p = stmt;
-
-  return GS_OK;
-}
-
 /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR.  */
 
 static enum gimplify_status
@@ -670,9 +621,6 @@ c_gimplify_expr (tree *expr_p, tree *pre
     case DO_STMT:
       return gimplify_do_stmt (expr_p);
 
-    case IF_STMT:
-      return gimplify_if_stmt (expr_p);
-
     case SWITCH_STMT:
       return gimplify_switch_stmt (expr_p);
 
Index: gcc/c-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pretty-print.c,v
retrieving revision 1.47
diff -u -p -u -r1.47 c-pretty-print.c
--- gcc/c-pretty-print.c	17 Jun 2004 01:23:58 -0000	1.47
+++ gcc/c-pretty-print.c	20 Jun 2004 09:02:58 -0000
@@ -1889,75 +1889,22 @@ pp_c_statement (c_pretty_printer *pp, tr
 
   if (stmt == NULL)
     return;
+
+  if (pp_needs_newline (pp))
+    pp_newline_and_indent (pp, 0);
   
   code = TREE_CODE (stmt);
   switch (code)
     {
-    case STATEMENT_LIST:
-      {
-	tree_stmt_iterator tsi;
-
-        if (pp_needs_newline (pp))
-          pp_newline_and_indent (pp, 0);
-        pp_c_left_brace (pp);
-        pp_newline_and_indent (pp, 3);
-	for (tsi = tsi_start (stmt); !tsi_end_p (tsi); tsi_next (&tsi))
-          pp_statement (pp, tsi_stmt (tsi));
-        pp_newline_and_indent (pp, -3);
-        pp_c_right_brace (pp);
-        pp_needs_newline (pp) = true;
-      }
-      break;
-
       /* expression-statement:
             expression(opt) ;  */
     case EXPR_STMT:
-    case CLEANUP_STMT:
-      if (pp_needs_newline (pp))
-        pp_newline_and_indent (pp, 0);
-      {
-        tree e = code == EXPR_STMT
-          ? EXPR_STMT_EXPR (stmt)
-          : CLEANUP_EXPR (stmt);
-        if (e)
-          pp_expression (pp, e);
-      }
+      pp_expression (pp, EXPR_STMT_EXPR (stmt));
       pp_c_semicolon (pp);
       pp_needs_newline (pp) = true;
       break;
 
-      /* selection-statement:
-            if ( expression ) statement
-            if ( expression ) statement else statement
-            switch ( expression ) statement   */
-    case IF_STMT:
-      if (pp_needs_newline (pp))
-        pp_newline_and_indent (pp, 0);
-      pp_c_identifier (pp, "if");
-      pp_c_whitespace (pp);
-      pp_c_left_paren (pp);
-      pp_expression (pp, IF_COND (stmt));
-      pp_c_right_paren (pp);
-      pp_newline_and_indent (pp, 3);
-      pp_statement (pp, THEN_CLAUSE (stmt));
-      pp_newline_and_indent (pp, -3);
-      if (ELSE_CLAUSE (stmt))
-	{
-	  tree else_clause = ELSE_CLAUSE (stmt);
-	  pp_c_identifier (pp, "else");
-	  if (TREE_CODE (else_clause) == IF_STMT)
-	    pp_c_whitespace (pp);
-	  else
-	    pp_newline_and_indent (pp, 3);
-	  pp_statement (pp, else_clause);
-	  if (TREE_CODE (else_clause) != IF_STMT)
-	    pp_newline_and_indent (pp, -3);
-	}
-      break;
-
     case SWITCH_STMT:
-      if (pp_needs_newline (pp))
-        pp_newline_and_indent (pp, 0);
       pp_c_identifier (pp, "switch");
       pp_space (pp);
       pp_c_left_paren (pp);
@@ -1975,8 +1922,6 @@ pp_c_statement (c_pretty_printer *pp, tr
             for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
             for ( declaration expression(opt) ; expression(opt) ) statement  */
     case WHILE_STMT:
-      if (pp_needs_newline (pp))
-        pp_newline_and_indent (pp, 0);
       pp_c_identifier (pp, "while");
       pp_space (pp);
       pp_c_left_paren (pp);
@@ -1989,8 +1934,6 @@ pp_c_statement (c_pretty_printer *pp, tr
       break;
 
     case DO_STMT:
-      if (pp_needs_newline (pp))
-        pp_newline_and_indent (pp, 0);
       pp_c_identifier (pp, "do");
       pp_newline_and_indent (pp, 3);
       pp_statement (pp, DO_BODY (stmt));
@@ -2005,8 +1948,6 @@ pp_c_statement (c_pretty_printer *pp, tr
       break;
 
     case FOR_STMT:
-      if (pp_needs_newline (pp))
-        pp_newline_and_indent (pp, 0);
       pp_c_identifier (pp, "for");
       pp_space (pp);
       pp_c_left_paren (pp);
@@ -2036,8 +1977,6 @@ pp_c_statement (c_pretty_printer *pp, tr
             return expression(opt) ;  */
     case BREAK_STMT:
     case CONTINUE_STMT:
-      if (pp_needs_newline (pp))
-        pp_newline_and_indent (pp, 0);
       pp_identifier (pp, code == BREAK_STMT ? "break" : "continue");
       pp_c_semicolon (pp);
       pp_needs_newline (pp) = true;
@@ -2046,8 +1985,6 @@ pp_c_statement (c_pretty_printer *pp, tr
     case RETURN_STMT:
       {
 	tree e = RETURN_STMT_EXPR (stmt);
-        if (pp_needs_newline (pp))
-          pp_newline_and_indent (pp, 0);
 	pp_c_identifier (pp, "return");
         pp_c_whitespace (pp);
 	if (e)
@@ -2063,14 +2000,13 @@ pp_c_statement (c_pretty_printer *pp, tr
       break;
 
     case DECL_STMT:
-      if (pp_needs_newline (pp))
-        pp_newline_and_indent (pp, 0);
       pp_declaration (pp, DECL_STMT_DECL (stmt));
       pp_needs_newline (pp) = true;
       break;
 
     default:
-      pp_unsupported_tree (pp, stmt);
+      dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
+      break;
     }
 }
 
Index: gcc/c-semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-semantics.c,v
retrieving revision 1.85
diff -u -p -u -r1.85 c-semantics.c
--- gcc/c-semantics.c	19 Jun 2004 19:34:20 -0000	1.85
+++ gcc/c-semantics.c	20 Jun 2004 09:02:58 -0000
@@ -158,19 +158,6 @@ add_decl_stmt (tree decl)
   add_stmt (decl_stmt);
 }
 
-/* Queue a cleanup.  CLEANUP is an expression/statement to be executed
-   when the current scope is exited.  EH_ONLY is true when this is not
-   meant to apply to normal control flow transfer.  */
-
-void
-push_cleanup (tree decl, tree cleanup, bool eh_only)
-{
-  tree stmt = build_stmt (CLEANUP_STMT, NULL, cleanup, decl);
-  CLEANUP_EH_ONLY (stmt) = eh_only;
-  add_stmt (stmt);
-  CLEANUP_BODY (stmt) = push_stmt_list ();
-}
-
 /* Build a generic statement based on the given type of node and
    arguments. Similar to `build_nt', except that we set
    EXPR_LOCUS to be the current source location.  */
Index: gcc/c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.320
diff -u -p -u -r1.320 c-typeck.c
--- gcc/c-typeck.c	17 Jun 2004 22:53:13 -0000	1.320
+++ gcc/c-typeck.c	20 Jun 2004 09:02:59 -0000
@@ -6483,8 +6483,7 @@ static int if_stack_space = 0;
 /* Stack pointer.  */
 static int if_stack_pointer = 0;
 
-/* Begin an if-statement.  Returns a newly created IF_STMT if
-   appropriate.  */
+/* Begin an if-statement.  */
 
 void
 c_begin_if_stmt (void)
@@ -6504,7 +6503,7 @@ c_begin_if_stmt (void)
       if_stack = xrealloc (if_stack, if_stack_space * sizeof (if_elt));
     }
 
-  r = add_stmt (build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE));
+  r = add_stmt (build_stmt (COND_EXPR, NULL_TREE, NULL_TREE, NULL_TREE));
 
   /* Record this if statement.  */
   elt = &if_stack[if_stack_pointer++];
@@ -6527,7 +6526,7 @@ c_finish_if_cond (tree cond, int compstm
   if_elt *elt = &if_stack[if_stack_pointer - 1];
   elt->compstmt_count = compstmt_count;
   elt->stmt_count = stmt_count;
-  IF_COND (elt->if_stmt) = lang_hooks.truthvalue_conversion (cond);
+  COND_EXPR_COND (elt->if_stmt) = lang_hooks.truthvalue_conversion (cond);
 }
 
 /* Called after the then-clause for an if-statement is processed.  */
@@ -6536,7 +6535,7 @@ void
 c_finish_then (tree then_stmt)
 {
   if_elt *elt = &if_stack[if_stack_pointer - 1];
-  THEN_CLAUSE (elt->if_stmt) = then_stmt;
+  COND_EXPR_THEN (elt->if_stmt) = then_stmt;
   elt->empty_locus = input_location;
 }
 
@@ -6570,7 +6569,7 @@ void
 c_finish_else (tree else_stmt)
 {
   if_elt *elt = &if_stack[if_stack_pointer - 1];
-  ELSE_CLAUSE (elt->if_stmt) = else_stmt;
+  COND_EXPR_ELSE (elt->if_stmt) = else_stmt;
   elt->empty_locus = input_location;
 }
 
@@ -6582,6 +6581,9 @@ c_finish_if_stmt (int stmt_count)
 {
   if_elt *elt = &if_stack[--if_stack_pointer];
 
+  if (COND_EXPR_ELSE (elt->if_stmt) == NULL)
+    COND_EXPR_ELSE (elt->if_stmt) = build_empty_stmt ();
+
   if (elt->needs_warning)
     warning ("%Hsuggest explicit braces to avoid ambiguous `else'",
 	     EXPR_LOCUS (elt->if_stmt));
@@ -6781,6 +6783,19 @@ c_end_compound_stmt (tree stmt, bool do_
 
   return stmt;
 }
+
+/* Queue a cleanup.  CLEANUP is an expression/statement to be executed
+   when the current scope is exited.  EH_ONLY is true when this is not
+   meant to apply to normal control flow transfer.  */
+
+void
+push_cleanup (tree decl ATTRIBUTE_UNUSED, tree cleanup, bool eh_only)
+{
+  enum tree_code code = eh_only ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR;
+  tree stmt = build_stmt (code, NULL, cleanup);
+  add_stmt (stmt);
+  TREE_OPERAND (stmt, 0) = push_stmt_list ();
+}
 
 /* Build a binary-operation expression without default conversions.
    CODE is the kind of expression to build.
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.522
diff -u -p -u -r1.522 tree.h
--- gcc/tree.h	18 Jun 2004 07:33:08 -0000	1.522
+++ gcc/tree.h	20 Jun 2004 09:03:00 -0000
@@ -209,8 +209,7 @@ struct tree_common GTY(())
        TREE_SYMBOL_REFERENCED in
            IDENTIFIER_NODE
        CLEANUP_EH_ONLY in
-           TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT,
-	   TREE_LIST elements of a block's cleanup list.
+           TARGET_EXPR, WITH_CLEANUP_EXPR
        ASM_INPUT_P in
            ASM_EXPR
        EH_FILTER_MUST_NOT_THROW in EH_FILTER_EXPR
@@ -690,9 +689,9 @@ extern void tree_operand_check_failed (i
    should be cleaned up some day.  */
 #define TREE_STATIC(NODE) ((NODE)->common.static_flag)
 
-/* In a TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT, or element of a
-   block's cleanup list, means that the pertinent cleanup should only be
-   executed if an exception is thrown, not on normal exit of its scope.  */
+/* In a TARGET_EXPR, WITH_CLEANUP_EXPR, means that the pertinent cleanup
+   should only be executed if an exception is thrown, not on normal exit
+   of its scope.  */
 #define CLEANUP_EH_ONLY(NODE) ((NODE)->common.static_flag)
 
 /* In an expr node (usually a conversion) this means the node was made
Index: gcc/cp/cp-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-gimplify.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 cp-gimplify.c
--- gcc/cp/cp-gimplify.c	19 Jun 2004 19:34:22 -0000	1.3
+++ gcc/cp/cp-gimplify.c	20 Jun 2004 09:03:00 -0000
@@ -79,6 +79,26 @@ genericize_eh_spec_block (tree *stmt_p)
   *stmt_p = gimple_build_eh_filter (body, allowed, failure);
 }
 
+/* Genericize an IF_STMT by turning it into a COND_EXPR.  */
+
+static void
+gimplify_if_stmt (tree *stmt_p)
+{
+  tree stmt, then_, else_;
+
+  stmt = *stmt_p;
+  then_ = THEN_CLAUSE (stmt);
+  else_ = ELSE_CLAUSE (stmt);
+
+  if (!then_)
+    then_ = build_empty_stmt ();
+  if (!else_)
+    else_ = build_empty_stmt ();
+
+  stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
+  *stmt_p = stmt;
+}
+
 /* Gimplify initialization from an AGGR_INIT_EXPR.  */
 
 static void
@@ -224,6 +244,11 @@ cp_gimplify_expr (tree *expr_p, tree *pr
       ret = GS_ALL_DONE;
       break;
 
+    case IF_STMT:
+      gimplify_if_stmt (expr_p);
+      ret = GS_OK;
+      break;
+
     default:
       ret = c_gimplify_expr (expr_p, pre_p, post_p);
       break;
@@ -236,3 +261,33 @@ cp_gimplify_expr (tree *expr_p, tree *pr
 
   return ret;
 }
+
+/* Genericize a CLEANUP_STMT.  This just turns into a TRY_FINALLY or
+   TRY_CATCH depending on whether it's EH-only.  */
+
+static tree
+gimplify_cleanup_stmt (tree *stmt_p, int *walk_subtrees,
+		       void *data ATTRIBUTE_UNUSED)
+{
+  tree stmt = *stmt_p;
+
+  if (DECL_P (stmt) || TYPE_P (stmt))
+    *walk_subtrees = 0;
+  else if (TREE_CODE (stmt) == CLEANUP_STMT)
+    *stmt_p = build (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR,
+		     void_type_node, CLEANUP_BODY (stmt), CLEANUP_EXPR (stmt));
+
+  return NULL;
+}
+
+void
+cp_genericize (tree fndecl)
+{
+  /* Due to the way voidify_wrapper_expr is written, we don't get a chance
+     to lower this construct before scanning it.  So we need to lower these
+     before doing anything else.  */
+  walk_tree (&DECL_SAVED_TREE (fndecl), gimplify_cleanup_stmt, NULL, NULL);
+
+  /* Do everything else.  */
+  c_genericize (fndecl);
+}
Index: gcc/cp/cp-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.def,v
retrieving revision 1.85
diff -u -p -u -r1.85 cp-tree.def
--- gcc/cp/cp-tree.def	31 May 2004 08:42:31 -0000	1.85
+++ gcc/cp/cp-tree.def	20 Jun 2004 09:03:00 -0000
@@ -243,8 +243,11 @@ DEFTREECODE (NON_DEPENDENT_EXPR, "non_de
 /* CTOR_INITIALIZER is a placeholder in template code for a call to
    setup_vtbl_pointer (and appears in all functions, not just ctors).  */
 DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1)
+
 DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
+
 DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2)
+
 /* A HANDLER wraps a catch handler for the HANDLER_TYPE.  If this is
    CATCH_ALL_TYPE, then the handler catches all types.  The declaration of
    the catch variable is in HANDLER_PARMS, and the body block in
@@ -255,6 +258,17 @@ DEFTREECODE (HANDLER, "handler", 'e', 2)
    throw, and must call terminate if it does.  */
 DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", 'e', 1)
 
+/* A CLEANUP_STMT marks the point at which a declaration is fully
+   constructed.  The CLEANUP_EXPR is run on behalf of CLEANUP_DECL
+   when CLEANUP_BODY completes.  */
+DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 3)
+
+/* Represents an 'if' statement. The operands are IF_COND,
+   THEN_CLAUSE, and ELSE_CLAUSE, respectively.  */
+/* ??? It is currently still necessary to distinguish between IF_STMT 
+   and COND_EXPR for the benefit of templates.  */
+DEFTREECODE (IF_STMT, "if_stmt", 'e', 3)
+
 DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0)
 
 /* Template instantiation level node.
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.981
diff -u -p -u -r1.981 cp-tree.h
--- gcc/cp/cp-tree.h	20 Jun 2004 08:34:47 -0000	1.981
+++ gcc/cp/cp-tree.h	20 Jun 2004 09:03:00 -0000
@@ -892,7 +892,8 @@ enum cplus_tree_code {
 
 #define cp_stmt_codes					\
    CTOR_INITIALIZER,	TRY_BLOCK,	HANDLER,	\
-   EH_SPEC_BLOCK,	USING_STMT,	TAG_DEFN
+   EH_SPEC_BLOCK,	USING_STMT,	TAG_DEFN,	\
+   IF_STMT,		CLEANUP_STMT
 
 enum languages { lang_c, lang_cplusplus, lang_java };
 
@@ -2939,6 +2940,19 @@ struct lang_decl GTY(())
 #define HANDLER_BODY(NODE)      TREE_OPERAND (HANDLER_CHECK (NODE), 1)
 #define HANDLER_TYPE(NODE)	TREE_TYPE (HANDLER_CHECK (NODE))
 
+/* CLEANUP_STMT accessors.  The statement(s) covered, the cleanup to run
+   and the VAR_DECL for which this cleanup exists.  */
+#define CLEANUP_BODY(NODE)	TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 0)
+#define CLEANUP_EXPR(NODE)	TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 1)
+#define CLEANUP_DECL(NODE)	TREE_OPERAND (CLEANUP_STMT_CHECK (NODE), 2)
+
+/* IF_STMT accessors. These give access to the condition of the if
+   statement, the then block of the if statement, and the else block
+   of the if statement if it exists.  */
+#define IF_COND(NODE)           TREE_OPERAND (IF_STMT_CHECK (NODE), 0)
+#define THEN_CLAUSE(NODE)       TREE_OPERAND (IF_STMT_CHECK (NODE), 1)
+#define ELSE_CLAUSE(NODE)       TREE_OPERAND (IF_STMT_CHECK (NODE), 2)
+
 /* The parameters for a call-declarator.  */
 #define CALL_DECLARATOR_PARMS(NODE) \
   (TREE_PURPOSE (TREE_OPERAND (NODE, 1)))
@@ -4304,6 +4318,7 @@ extern bool cp_dump_tree                
 
 /* in cp-simplify.c */
 extern int cp_gimplify_expr		        (tree *, tree *, tree *);
+extern void cp_genericize			(tree);
 
 /* -- end of C++ */
 
Index: gcc/cp/cxx-pretty-print.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cxx-pretty-print.c,v
retrieving revision 1.22
diff -u -p -u -r1.22 cxx-pretty-print.c
--- gcc/cp/cxx-pretty-print.c	17 Jun 2004 01:24:03 -0000	1.22
+++ gcc/cp/cxx-pretty-print.c	20 Jun 2004 09:03:01 -0000
@@ -1517,6 +1517,43 @@ pp_cxx_statement (cxx_pretty_printer *pp
       pp_needs_newline (pp) = true;
       break;
 
+      /* selection-statement:
+            if ( expression ) statement
+            if ( expression ) statement else statement  */
+    case IF_STMT:
+      pp_cxx_identifier (pp, "if");
+      pp_cxx_whitespace (pp);
+      pp_cxx_left_paren (pp);
+      pp_cxx_expression (pp, IF_COND (t));
+      pp_cxx_right_paren (pp);
+      pp_newline_and_indent (pp, 2);
+      pp_cxx_statement (pp, THEN_CLAUSE (t));
+      pp_newline_and_indent (pp, -2);
+      if (ELSE_CLAUSE (t))
+	{
+	  tree else_clause = ELSE_CLAUSE (t);
+	  pp_cxx_identifier (pp, "else");
+	  if (TREE_CODE (else_clause) == IF_STMT)
+	    pp_cxx_whitespace (pp);
+	  else
+	    pp_newline_and_indent (pp, 2);
+	  pp_cxx_statement (pp, else_clause);
+	  if (TREE_CODE (else_clause) != IF_STMT)
+	    pp_newline_and_indent (pp, -2);
+	}
+      break;
+
+    case CLEANUP_STMT:
+      pp_cxx_identifier (pp, "try");
+      pp_newline_and_indent (pp, 2);
+      pp_cxx_statement (pp, CLEANUP_BODY (t));
+      pp_newline_and_indent (pp, -2);
+      pp_cxx_identifier (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
+      pp_newline_and_indent (pp, 2);
+      pp_cxx_statement (pp, CLEANUP_EXPR (t));
+      pp_newline_and_indent (pp, -2);
+      break;
+
     default:
       pp_c_statement (pp_c_base (pp), t);
       break;
Index: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1221
diff -u -p -u -r1.1221 decl.c
--- gcc/cp/decl.c	20 Jun 2004 08:34:49 -0000	1.1221
+++ gcc/cp/decl.c	20 Jun 2004 09:03:02 -0000
@@ -10812,7 +10812,7 @@ finish_function (int flags)
   /* Genericize before inlining.  */
   if (!processing_template_decl)
     {
-      c_genericize (fndecl);
+      cp_genericize (fndecl);
 
       /* Handle attribute((warn_unused_result)).  Relies on gimple input.  */
       c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
Index: gcc/cp/dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/dump.c,v
retrieving revision 1.74
diff -u -p -u -r1.74 dump.c
--- gcc/cp/dump.c	8 Dec 2003 20:29:15 -0000	1.74
+++ gcc/cp/dump.c	20 Jun 2004 09:03:02 -0000
@@ -411,7 +411,23 @@ cp_dump_tree (void* dump_info, tree t)
       dump_child ("nmsp", USING_STMT_NAMESPACE (t));
       dump_next_stmt (di, t);
       break;
-      
+
+    case CLEANUP_STMT:
+      dump_stmt (di, t);
+      dump_child ("decl", CLEANUP_DECL (t));
+      dump_child ("expr", CLEANUP_EXPR (t));
+      dump_child ("body", CLEANUP_BODY (t));
+      dump_next_stmt (di, t);
+      break;
+
+    case IF_STMT:
+      dump_stmt (di, t);
+      dump_child ("cond", IF_COND (t));
+      dump_child ("then", THEN_CLAUSE (t));
+      dump_child ("else", ELSE_CLAUSE (t));
+      dump_next_stmt (di, t);
+      break;
+
     default:
       break;
     }
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.403
diff -u -p -u -r1.403 semantics.c
--- gcc/cp/semantics.c	18 Jun 2004 22:51:57 -0000	1.403
+++ gcc/cp/semantics.c	20 Jun 2004 09:03:02 -0000
@@ -346,6 +346,19 @@ do_pushlevel (scope_kind sk)
   return ret;
 }
 
+/* Queue a cleanup.  CLEANUP is an expression/statement to be executed
+   when the current scope is exited.  EH_ONLY is true when this is not
+   meant to apply to normal control flow transfer.  */
+
+void
+push_cleanup (tree decl, tree cleanup, bool eh_only)
+{
+  tree stmt = build_stmt (CLEANUP_STMT, NULL, cleanup, decl);
+  CLEANUP_EH_ONLY (stmt) = eh_only;
+  add_stmt (stmt);
+  CLEANUP_BODY (stmt) = push_stmt_list ();
+}
+
 /* Begin a conditional that might contain a declaration.  When generating
    normal code, we want the declaration to appear before the statement
    containing the conditional.  When generating template code, we want the


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]