mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 13:01:02 +08:00
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
This commit is contained in:
parent
500e12641f
commit
5a5086621e
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
15
gcc/c-dump.c
15
gcc/c-dump.c
@ -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));
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
||||
/* Build a binary-operation expression without default conversions.
|
||||
CODE is the kind of expression to build.
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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++ */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user