summaryrefslogtreecommitdiff
path: root/gcc/gimplify.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-16 01:21:38 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-16 01:21:38 +0000
commit2363ef003652e46b5d1eb1b1bc7a93327168977a (patch)
treefd045b9b0d56d6e00876348ae58483539fd0ec02 /gcc/gimplify.c
parent53a9841beb1d5b151218420952cd30f98913a93d (diff)
downloadgcc-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/gimplify.c')
-rw-r--r--gcc/gimplify.c69
1 files changed, 40 insertions, 29 deletions
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index a4b9c702e28..b0a2aa67c12 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -754,23 +754,23 @@ gimple_build_eh_filter (tree body, tree allowed, tree failure)
WRAPPER was already void. */
tree
-voidify_wrapper_expr (tree wrapper)
+voidify_wrapper_expr (tree wrapper, tree temp)
{
if (!VOID_TYPE_P (TREE_TYPE (wrapper)))
{
- tree *p;
- tree temp;
+ tree *p, sub = wrapper;
+ restart:
/* Set p to point to the body of the wrapper. */
- switch (TREE_CODE (wrapper))
+ switch (TREE_CODE (sub))
{
case BIND_EXPR:
/* For a BIND_EXPR, the body is operand 1. */
- p = &BIND_EXPR_BODY (wrapper);
+ p = &BIND_EXPR_BODY (sub);
break;
default:
- p = &TREE_OPERAND (wrapper, 0);
+ p = &TREE_OPERAND (sub, 0);
break;
}
@@ -789,15 +789,22 @@ voidify_wrapper_expr (tree wrapper)
}
}
- if (p && TREE_CODE (*p) == INIT_EXPR)
+ if (p == NULL || IS_EMPTY_STMT (*p))
+ ;
+ /* Look through exception handling. */
+ else if (TREE_CODE (*p) == TRY_FINALLY_EXPR
+ || TREE_CODE (*p) == TRY_CATCH_EXPR)
{
- /* The C++ frontend already did this for us. */;
- temp = TREE_OPERAND (*p, 0);
+ sub = *p;
+ goto restart;
}
- else if (p && TREE_CODE (*p) == INDIRECT_REF)
+ /* The C++ frontend already did this for us. */
+ else if (TREE_CODE (*p) == INIT_EXPR)
+ temp = TREE_OPERAND (*p, 0);
+ /* If we're returning a dereference, move the dereference
+ outside the wrapper. */
+ else if (TREE_CODE (*p) == INDIRECT_REF)
{
- /* If we're returning a dereference, move the dereference outside
- the wrapper. */
tree ptr = TREE_OPERAND (*p, 0);
temp = create_tmp_var (TREE_TYPE (ptr), "retval");
*p = build (MODIFY_EXPR, TREE_TYPE (ptr), temp, ptr);
@@ -808,12 +815,10 @@ voidify_wrapper_expr (tree wrapper)
}
else
{
- temp = create_tmp_var (TREE_TYPE (wrapper), "retval");
- if (p && !IS_EMPTY_STMT (*p))
- {
- *p = build (MODIFY_EXPR, TREE_TYPE (temp), temp, *p);
- TREE_SIDE_EFFECTS (wrapper) = 1;
- }
+ if (!temp)
+ temp = create_tmp_var (TREE_TYPE (wrapper), "retval");
+ *p = build (MODIFY_EXPR, TREE_TYPE (temp), temp, *p);
+ TREE_SIDE_EFFECTS (wrapper) = 1;
}
TREE_TYPE (wrapper) = void_type_node;
@@ -845,13 +850,14 @@ build_stack_save_restore (tree *save, tree *restore)
/* Gimplify a BIND_EXPR. Just voidify and recurse. */
static enum gimplify_status
-gimplify_bind_expr (tree *expr_p, tree *pre_p)
+gimplify_bind_expr (tree *expr_p, tree temp, tree *pre_p)
{
tree bind_expr = *expr_p;
- tree temp = voidify_wrapper_expr (bind_expr);
bool old_save_stack = gimplify_ctxp->save_stack;
tree t;
+ temp = voidify_wrapper_expr (bind_expr, temp);
+
/* Mark variables seen in this bind expr. */
for (t = BIND_EXPR_VARS (bind_expr); t ; t = TREE_CHAIN (t))
t->decl.seen_in_bind_expr = 1;
@@ -2872,7 +2878,7 @@ gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
tree_stmt_iterator iter;
tree body;
- tree temp = voidify_wrapper_expr (*expr_p);
+ tree temp = voidify_wrapper_expr (*expr_p, NULL);
/* We only care about the number of conditions between the innermost
CLEANUP_POINT_EXPR and the cleanup. So save and reset the count. */
@@ -3006,12 +3012,17 @@ gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
temps list. */
gimple_add_tmp_var (temp);
- /* Build up the initialization and add it to pre_p. */
- init = build (MODIFY_EXPR, void_type_node, temp, init);
- ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
- if (ret == GS_ERROR)
- return GS_ERROR;
-
+ /* Build up the initialization and add it to pre_p. Special handling
+ for BIND_EXPR can result in fewer temporaries created. */
+ if (TREE_CODE (init) == BIND_EXPR)
+ gimplify_bind_expr (&init, temp, pre_p);
+ if (init != temp)
+ {
+ init = build (MODIFY_EXPR, void_type_node, temp, init);
+ ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
+ if (ret == GS_ERROR)
+ return GS_ERROR;
+ }
append_to_statement_list (init, pre_p);
/* If needed, push the cleanup for the temp. */
@@ -3286,7 +3297,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
break;
case BIND_EXPR:
- ret = gimplify_bind_expr (expr_p, pre_p);
+ ret = gimplify_bind_expr (expr_p, NULL, pre_p);
break;
case LOOP_EXPR:
@@ -3530,7 +3541,7 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
/* If we are gimplifying at the statement level, we're done. Tack
everything together and replace the original statement with the
gimplified form. */
- if (is_statement)
+ if (fallback == fb_none || is_statement)
{
if (internal_pre || internal_post)
{