Commit 5a508662 by Richard Henderson Committed by Richard Henderson

c-common.def (IF_STMT, [...]): Move to cp-tree.def.

        * 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
parent 500e1264
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> 2004-06-20 Zack Weinberg <zack@codesourcery.com>
* c-common.h (has_c_linkage): New interface. * c-common.h (has_c_linkage): New interface.
......
...@@ -37,10 +37,6 @@ DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1) ...@@ -37,10 +37,6 @@ DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1)
DECL_STMT_DECL. */ DECL_STMT_DECL. */
DEFTREECODE (DECL_STMT, "decl_stmt", 'e', 1) 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 /* Used to represent a `for' statement. The operands are
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */ FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4) DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4)
...@@ -78,11 +74,6 @@ DEFTREECODE (STMT_EXPR, "stmt_expr", 'e', 1) ...@@ -78,11 +74,6 @@ DEFTREECODE (STMT_EXPR, "stmt_expr", 'e', 1)
the compound literal. */ the compound literal. */
DEFTREECODE (COMPOUND_LITERAL_EXPR, "compound_literal_expr", 'e', 1) 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: Local variables:
mode:c mode:c
......
...@@ -922,13 +922,6 @@ extern void finish_file (void); ...@@ -922,13 +922,6 @@ extern void finish_file (void);
#define STATEMENT_LIST_STMT_EXPR(NODE) \ #define STATEMENT_LIST_STMT_EXPR(NODE) \
TREE_LANG_FLAG_1 (STATEMENT_LIST_CHECK (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_STMT accessors. These give access to the condition of the
while statement and the body of the while statement, respectively. */ while statement and the body of the while statement, respectively. */
#define WHILE_COND(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 0) #define WHILE_COND(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 0)
...@@ -975,16 +968,6 @@ extern void finish_file (void); ...@@ -975,16 +968,6 @@ extern void finish_file (void);
#define COMPOUND_LITERAL_EXPR_DECL(NODE) \ #define COMPOUND_LITERAL_EXPR_DECL(NODE) \
DECL_STMT_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (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, #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
enum c_tree_code { enum c_tree_code {
...@@ -996,8 +979,7 @@ enum c_tree_code { ...@@ -996,8 +979,7 @@ enum c_tree_code {
#undef DEFTREECODE #undef DEFTREECODE
#define c_common_stmt_codes \ #define c_common_stmt_codes \
CLEANUP_STMT, EXPR_STMT, \ EXPR_STMT, DECL_STMT, FOR_STMT, \
DECL_STMT, IF_STMT, FOR_STMT, \
WHILE_STMT, DO_STMT, RETURN_STMT, \ WHILE_STMT, DO_STMT, RETURN_STMT, \
BREAK_STMT, CONTINUE_STMT, SWITCH_STMT BREAK_STMT, CONTINUE_STMT, SWITCH_STMT
......
...@@ -69,13 +69,6 @@ c_dump_tree (void *dump_info, tree t) ...@@ -69,13 +69,6 @@ c_dump_tree (void *dump_info, tree t)
dump_next_stmt (di, t); dump_next_stmt (di, t);
break; 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: case DECL_STMT:
dump_stmt (di, t); dump_stmt (di, t);
dump_child ("decl", DECL_STMT_DECL (t)); dump_child ("decl", DECL_STMT_DECL (t));
...@@ -104,14 +97,6 @@ c_dump_tree (void *dump_info, tree t) ...@@ -104,14 +97,6 @@ c_dump_tree (void *dump_info, tree t)
dump_next_stmt (di, t); dump_next_stmt (di, t);
break; 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: case RETURN_STMT:
dump_stmt (di, t); dump_stmt (di, t);
dump_child ("expr", RETURN_STMT_EXPR (t)); dump_child ("expr", RETURN_STMT_EXPR (t));
......
...@@ -72,8 +72,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -72,8 +72,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Local declarations. */ /* Local declarations. */
static void gimplify_cleanup_stmts (tree);
enum bc_t { bc_break = 0, bc_continue = 1 }; enum bc_t { bc_break = 0, bc_continue = 1 };
static struct c_gimplify_ctx static struct c_gimplify_ctx
...@@ -137,7 +135,6 @@ c_genericize (tree fndecl) ...@@ -137,7 +135,6 @@ c_genericize (tree fndecl)
/* Go ahead and gimplify for now. */ /* Go ahead and gimplify for now. */
push_context (); push_context ();
gimplify_cleanup_stmts (fndecl);
gimplify_function_tree (fndecl); gimplify_function_tree (fndecl);
pop_context (); pop_context ();
...@@ -152,30 +149,6 @@ c_genericize (tree fndecl) ...@@ -152,30 +149,6 @@ c_genericize (tree fndecl)
c_genericize (cgn->decl); 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 static void
add_block_to_enclosing (tree block) add_block_to_enclosing (tree block)
{ {
...@@ -479,28 +452,6 @@ gimplify_do_stmt (tree *stmt_p) ...@@ -479,28 +452,6 @@ gimplify_do_stmt (tree *stmt_p)
return GS_ALL_DONE; 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. */ /* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR. */
static enum gimplify_status static enum gimplify_status
...@@ -670,9 +621,6 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED) ...@@ -670,9 +621,6 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
case DO_STMT: case DO_STMT:
return gimplify_do_stmt (expr_p); return gimplify_do_stmt (expr_p);
case IF_STMT:
return gimplify_if_stmt (expr_p);
case SWITCH_STMT: case SWITCH_STMT:
return gimplify_switch_stmt (expr_p); return gimplify_switch_stmt (expr_p);
......
...@@ -1889,75 +1889,22 @@ pp_c_statement (c_pretty_printer *pp, tree stmt) ...@@ -1889,75 +1889,22 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
if (stmt == NULL) if (stmt == NULL)
return; return;
if (pp_needs_newline (pp))
pp_newline_and_indent (pp, 0);
code = TREE_CODE (stmt); code = TREE_CODE (stmt);
switch (code) 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-statement:
expression(opt) ; */ expression(opt) ; */
case EXPR_STMT: case EXPR_STMT:
case CLEANUP_STMT: pp_expression (pp, EXPR_STMT_EXPR (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_c_semicolon (pp); pp_c_semicolon (pp);
pp_needs_newline (pp) = true; pp_needs_newline (pp) = true;
break; 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: case SWITCH_STMT:
if (pp_needs_newline (pp))
pp_newline_and_indent (pp, 0);
pp_c_identifier (pp, "switch"); pp_c_identifier (pp, "switch");
pp_space (pp); pp_space (pp);
pp_c_left_paren (pp); pp_c_left_paren (pp);
...@@ -1975,8 +1922,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt) ...@@ -1975,8 +1922,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
for ( expression(opt) ; expression(opt) ; expression(opt) ) statement for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
for ( declaration expression(opt) ; expression(opt) ) statement */ for ( declaration expression(opt) ; expression(opt) ) statement */
case WHILE_STMT: case WHILE_STMT:
if (pp_needs_newline (pp))
pp_newline_and_indent (pp, 0);
pp_c_identifier (pp, "while"); pp_c_identifier (pp, "while");
pp_space (pp); pp_space (pp);
pp_c_left_paren (pp); pp_c_left_paren (pp);
...@@ -1989,8 +1934,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt) ...@@ -1989,8 +1934,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
break; break;
case DO_STMT: case DO_STMT:
if (pp_needs_newline (pp))
pp_newline_and_indent (pp, 0);
pp_c_identifier (pp, "do"); pp_c_identifier (pp, "do");
pp_newline_and_indent (pp, 3); pp_newline_and_indent (pp, 3);
pp_statement (pp, DO_BODY (stmt)); pp_statement (pp, DO_BODY (stmt));
...@@ -2005,8 +1948,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt) ...@@ -2005,8 +1948,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
break; break;
case FOR_STMT: case FOR_STMT:
if (pp_needs_newline (pp))
pp_newline_and_indent (pp, 0);
pp_c_identifier (pp, "for"); pp_c_identifier (pp, "for");
pp_space (pp); pp_space (pp);
pp_c_left_paren (pp); pp_c_left_paren (pp);
...@@ -2036,8 +1977,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt) ...@@ -2036,8 +1977,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
return expression(opt) ; */ return expression(opt) ; */
case BREAK_STMT: case BREAK_STMT:
case CONTINUE_STMT: case CONTINUE_STMT:
if (pp_needs_newline (pp))
pp_newline_and_indent (pp, 0);
pp_identifier (pp, code == BREAK_STMT ? "break" : "continue"); pp_identifier (pp, code == BREAK_STMT ? "break" : "continue");
pp_c_semicolon (pp); pp_c_semicolon (pp);
pp_needs_newline (pp) = true; pp_needs_newline (pp) = true;
...@@ -2046,8 +1985,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt) ...@@ -2046,8 +1985,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
case RETURN_STMT: case RETURN_STMT:
{ {
tree e = RETURN_STMT_EXPR (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_identifier (pp, "return");
pp_c_whitespace (pp); pp_c_whitespace (pp);
if (e) if (e)
...@@ -2063,14 +2000,13 @@ pp_c_statement (c_pretty_printer *pp, tree stmt) ...@@ -2063,14 +2000,13 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
break; break;
case DECL_STMT: case DECL_STMT:
if (pp_needs_newline (pp))
pp_newline_and_indent (pp, 0);
pp_declaration (pp, DECL_STMT_DECL (stmt)); pp_declaration (pp, DECL_STMT_DECL (stmt));
pp_needs_newline (pp) = true; pp_needs_newline (pp) = true;
break; break;
default: default:
pp_unsupported_tree (pp, stmt); dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
break;
} }
} }
......
...@@ -158,19 +158,6 @@ add_decl_stmt (tree decl) ...@@ -158,19 +158,6 @@ add_decl_stmt (tree decl)
add_stmt (decl_stmt); 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 /* Build a generic statement based on the given type of node and
arguments. Similar to `build_nt', except that we set arguments. Similar to `build_nt', except that we set
EXPR_LOCUS to be the current source location. */ EXPR_LOCUS to be the current source location. */
......
...@@ -6483,8 +6483,7 @@ static int if_stack_space = 0; ...@@ -6483,8 +6483,7 @@ static int if_stack_space = 0;
/* Stack pointer. */ /* Stack pointer. */
static int if_stack_pointer = 0; static int if_stack_pointer = 0;
/* Begin an if-statement. Returns a newly created IF_STMT if /* Begin an if-statement. */
appropriate. */
void void
c_begin_if_stmt (void) c_begin_if_stmt (void)
...@@ -6504,7 +6503,7 @@ 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)); 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. */ /* Record this if statement. */
elt = &if_stack[if_stack_pointer++]; elt = &if_stack[if_stack_pointer++];
...@@ -6527,7 +6526,7 @@ c_finish_if_cond (tree cond, int compstmt_count, int stmt_count) ...@@ -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]; if_elt *elt = &if_stack[if_stack_pointer - 1];
elt->compstmt_count = compstmt_count; elt->compstmt_count = compstmt_count;
elt->stmt_count = stmt_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. */ /* Called after the then-clause for an if-statement is processed. */
...@@ -6536,7 +6535,7 @@ void ...@@ -6536,7 +6535,7 @@ void
c_finish_then (tree then_stmt) c_finish_then (tree then_stmt)
{ {
if_elt *elt = &if_stack[if_stack_pointer - 1]; 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; elt->empty_locus = input_location;
} }
...@@ -6570,7 +6569,7 @@ void ...@@ -6570,7 +6569,7 @@ void
c_finish_else (tree else_stmt) c_finish_else (tree else_stmt)
{ {
if_elt *elt = &if_stack[if_stack_pointer - 1]; 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; elt->empty_locus = input_location;
} }
...@@ -6582,6 +6581,9 @@ c_finish_if_stmt (int stmt_count) ...@@ -6582,6 +6581,9 @@ c_finish_if_stmt (int stmt_count)
{ {
if_elt *elt = &if_stack[--if_stack_pointer]; 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) if (elt->needs_warning)
warning ("%Hsuggest explicit braces to avoid ambiguous `else'", warning ("%Hsuggest explicit braces to avoid ambiguous `else'",
EXPR_LOCUS (elt->if_stmt)); EXPR_LOCUS (elt->if_stmt));
...@@ -6781,6 +6783,19 @@ c_end_compound_stmt (tree stmt, bool do_scope) ...@@ -6781,6 +6783,19 @@ c_end_compound_stmt (tree stmt, bool do_scope)
return stmt; 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. /* Build a binary-operation expression without default conversions.
CODE is the kind of expression to build. CODE is the kind of expression to build.
......
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> 2004-06-20 Zack Weinberg <zack@codesourcery.com>
* cp-lang.c (has_c_linkage): Implement. * cp-lang.c (has_c_linkage): Implement.
......
...@@ -79,6 +79,26 @@ genericize_eh_spec_block (tree *stmt_p) ...@@ -79,6 +79,26 @@ genericize_eh_spec_block (tree *stmt_p)
*stmt_p = gimple_build_eh_filter (body, allowed, failure); *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. */ /* Gimplify initialization from an AGGR_INIT_EXPR. */
static void static void
...@@ -224,6 +244,11 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p) ...@@ -224,6 +244,11 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
ret = GS_ALL_DONE; ret = GS_ALL_DONE;
break; break;
case IF_STMT:
gimplify_if_stmt (expr_p);
ret = GS_OK;
break;
default: default:
ret = c_gimplify_expr (expr_p, pre_p, post_p); ret = c_gimplify_expr (expr_p, pre_p, post_p);
break; break;
...@@ -236,3 +261,33 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p) ...@@ -236,3 +261,33 @@ cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
return ret; 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);
}
...@@ -243,8 +243,11 @@ DEFTREECODE (NON_DEPENDENT_EXPR, "non_dependent_expr", 'e', 1) ...@@ -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 /* CTOR_INITIALIZER is a placeholder in template code for a call to
setup_vtbl_pointer (and appears in all functions, not just ctors). */ setup_vtbl_pointer (and appears in all functions, not just ctors). */
DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1) DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 1)
DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2) DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_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 /* 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 CATCH_ALL_TYPE, then the handler catches all types. The declaration of
the catch variable is in HANDLER_PARMS, and the body block in the catch variable is in HANDLER_PARMS, and the body block in
...@@ -255,6 +258,17 @@ DEFTREECODE (HANDLER, "handler", 'e', 2) ...@@ -255,6 +258,17 @@ DEFTREECODE (HANDLER, "handler", 'e', 2)
throw, and must call terminate if it does. */ throw, and must call terminate if it does. */
DEFTREECODE (MUST_NOT_THROW_EXPR, "must_not_throw_expr", 'e', 1) 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) DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0)
/* Template instantiation level node. /* Template instantiation level node.
......
...@@ -892,7 +892,8 @@ enum cplus_tree_code { ...@@ -892,7 +892,8 @@ enum cplus_tree_code {
#define cp_stmt_codes \ #define cp_stmt_codes \
CTOR_INITIALIZER, TRY_BLOCK, HANDLER, \ 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 }; enum languages { lang_c, lang_cplusplus, lang_java };
...@@ -2939,6 +2940,19 @@ struct lang_decl GTY(()) ...@@ -2939,6 +2940,19 @@ struct lang_decl GTY(())
#define HANDLER_BODY(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 1) #define HANDLER_BODY(NODE) TREE_OPERAND (HANDLER_CHECK (NODE), 1)
#define HANDLER_TYPE(NODE) TREE_TYPE (HANDLER_CHECK (NODE)) #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. */ /* The parameters for a call-declarator. */
#define CALL_DECLARATOR_PARMS(NODE) \ #define CALL_DECLARATOR_PARMS(NODE) \
(TREE_PURPOSE (TREE_OPERAND (NODE, 1))) (TREE_PURPOSE (TREE_OPERAND (NODE, 1)))
...@@ -4304,6 +4318,7 @@ extern bool cp_dump_tree (void *, tree); ...@@ -4304,6 +4318,7 @@ extern bool cp_dump_tree (void *, tree);
/* in cp-simplify.c */ /* in cp-simplify.c */
extern int cp_gimplify_expr (tree *, tree *, tree *); extern int cp_gimplify_expr (tree *, tree *, tree *);
extern void cp_genericize (tree);
/* -- end of C++ */ /* -- end of C++ */
......
...@@ -1517,6 +1517,43 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t) ...@@ -1517,6 +1517,43 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t)
pp_needs_newline (pp) = true; pp_needs_newline (pp) = true;
break; 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: default:
pp_c_statement (pp_c_base (pp), t); pp_c_statement (pp_c_base (pp), t);
break; break;
......
...@@ -10812,7 +10812,7 @@ finish_function (int flags) ...@@ -10812,7 +10812,7 @@ finish_function (int flags)
/* Genericize before inlining. */ /* Genericize before inlining. */
if (!processing_template_decl) if (!processing_template_decl)
{ {
c_genericize (fndecl); cp_genericize (fndecl);
/* Handle attribute((warn_unused_result)). Relies on gimple input. */ /* Handle attribute((warn_unused_result)). Relies on gimple input. */
c_warn_unused_result (&DECL_SAVED_TREE (fndecl)); c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
......
...@@ -411,7 +411,23 @@ cp_dump_tree (void* dump_info, tree t) ...@@ -411,7 +411,23 @@ cp_dump_tree (void* dump_info, tree t)
dump_child ("nmsp", USING_STMT_NAMESPACE (t)); dump_child ("nmsp", USING_STMT_NAMESPACE (t));
dump_next_stmt (di, t); dump_next_stmt (di, t);
break; 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: default:
break; break;
} }
......
...@@ -346,6 +346,19 @@ do_pushlevel (scope_kind sk) ...@@ -346,6 +346,19 @@ do_pushlevel (scope_kind sk)
return ret; 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 /* Begin a conditional that might contain a declaration. When generating
normal code, we want the declaration to appear before the statement normal code, we want the declaration to appear before the statement
containing the conditional. When generating template code, we want the containing the conditional. When generating template code, we want the
......
...@@ -209,8 +209,7 @@ struct tree_common GTY(()) ...@@ -209,8 +209,7 @@ struct tree_common GTY(())
TREE_SYMBOL_REFERENCED in TREE_SYMBOL_REFERENCED in
IDENTIFIER_NODE IDENTIFIER_NODE
CLEANUP_EH_ONLY in CLEANUP_EH_ONLY in
TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT, TARGET_EXPR, WITH_CLEANUP_EXPR
TREE_LIST elements of a block's cleanup list.
ASM_INPUT_P in ASM_INPUT_P in
ASM_EXPR ASM_EXPR
EH_FILTER_MUST_NOT_THROW in EH_FILTER_EXPR EH_FILTER_MUST_NOT_THROW in EH_FILTER_EXPR
...@@ -690,9 +689,9 @@ extern void tree_operand_check_failed (int, enum tree_code, ...@@ -690,9 +689,9 @@ extern void tree_operand_check_failed (int, enum tree_code,
should be cleaned up some day. */ should be cleaned up some day. */
#define TREE_STATIC(NODE) ((NODE)->common.static_flag) #define TREE_STATIC(NODE) ((NODE)->common.static_flag)
/* In a TARGET_EXPR, WITH_CLEANUP_EXPR, CLEANUP_STMT, or element of a /* In a TARGET_EXPR, WITH_CLEANUP_EXPR, means that the pertinent cleanup
block's cleanup list, means that the pertinent cleanup should only be should only be executed if an exception is thrown, not on normal exit
executed if an exception is thrown, not on normal exit of its scope. */ of its scope. */
#define CLEANUP_EH_ONLY(NODE) ((NODE)->common.static_flag) #define CLEANUP_EH_ONLY(NODE) ((NODE)->common.static_flag)
/* In an expr node (usually a conversion) this means the node was made /* In an expr node (usually a conversion) this means the node was made
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment