diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-16 01:21:38 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-16 01:21:38 +0000 |
commit | 2363ef003652e46b5d1eb1b1bc7a93327168977a (patch) | |
tree | fd045b9b0d56d6e00876348ae58483539fd0ec02 /gcc/c-semantics.c | |
parent | 53a9841beb1d5b151218420952cd30f98913a93d (diff) | |
download | gcc-2363ef003652e46b5d1eb1b1bc7a93327168977a.tar.gz |
* c-common.c (lang_gimplify_stmt): Remove next_p argument.
(if_elt, if_stack, if_stack_space, c_expand_start_cond, c_finish_then,
c_expand_end_cond, c_expand_start_else, c_finish_else, c_begin_if_stmt,
c_begin_while_stmt, c_finish_while_stmt_cond): Move to c-typeck.c.
(finish_fname_decls, fname_decl): Use statement_lists.
(c_expand_expr_stmt): Don't set last_expr_type.
(c_type_hash): Fix indentation.
(c_safe_from_p): Don't follow TREE_CHAIN.
(c_tree_chain_matters_p): Remove.
* c-common.def (SCOPE_STMT): Remove.
(CLEANUP_STMT): Redefine to contain its own body.
* c-common.h (struct stmt_tree_s): Remove x_last_stmt,
x_last_expr_type, x_last_expr_filename, x_scope_stmt_stack.
Add x_cur_stmt_list.
(last_tree, last_expr_type, last_expr_filename, RECHAIN_STMTS): Remove.
(cur_stmt_list): New.
(STATEMENT_LIST_STMT_EXPR): New.
(SCOPE_BEGIN_P, SCOPE_END_P, SCOPE_STMT_BLOCK, SCOPE_NULLIFIED_P,
SCOPE_NO_CLEANUPS_P, SCOPE_PARTIAL_P, NEW_FOR_SCOPE_P): Remove.
(CLEANUP_BODY): New.
(CLEANUP_DECL): Move to operand 2.
(c_common_stmt_codes): Remove SCOPE_STMT.
(COMPOUND_STMT_NO_SCOPE, COMPOUND_STMT_BODY_BLOCK): Remove.
* c-decl.c (c_scope_stmt_stack, current_scope_stmt_stack): Remove.
(c_push_function_context, c_pop_function_context): Don't save it.
(finish_decl): Set TREE_USED on the decl for a cleanup.
Use push_cleanup.
(store_parm_decls): Use statement lists.
(finish_function): Remove compstmt rule workaround. Use statement
lists. Call finish_fname_decls after finalizing the body.
(c_begin_compound_stmt): Move to c-typeck.c.
* c-dump.c (c_dump_tree): Remove SCOPE_STMT.
* c-gimplify.c (gimplify_cleanup_stmt, gimplify_cleanup_stmts): New.
(c_genericize): Invoke them.
(c_gimplify_stmt): Don't look through TREE_CHAIN. Kill SCOPE_STMT.
(c_build_bind_expr): Export.
(gimplify_block, gimplify_cleanup): Remove.
(gimplify_condition): Use gimplify_stmt.
(gimplify_for_stmt): Remove FOR_INIT_STMT chaining hack.
(gimplify_if_stmt): Remove recursion hack.
(c_gimplify_expr): Remove STMT_EXPR handling.
(stmt_expr_last_stmt, gimplify_stmt_expr): Remove.
(is_last_stmt_of_scope): Remove.
* c-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P): Remove.
* c-mudflap.c (mflang_flush_calls): Use c_begin_compound_stmt,
c_end_compound_stmt.
* c-objc-common.c (build_cdtor): Likewise.
* c-parse.in (primary): Use c_finish_stmt_expr.
(push_scope, pop_scope): Remove.
(c99_block_start, compstmt_start): Use c_begin_compound_stmt.
(c99_block_end, compstmt): Use c_end_compound_stmt.
(c99_block_lineno_labeled_stmt): Likewise.
(compstmt_primary_start): Use c_begin_stmt_expr.
(simple_if, select_or_iter_stmt): Update calls to stmt builders.
(do_stmt_start): Fill in body directly.
(lineno_stmt): Avoid setting lineno on constants.
* c-pretty-print.c (pp_c_statement): Handle STATEMENT_LIST.
Remove SCOPE_STMT.
* c-semantics.c (begin_stmt_tree): Remove.
(push_stmt_list, re_push_stmt_list, pop_stmt_list): New.
(add_stmt): Use statement lists.
(add_scope_stmt, finish_stmt_tree): Remove.
(push_cleanup): New.
* c-tree.h: Move some decls from c-common.h.
* c-typeck.c (c_tree_expr_nonnegative_p): Simplify for statement lists.
(do_case, c_finish_case): Likewise.
(c_finish_then): Take body for then as argument.
(c_finish_else): Similarly.
(c_begin_for_stmt, c_finish_for_stmt_init, c_finish_for_stmt_cond,
c_finish_for_stmt_incr, c_finish_for_stmt): New.
(c_begin_stmt_expr, c_finish_stmt_expr): New.
(c_begin_compound_stmt): Do scope management.
(c_end_compound_stmt): New.
* fold-const.c (tree_expr_nonnegative_p): Fix BIND_EXPR.
* gimplify.c (voidify_wrapper_expr): Accept temporary argument.
Look through exception handling constructs.
(gimplify_bind_expr): Accept temporary argument.
(gimplify_target_expr): Special case BIND_EXPR bodies.
(gimplify_expr): Handle fallback == fb_none like a statement.
* langhooks-def.h (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P): Kill.
* langhooks.c (lhd_tree_inlining_tree_chain_matters_p): Remove.
* langhooks.h (tree_chain_matters_p): Remove.
* stub-objc.c (objc_clear_super_receiver): New.
* tree-gimple.h (voidify_wrapper_expr): Update decl.
(append_to_statement_list, append_to_statement_list_force): Move
to tree-iterator.h.
* tree-inline.c (expand_call_inline): Update call.
(clone_body): Use statement lists.
(walk_tree): Don't check tree_chain_matters_p.
(copy_tree_r): Likewise.
* tree-iterator.c (alloc_stmt_list): Clear lang bits.
(tsi_link_before, tsi_link_after): Set TREE_SIDE_EFFECTS properly.
* tree-iterator.h (append_to_statement_list,
append_to_statement_list_force): Moved from tree-gimple.h.
* tree-pretty-print.c (dump_generic_node): Clean up TARGET_EXPR dump.
* objc/objc-act.c (build_module_descriptor): Use c_begin_compound_stmt.
(objc_enter_block): Likewise.
(objc_exit_block): Use c_end_compound_stmt.
(objc_build_try_enter_fragment): Add #error and comment for
rewriting for OBJCPLUS.
(objc_build_extract_fragment, objc_build_try_epilogue,
objc_build_catch_stmt, objc_build_finally_prologue,
objc_build_finally_epilogue): Update for C statement builders.
* objc/objc-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P):
Remove.
cp/
* call.c (initialize_reference): Don't build CLEANUP_STMT here.
* cp-gimplify.c (cp_gimplify_stmt): Remove next_p argument.
(genericize_try_block): Use gimplify_stmt.
(genericize_catch_block, genericize_eh_spec_block): Likewise.
(cp_gimplify_init_expr): Remove STMT_EXPR special case.
(gimplify_must_not_throw_expr): Update voidify_wrapper_expr call.
* cp-lang.c (LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P): Remove.
(cp_tree_chain_matters_p): Remove.
* cp-tree.h (COMPOUND_STMT_TRY_BLOCK): New.
(COMPOUND_STMT_BODY_BLOCK): New.
(STATEMENT_LIST_NO_SCOPE, STATEMENT_LIST_TRY_BLOCK): New.
(EXPR_STMT_STMT_EXPR_RESULT): New.
(building_stmt_tree): Check cur_stmt_list.
(tf_stmt_expr_cmpd, tf_stmt_expr_body): Remove.
(BCS_NO_SCOPE, BCS_TRY_BLOCK, BCS_FN_BODY): New.
* decl.c (poplevel): Use pop_stmt_list for minding cleanups.
(cp_finish_decl): Use push_cleanup.
(start_function, finish_function): Use statement lists.
(finish_stmt): Do nothing.
* except.c (begin_eh_spec_block): Use statement lists.
(check_handlers_1, check_handlers): Likewise.
* init.c (construct_virtual_base): Don't add extra compound stmts.
(build_vec_init): Likewise.
* name-lookup.c (maybe_push_cleanup_level): Use statement lists.
* name-lookup.h (struct cp_binding_level): Add statement_list.
* parser.c (cp_parser_statement): Take the STMT_EXPR node, not a bool.
(cp_parser_labeled_statement, cp_parser_expression_statement,
cp_parser_statement_seq_opt): Likewise.
(cp_parser_compound_statement): Likewise. Take bool for try block.
(cp_parser_selection_statement): Tidy if processing.
(cp_parser_already_scoped_statement): Rewrite to do what it says.
* pt.c (tsubst_copy): Move STMT_EXPR to tsubst_expr.
(tsubst_expr): Rewrite STMT_EXPR processing. Handle STATEMENT_LIST.
Mind COMPOUND_STMT_TRY_BLOCK, EXPR_STMT_STMT_EXPR_RESULT.
* semantics.c (do_poplevel, do_pushlevel): Use statement lists.
(finish_cond): New, rewritten from FINISH_COND.
(simplify_loop_decl_cond): New.
(finish_expr_stmt): Avoid nested EXPR_STMTs.
(begin_if_stmt, finish_if_stmt_cond, finish_then_clause,
begin_else_clause, finish_else_clause, finish_if_stmt,
begin_while_stmt, finish_while_stmt_cond, finish_while_stmt,
begin_do_stmt, finish_do_body, begin_for_stmt, finish_for_init_stmt,
finish_for_cond, finish_for_stmt, begin_switch_stmt,
finish_switch_cond, finish_switch_stmt, begin_try_block,
finish_try_block, finish_cleanup_try_block, finish_function_try_block,
finish_handler_sequence, finish_function_handler_sequence,
begin_handler, finish_handler_parms, finish_handler,
begin_stmt_expr, finish_stmt_expr_expr, finish_stmt_expr): Rewrite
using statement lists.
(begin_compound_stmt): Replace has_no_scope argument with flags.
Update all callers. Use statement lists.
(finish_compound_stmt): Likewise.
(finish_decl_cleanup, finish_eh_cleanup): Use push_cleanup.
(current_scope_stmt_stack): Remove.
(simplify_aggr_init_expr): Don't muck with TREE_CHAIN.
* typeck2.c (split_nonconstant_init_1, split_nonconstant_init):
Rewrite with statement lists.
testsuite/
* g++.dg/ext/stmtexpr1.C: XFAIL.
* gcc.dg/20030612-1.c: XFAIL.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83221 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-semantics.c')
-rw-r--r-- | gcc/c-semantics.c | 159 |
1 files changed, 92 insertions, 67 deletions
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c index ce36fb54304..4a481916700 100644 --- a/gcc/c-semantics.c +++ b/gcc/c-semantics.c @@ -43,20 +43,84 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "timevar.h" #include "predict.h" #include "tree-inline.h" +#include "tree-gimple.h" #include "langhooks.h" /* Create an empty statement tree rooted at T. */ -void -begin_stmt_tree (tree *t) +tree +push_stmt_list (void) { - /* We create a trivial EXPR_STMT so that last_tree is never NULL in - what follows. We remove the extraneous statement in - finish_stmt_tree. */ - *t = build_nt (EXPR_STMT, void_zero_node); - last_tree = *t; - last_expr_type = NULL_TREE; - last_expr_filename = input_filename; + tree t; + t = alloc_stmt_list (); + TREE_CHAIN (t) = cur_stmt_list; + cur_stmt_list = t; + return t; +} + +/* Similarly, except that T may have already been pushed/popped, and + thus may already contain statement(s). Arrage for new statements + to be appended. */ + +tree +re_push_stmt_list (tree t) +{ + if (t) + { + if (TREE_CODE (t) != STATEMENT_LIST) + { + tree u = alloc_stmt_list (); + append_to_statement_list_force (t, &u); + t = u; + } + } + else + t = alloc_stmt_list (); + TREE_CHAIN (t) = cur_stmt_list; + cur_stmt_list = t; + return t; +} + +/* Finish the statement tree rooted at T. */ + +tree +pop_stmt_list (tree t) +{ + tree u = cur_stmt_list, chain; + + /* Pop statement lists until we reach the target level. The extra + nestings will be due to outstanding cleanups. */ + while (1) + { + chain = TREE_CHAIN (u); + TREE_CHAIN (u) = NULL_TREE; + if (t == u) + break; + u = chain; + } + cur_stmt_list = chain; + + /* If the statement list is completely empty, just return it. This is + just as good small as build_empty_stmt, with the advantage that + statement lists are merged when they appended to one another. So + using the STATEMENT_LIST avoids pathological buildup of EMPTY_STMT_P + statements. */ + if (TREE_SIDE_EFFECTS (t)) + { + tree_stmt_iterator i = tsi_start (t); + + /* If the statement list contained exactly one statement, then + extract it immediately. */ + if (tsi_one_before_end_p (i)) + { + u = tsi_stmt (i); + tsi_delink (&i); + free_stmt_list (t); + t = u; + } + } + + return t; } /* T is a statement. Add it to the statement-tree. */ @@ -64,16 +128,19 @@ begin_stmt_tree (tree *t) tree add_stmt (tree t) { - if (!EXPR_LOCUS (t)) - annotate_with_locus (t, input_location); + if (EXPR_P (t) || STATEMENT_CODE_P (TREE_CODE (t))) + { + if (!EXPR_LOCUS (t)) + annotate_with_locus (t, input_location); - /* Add T to the statement-tree. */ - TREE_CHAIN (last_tree) = t; - last_tree = t; + /* When we expand a statement-tree, we must know whether or not the + statements are full-expressions. We record that fact here. */ + STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); + } - /* When we expand a statement-tree, we must know whether or not the - statements are full-expressions. We record that fact here. */ - STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p (); + /* Add T to the statement-tree. Non-side-effect statements need to be + recorded during statement expressions. */ + append_to_statement_list_force (t, &cur_stmt_list); return t; } @@ -91,59 +158,17 @@ add_decl_stmt (tree decl) add_stmt (decl_stmt); } -/* Add a scope-statement to the statement-tree. BEGIN_P indicates - whether this statements opens or closes a scope. PARTIAL_P is true - for a partial scope, i.e, the scope that begins after a label when - an object that needs a cleanup is created. If BEGIN_P is nonzero, - returns a new TREE_LIST representing the top of the SCOPE_STMT - stack. The TREE_PURPOSE is the new SCOPE_STMT. If BEGIN_P is - zero, returns a TREE_LIST whose TREE_VALUE is the new SCOPE_STMT, - and whose TREE_PURPOSE is the matching SCOPE_STMT with - SCOPE_BEGIN_P set. */ - -tree -add_scope_stmt (int begin_p, int partial_p) -{ - tree *stack_ptr = current_scope_stmt_stack (); - tree ss; - tree top = *stack_ptr; - - /* Build the statement. */ - ss = build_stmt (SCOPE_STMT, NULL_TREE); - SCOPE_BEGIN_P (ss) = begin_p; - SCOPE_PARTIAL_P (ss) = partial_p; - - /* Keep the scope stack up to date. */ - if (begin_p) - { - top = tree_cons (ss, NULL_TREE, top); - *stack_ptr = top; - } - else - { - if (partial_p != SCOPE_PARTIAL_P (TREE_PURPOSE (top))) - abort (); - TREE_VALUE (top) = ss; - *stack_ptr = TREE_CHAIN (top); - } - - /* Add the new statement to the statement-tree. */ - add_stmt (ss); - - return top; -} - -/* Finish the statement tree rooted at T. */ +/* 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 -finish_stmt_tree (tree *t) +push_cleanup (tree decl, tree cleanup, bool eh_only) { - tree stmt; - - /* Remove the fake extra statement added in begin_stmt_tree. */ - stmt = TREE_CHAIN (*t); - *t = stmt; - last_tree = NULL_TREE; + 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 |