diff options
author | Richard Henderson <rth@redhat.com> | 2004-06-15 18:21:38 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-06-15 18:21:38 -0700 |
commit | 325c36911589375105e5437c513bf880aeffdc75 (patch) | |
tree | fd045b9b0d56d6e00876348ae58483539fd0ec02 /gcc/c-common.c | |
parent | aaab7bb6d7660df0773a444bd6a4a20f586f1a98 (diff) | |
download | gcc-325c36911589375105e5437c513bf880aeffdc75.zip gcc-325c36911589375105e5437c513bf880aeffdc75.tar.gz gcc-325c36911589375105e5437c513bf880aeffdc75.tar.bz2 |
c-common.c (lang_gimplify_stmt): Remove next_p argument.
* 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.
From-SVN: r83221
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 276 |
1 files changed, 50 insertions, 226 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 01a8783..2b68c0a 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -690,7 +690,7 @@ int (*lang_statement_code_p) (enum tree_code); /* If non-NULL, the address of a language-specific function that does any language-specific gimplification for _STMT nodes and returns 1 iff handled. */ -int (*lang_gimplify_stmt) (tree *, tree *); +int (*lang_gimplify_stmt) (tree *); /* If non-NULL, the address of a language-specific function that takes any action required right before expand_function_end is called. */ @@ -723,27 +723,6 @@ const struct fname_var_t fname_vars[] = static int constant_fits_type_p (tree, tree); -/* Keep a stack of if statements. We record the number of compound - statements seen up to the if keyword, as well as the line number - and file of the if. If a potentially ambiguous else is seen, that - fact is recorded; the warning is issued when we can be sure that - the enclosing if statement does not have an else branch. */ -typedef struct -{ - int compstmt_count; - location_t locus; - int needs_warning; - tree if_stmt; -} if_elt; - -static if_elt *if_stack; - -/* Amount of space in the if statement stack. */ -static int if_stack_space = 0; - -/* Stack pointer. */ -static int if_stack_pointer = 0; - static tree handle_packed_attribute (tree *, tree, tree, int, bool *); static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *); static tree handle_common_attribute (tree *, tree, tree, int, bool *); @@ -876,131 +855,6 @@ const struct attribute_spec c_common_format_attribute_table[] = { NULL, 0, 0, false, false, false, NULL } }; -/* Record the start of an if-then, and record the start of it - for ambiguous else detection. - - COND is the condition for the if-then statement. - - IF_STMT is the statement node that has already been created for - this if-then statement. It is created before parsing the - condition to keep line number information accurate. */ - -void -c_expand_start_cond (tree cond, int compstmt_count, tree if_stmt) -{ - /* Make sure there is enough space on the stack. */ - if (if_stack_space == 0) - { - if_stack_space = 10; - if_stack = xmalloc (10 * sizeof (if_elt)); - } - else if (if_stack_space == if_stack_pointer) - { - if_stack_space += 10; - if_stack = xrealloc (if_stack, if_stack_space * sizeof (if_elt)); - } - - IF_COND (if_stmt) = cond; - add_stmt (if_stmt); - - /* Record this if statement. */ - if_stack[if_stack_pointer].compstmt_count = compstmt_count; - if_stack[if_stack_pointer].locus = input_location; - if_stack[if_stack_pointer].needs_warning = 0; - if_stack[if_stack_pointer].if_stmt = if_stmt; - if_stack_pointer++; -} - -/* Called after the then-clause for an if-statement is processed. */ - -void -c_finish_then (void) -{ - tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt; - RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt)); -} - -/* Record the end of an if-then. Optionally warn if a nested - if statement had an ambiguous else clause. */ - -void -c_expand_end_cond (void) -{ - if_stack_pointer--; - if (if_stack[if_stack_pointer].needs_warning) - warning ("%Hsuggest explicit braces to avoid ambiguous `else'", - &if_stack[if_stack_pointer].locus); - last_expr_type = NULL_TREE; -} - -/* Called between the then-clause and the else-clause - of an if-then-else. */ - -void -c_expand_start_else (void) -{ - /* An ambiguous else warning must be generated for the enclosing if - statement, unless we see an else branch for that one, too. */ - if (warn_parentheses - && if_stack_pointer > 1 - && (if_stack[if_stack_pointer - 1].compstmt_count - == if_stack[if_stack_pointer - 2].compstmt_count)) - if_stack[if_stack_pointer - 2].needs_warning = 1; - - /* Even if a nested if statement had an else branch, it can't be - ambiguous if this one also has an else. So don't warn in that - case. Also don't warn for any if statements nested in this else. */ - if_stack[if_stack_pointer - 1].needs_warning = 0; - if_stack[if_stack_pointer - 1].compstmt_count--; -} - -/* Called after the else-clause for an if-statement is processed. */ - -void -c_finish_else (void) -{ - tree if_stmt = if_stack[if_stack_pointer - 1].if_stmt; - RECHAIN_STMTS (if_stmt, ELSE_CLAUSE (if_stmt)); -} - -/* Begin an if-statement. Returns a newly created IF_STMT if - appropriate. - - Unlike the C++ front-end, we do not call add_stmt here; it is - probably safe to do so, but I am not very familiar with this - code so I am being extra careful not to change its behavior - beyond what is strictly necessary for correctness. */ - -tree -c_begin_if_stmt (void) -{ - tree r; - r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE); - return r; -} - -/* Begin a while statement. Returns a newly created WHILE_STMT if - appropriate. - - Unlike the C++ front-end, we do not call add_stmt here; it is - probably safe to do so, but I am not very familiar with this - code so I am being extra careful not to change its behavior - beyond what is strictly necessary for correctness. */ - -tree -c_begin_while_stmt (void) -{ - tree r; - r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE); - return r; -} - -void -c_finish_while_stmt_cond (tree cond, tree while_stmt) -{ - WHILE_COND (while_stmt) = cond; -} - /* Push current bindings for the function name VAR_DECLS. */ void @@ -1026,43 +880,32 @@ start_fname_decls (void) saved_function_name_decls); } -/* Finish up the current bindings, adding them into the - current function's statement tree. This is done by wrapping the - function's body in a COMPOUND_STMT containing these decls too. This - must be done _before_ finish_stmt_tree is called. If there is no - current function, we must be at file scope and no statements are - involved. Pop the previous bindings. */ +/* Finish up the current bindings, adding them into the current function's + statement tree. This must be done _before_ finish_stmt_tree is called. + If there is no current function, we must be at file scope and no statements + are involved. Pop the previous bindings. */ void finish_fname_decls (void) { unsigned ix; - tree body = NULL_TREE; + tree stmts = NULL_TREE; tree stack = saved_function_name_decls; for (; stack && TREE_VALUE (stack); stack = TREE_CHAIN (stack)) - body = chainon (TREE_VALUE (stack), body); + append_to_statement_list (TREE_VALUE (stack), &stmts); - if (body) + if (stmts) { - /* They were called into existence, so add to statement tree. Add - the DECL_STMTs inside the outermost scope. */ - tree *p = &DECL_SAVED_TREE (current_function_decl); - /* Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK. */ - while (TREE_CODE (*p) != COMPOUND_STMT) - { - if (TREE_CODE (*p) == EXPR_STMT) - p = &TREE_CHAIN (*p); - else - p = &TREE_OPERAND(*p, 0); - } + tree *bodyp = &DECL_SAVED_TREE (current_function_decl); - p = &COMPOUND_BODY (*p); - if (TREE_CODE (*p) == SCOPE_STMT) - p = &TREE_CHAIN (*p); + if (TREE_CODE (*bodyp) == COMPOUND_STMT) + bodyp = &COMPOUND_BODY (*bodyp); + if (TREE_CODE (*bodyp) == BIND_EXPR) + bodyp = &BIND_EXPR_BODY (*bodyp); - body = chainon (body, *p); - *p = body; + append_to_statement_list (*bodyp, &stmts); + *bodyp = stmts; } for (ix = 0; fname_vars[ix].decl; ix++) @@ -1167,30 +1010,23 @@ fname_decl (unsigned int rid, tree id) decl = *fname_vars[ix].decl; if (!decl) { - tree saved_last_tree = last_tree; /* If a tree is built here, it would normally have the lineno of the current statement. Later this tree will be moved to the beginning of the function and this line number will be wrong. To avoid this problem set the lineno to 0 here; that prevents it from appearing in the RTL. */ - int saved_lineno = input_line; + tree stmts; + location_t saved_locus = input_location; input_line = 0; + stmts = push_stmt_list (); decl = (*make_fname_decl) (id, fname_vars[ix].pretty); - if (last_tree != saved_last_tree) - { - /* We created some statement tree for the decl. This belongs - at the start of the function, so remove it now and reinsert - it after the function is complete. */ - tree stmts = TREE_CHAIN (saved_last_tree); - - TREE_CHAIN (saved_last_tree) = NULL_TREE; - last_tree = saved_last_tree; - saved_function_name_decls = tree_cons (decl, stmts, - saved_function_name_decls); - } + stmts = pop_stmt_list (stmts); + if (!IS_EMPTY_STMT (stmts)) + saved_function_name_decls + = tree_cons (decl, stmts, saved_function_name_decls); *fname_vars[ix].decl = decl; - input_line = saved_lineno; + input_location = saved_locus; } if (!ix && !current_function_decl) pedwarn ("%J'%D' is not defined outside of function scope", decl, decl); @@ -1790,7 +1626,11 @@ c_expand_expr_stmt (tree expr) && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE) error ("expression statement has incomplete type"); - last_expr_type = TREE_TYPE (expr); + /* As tempting as it might be, we can't diagnose statement with no + effect yet. We have to wait until after statement expressions + have been parsed, and that process modifies the trees we are + creating here. */ + return add_stmt (build_stmt (EXPR_STMT, expr)); } @@ -2855,28 +2695,28 @@ c_type_hash (const void *p) tree t2; switch (TREE_CODE (t)) { - /* For pointers, hash on pointee type plus some swizzling. */ - case POINTER_TYPE: - return c_type_hash (TREE_TYPE (t)) ^ 0x3003003; - /* Hash on number of elements and total size. */ - case ENUMERAL_TYPE: - shift = 3; - t2 = TYPE_VALUES (t); - break; - case RECORD_TYPE: - shift = 0; - t2 = TYPE_FIELDS (t); - break; - case QUAL_UNION_TYPE: - shift = 1; - t2 = TYPE_FIELDS (t); - break; - case UNION_TYPE: - shift = 2; - t2 = TYPE_FIELDS (t); - break; - default: - abort (); + /* For pointers, hash on pointee type plus some swizzling. */ + case POINTER_TYPE: + return c_type_hash (TREE_TYPE (t)) ^ 0x3003003; + /* Hash on number of elements and total size. */ + case ENUMERAL_TYPE: + shift = 3; + t2 = TYPE_VALUES (t); + break; + case RECORD_TYPE: + shift = 0; + t2 = TYPE_FIELDS (t); + break; + case QUAL_UNION_TYPE: + shift = 1; + t2 = TYPE_FIELDS (t); + break; + case UNION_TYPE: + shift = 2; + t2 = TYPE_FIELDS (t); + break; + default: + abort (); } for (; t2; t2 = TREE_CHAIN (t2)) i++; @@ -4287,10 +4127,6 @@ c_safe_from_p (rtx target, tree exp) return 0; } - /* For any statement, we must follow the statement-chain. */ - if (STATEMENT_CODE_P (TREE_CODE (exp)) && TREE_CHAIN (exp)) - return safe_from_p (target, TREE_CHAIN (exp), /*top_p=*/0); - /* Assume everything else is safe. */ return 1; } @@ -5727,18 +5563,6 @@ c_walk_subtrees (tree *tp, int *walk_subtrees_p ATTRIBUTE_UNUSED, #undef WALK_SUBTREE } -/* C implementation of lang_hooks.tree_inlining.tree_chain_matters_p. - Apart from TREE_LISTs, the only trees whose TREE_CHAIN we care about are - _STMT nodes. */ - -int -c_tree_chain_matters_p (tree t) -{ - /* For statements, we also walk the chain so that we cover the - entire statement tree. */ - return STATEMENT_CODE_P (TREE_CODE (t)); -} - /* Function to help qsort sort FIELD_DECLs by name order. */ int |