diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-07 01:36:11 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-07 01:36:11 +0000 |
commit | a08e60ae83fcfcdacf97c738e6c81c097ad979c4 (patch) | |
tree | 1ae8ce0d3f4f58cfa7b33b9fac7c1209e34d27a7 /gcc/c-common.c | |
parent | d2eef15bfd5afb4c864922ffa591fa3717269080 (diff) | |
download | gcc-a08e60ae83fcfcdacf97c738e6c81c097ad979c4.tar.gz |
Move statement-tree facilities from C++ to C front-end.
* c-common.h (c_tree_index): Add CTI_VOID_ZERO.
(void_zero_node): New macro.
(struct stmt_tree_s): New type.
(stmt_tree): New typedef.
(struct language_function): New type.
(last_tree): New macro.
(last_expr_type): Likewise.
(walk_tree_fn): New typedef.
(current_stmt_tree): New function.
(begin_stmt_tree): Likewise.
(add_stmt): Likewise.
(finish_stmt_tree): Likewise.
(statement_code_p): Likewise.
(lang_statement_code_p): New variable.
(walk_stmt_tree): New function.
(STMT_IS_FULL_EXPR_P): New macro.
* c-common.c (lang_statement_code_p): New variable.
(c_common_nodes_and_builtins): Initialize void_zero_node.
(statement_code_p): New function.
(walk_stmt_tree): Likewise.
* c-decl.c (language_function): Rename to ...
(c_language_function): ... this. Include language_function.
(push_c_function_context): Adjust accordingly.
(pop_c_function_context): Likewise.
(mark_c_function_context): Likewise.
(current_stmt_tree): Define.
* c-semantics.c (begin_stmt_tree): New function.
(add_stmt): Likewise.
(prune_unused_decls): Likewise.
(finish_stmt_tree): Likewise.
Move statement-tree facilities from C++ to C front-end.
* cp-tree.h (cp_tree_index): Remove CPTI_VOID_ZERO.
(void_zero_node): Remove.
(stmt_tree): Likewise.
(scope_chain): Adjust.
(language_function): Rename to cp_language_function.
(cp_function_chain): Adjust.
(current_stmt_tree): Remove.
(last_tree): Likewise.
(last_expr_type): Likewise.
(struct lang_decl): Adjust.
(STMT_IS_FULL_EXPR_P): Remove.
(add_tree): Remove.
(begin_stmt_tree): Likewise.
(finish_stmt_tree): Likewise.
(walk_tree_fn): Likewise.
(walk_stmt_tree): Likewise.
* class.c (finish_struct): Replace use of add_tree with add_stmt.
* decl.c (mark_stmt_tree): Adjust type.
(init_decl_processing): Don't build void_zero_node.
(initialize_local_var): Adjust usage of current_stmt_tree.
(finish_enum): Use add_stmt, not add_tree.
(save_function_data): Adjust use of language_function.
(finish_constructor_body): Use add_stmt, not add_tree.
(finish_destructor_body): Likewise.
(push_cp_function_context): Adjust use of language_function.
(pop_cp_function_context): Likewise.
(mark_lang_function): Likewise.
(mark_cp_function_context): Likewise.
* init.c (build_aggr_init): Adjust use of current_stmt_tree.
(build_vec_init): Likewise.
* semantics.c (SET_LAST_STMT): Remove.
(RECHAIN_STMTS): Don't use it.
(stmts_are_full_exprs_p): Adjust use of current_stmt_tree.
(current_stmt_tree): Define.
(add_tree): Remove.
(finish_goto_stmt): Use add_stmt, not add_tree.
(finish_expr_stmt): Likewise.
(begin_if_stmt): Likewise.
(finish_then_clause): Likewise.
(begin_while_stmt): Likewise.
(begin_do_stmt): Likewise.
(finish_return_stmt): Likewise.
(begin_for_stmt): Likewise.
(finish_break_stmt): Likewise.
(finish_continue_stmt): Likewise.
(begin_switch_stmt): Likewise.
(finish_case_label): Likewise.
(begin_try_block): Likewise.
(begin_function_try_block): Likewise.
(begin_handler): Likewise.
(begin_catch_block): Likewise.
(begin_compound_stmt): Likewise.
(begin_asm_stmt): Likewise.
(finish_asm_stmt): Likewise.
(finish_label_stmt): Likewise.
(add_decl_stmt): Likewise.
(finish_subobject): Likewise.
(finish_decl_cleanup): Likewise.
(finish_named_return_value): Likewise.
(setup_vtbl_ptr): Likewise.
(add_scope_stmt): Likewise.
(finish_stmt_expr): Likewise.
(prune_unused_decls): Remove.
(begin_stmt_tree): Likewise.
(finish_stmt_tree): Likewise.
(prep_stmt): Adjust use of current_stmt_tree.
(lang_expand_stmt): Likewise.
* tree.c (statement_code_p): Remove.
(cp_statement_code_p): New function.
(walk_stmt_tree): Remove.
(init_tree): Set lang_statement_code_p.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36221 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index efb81a37528..fc8476a222d 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -144,6 +144,10 @@ tree *ridpointers; tree (*make_fname_decl) PARAMS ((tree, const char *, int)); +/* If non-NULL, the address of a language-specific function that + returns 1 for language-specific statement codes. */ +int (*lang_statement_code_p) PARAMS ((enum tree_code)); + /* Nonzero means the expression being parsed will never be evaluated. This is a count, since unevaluated expressions can nest. */ int skip_evaluation; @@ -3870,6 +3874,9 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins) sizetype, endlink)))); + void_zero_node = build_int_2 (0, 0); + TREE_TYPE (void_zero_node) = void_type_node; + /* Prototype for strcpy. */ string_ftype_ptr_ptr = build_function_type (string_type_node, @@ -4378,6 +4385,111 @@ expand_tree_builtin (function, params, coerced_params) return NULL_TREE; } +/* Returns non-zero if CODE is the code for a statement. */ + +int +statement_code_p (code) + enum tree_code code; +{ + switch (code) + { + case EXPR_STMT: + case COMPOUND_STMT: + case DECL_STMT: + case IF_STMT: + case FOR_STMT: + case WHILE_STMT: + case DO_STMT: + case RETURN_STMT: + case BREAK_STMT: + case CONTINUE_STMT: + case SWITCH_STMT: + case GOTO_STMT: + case LABEL_STMT: + case ASM_STMT: + case CASE_LABEL: + return 1; + + default: + if (lang_statement_code_p) + return (*lang_statement_code_p) (code); + return 0; + } +} + +/* Walk the statemen tree, rooted at *tp. Apply FUNC to all the + sub-trees of *TP in a pre-order traversal. FUNC is called with the + DATA and the address of each sub-tree. If FUNC returns a non-NULL + value, the traversal is aborted, and the value returned by FUNC is + returned. If FUNC sets WALK_SUBTREES to zero, then the subtrees of + the node being visited are not walked. + + We don't need a without_duplicates variant of this one because the + statement tree is a tree, not a graph. */ + +tree +walk_stmt_tree (tp, func, data) + tree *tp; + walk_tree_fn func; + void *data; +{ + enum tree_code code; + int walk_subtrees; + tree result; + int i, len; + +#define WALK_SUBTREE(NODE) \ + do \ + { \ + result = walk_stmt_tree (&(NODE), func, data); \ + if (result) \ + return result; \ + } \ + while (0) + + /* Skip empty subtrees. */ + if (!*tp) + return NULL_TREE; + + /* Skip subtrees below non-statement nodes. */ + if (!statement_code_p (TREE_CODE (*tp))) + return NULL_TREE; + + /* Call the function. */ + walk_subtrees = 1; + result = (*func) (tp, &walk_subtrees, data); + + /* If we found something, return it. */ + if (result) + return result; + + /* Even if we didn't, FUNC may have decided that there was nothing + interesting below this point in the tree. */ + if (!walk_subtrees) + return NULL_TREE; + + /* FUNC may have modified the tree, recheck that we're looking at a + statement node. */ + code = TREE_CODE (*tp); + if (!statement_code_p (code)) + return NULL_TREE; + + /* Walk over all the sub-trees of this operand. Statement nodes never + contain RTL, and we needn't worry about TARGET_EXPRs. */ + len = TREE_CODE_LENGTH (code); + + /* Go through the subtrees. We need to do this in forward order so + that the scope of a FOR_EXPR is handled properly. */ + for (i = 0; i < len; ++i) + WALK_SUBTREE (TREE_OPERAND (*tp, i)); + + /* Finally visit the chain. This can be tail-recursion optimized if + we write it this way. */ + return walk_stmt_tree (&TREE_CHAIN (*tp), func, data); + +#undef WALK_SUBTREE +} + /* Tree code classes. */ #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, |