summaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-09-07 01:36:11 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2000-09-07 01:36:11 +0000
commita08e60ae83fcfcdacf97c738e6c81c097ad979c4 (patch)
tree1ae8ce0d3f4f58cfa7b33b9fac7c1209e34d27a7 /gcc/c-common.c
parentd2eef15bfd5afb4c864922ffa591fa3717269080 (diff)
downloadgcc-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.c112
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,