c-common.def (IF_STMT, [...]): Move to cp-tree.def.
authorRichard Henderson <rth@redhat.com>
Sun, 20 Jun 2004 09:18:13 +0000 (02:18 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 20 Jun 2004 09:18:13 +0000 (02:18 -0700)
        * 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.

From-SVN: r83407

17 files changed:
gcc/ChangeLog
gcc/c-common.def
gcc/c-common.h
gcc/c-dump.c
gcc/c-gimplify.c
gcc/c-pretty-print.c
gcc/c-semantics.c
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/cxx-pretty-print.c
gcc/cp/decl.c
gcc/cp/dump.c
gcc/cp/semantics.c
gcc/tree.h

index acb2bffd3f5be293e36cd031e81f594b0c0d7283..fd9f0ac0ee1e823b3ad3b0a4e07da8e809cf4828 100644 (file)
@@ -1,3 +1,20 @@
+2004-06-20  Richard Henderson  <rth@redhat.com>
+
+       * 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.
+
 2004-06-20  Zack Weinberg  <zack@codesourcery.com>
 
        * c-common.h (has_c_linkage): New interface.
index b66098a3a27d23795a2a1832bf23bd83b336004f..62dd05703cfdfcbc0ea49d6b839ad7d6100990cc 100644 (file)
@@ -37,10 +37,6 @@ DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1)
    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', 1)
    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 91a18869b2de021a9178f1682a1606f6ab2db30b..073ff70e4ec9e303614c6b91f88c45536501db2d 100644 (file)
@@ -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 74ef44db0322df7a9afc8293ce5f1e371554ca0b..18a8887295f208eee24ae65a6d9ed0feedd3a173 100644 (file)
@@ -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 1f8ce647b9d27c62e7a2ccd95917421efc983392..fa3ea299cc47c8fd2c4425e4ded115f864c55f7f 100644 (file)
@@ -72,8 +72,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 /* 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_p, tree *post_p ATTRIBUTE_UNUSED)
     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 490cf809800308a7178be4a799e1cbb39d48d23e..7ecbe6b08dad46da07c0fb70f740e743fb1ac457 100644 (file)
@@ -1889,75 +1889,22 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
 
   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, tree stmt)
             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, tree stmt)
       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, tree stmt)
       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, tree stmt)
             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, tree stmt)
     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, tree stmt)
       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 8a98e07b3a3d367fb99ff8f136a41f8c1b7d9c89..ba4e90b491169292bd4aa4831bc115372650cf79 100644 (file)
@@ -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 b2718b6b79a58a3feef9544f4595592c8dde3bca..201c5f1c1142ebfa429491e75046946e49ea144d 100644 (file)
@@ -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 compstmt_count, int stmt_count)
   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_scope)
 
   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 ();
+}
 \f
 /* Build a binary-operation expression without default conversions.
    CODE is the kind of expression to build.
index e3048d3dba08536b1c1f336f4dab1db452d504ce..b01e1f8b49def8bfa893bd17f901127eadb1e656 100644 (file)
@@ -1,3 +1,19 @@
+2004-06-20  Richard Henderson  <rth@redhat.com>
+
+       * 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.
+
 2004-06-20  Zack Weinberg  <zack@codesourcery.com>
 
        * cp-lang.c (has_c_linkage): Implement.
index 99016434e42eb1a403a74d7a5c373e4265f16f15..8bdf5f4fcc5993013ab1ccb50248d2d47f6d262b 100644 (file)
@@ -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 *pre_p, tree *post_p)
       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 *pre_p, tree *post_p)
 
   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 3b4c6e6eb5afccae91e7a2ed5aa40b7cf0f28dca..4f7961b7b8aeca556c81cd603de367132436d2b9 100644 (file)
@@ -243,8 +243,11 @@ DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", 'e', 1)
 /* 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 1838c8288f9b6259792b251f5b2578d24ae12618..ae62adc70dd3c538f7d0409d629ed23f6a323165 100644 (file)
@@ -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                         (void *, tree);
 
 /* in cp-simplify.c */
 extern int cp_gimplify_expr                    (tree *, tree *, tree *);
+extern void cp_genericize                      (tree);
 
 /* -- end of C++ */
 
index a50ecc4114c1274a24d4bddd518c2cfd705c016b..cd08611763401da0371df5933b9a93a22fab7e3b 100644 (file)
@@ -1517,6 +1517,43 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t)
       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 dfdfe564991dfc683b45a0b45f1bd2f69a0a2151..84f3b8459af5c7e85ab4e6e2c28b3f53d6ec9a0c 100644 (file)
@@ -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 17b30c94367bb52de4d32ab1eacf1bdaeec21552..fd0a847a409eeac1c59a7d7d85f6b6083fd95718 100644 (file)
@@ -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 74a513a9cd672b32b08c6836840b0c26f4308112..e53222f48b2b4723a213b264c9daac53e9a4fb69 100644 (file)
@@ -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 facd4217f1091b47f0713a133ce927e839672ed0..6babb197c59ccaf8e2d2994a4fdc99070c18a8d8 100644 (file)
@@ -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 (int, enum tree_code,
    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