From ae499ccea4f2eee460c8612d920755773cacfe47 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Thu, 7 Sep 2000 01:36:11 +0000 Subject: [PATCH] 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. From-SVN: r36221 --- gcc/ChangeLog | 34 ++++++++ gcc/c-common.c | 112 +++++++++++++++++++++++++ gcc/c-common.h | 76 ++++++++++++++++- gcc/c-decl.c | 26 ++++-- gcc/c-semantics.c | 113 +++++++++++++++++++++++++ gcc/cp/ChangeLog | 75 +++++++++++++++++ gcc/cp/class.c | 2 +- gcc/cp/cp-tree.h | 60 ++------------ gcc/cp/decl.c | 52 ++++++------ gcc/cp/init.c | 12 +-- gcc/cp/semantics.c | 203 +++++++++++---------------------------------- gcc/cp/tree.c | 95 ++------------------- libio/editbuf.h | 2 +- libobjc/encoding.c | 2 +- 14 files changed, 524 insertions(+), 340 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0214e8d4d99..7cc7fda58ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,37 @@ +2000-09-06 Mark Mitchell + + 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. + 2000-09-06 Herman A.J. ten Brugge * flow.c (insn_dead_p): Detect dead memory stores with auto increments. 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, diff --git a/gcc/c-common.h b/gcc/c-common.h index 7b4912cb03b..6f442c466c6 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -147,6 +147,8 @@ enum c_tree_index CTI_PRETTY_FUNCTION_ID, CTI_FUNC_ID, + CTI_VOID_ZERO, + CTI_MAX }; @@ -187,6 +189,9 @@ enum c_tree_index #define pretty_function_id_node c_global_trees[CTI_PRETTY_FUNCTION_ID] #define func_id_node c_global_trees[CTI_FUNC_ID] +/* A node for `((void) 0)'. */ +#define void_zero_node c_global_trees[CTI_VOID_ZERO] + extern tree c_global_trees[CTI_MAX]; typedef enum c_language_kind @@ -198,6 +203,68 @@ typedef enum c_language_kind } c_language_kind; +/* Information about a statement tree. */ + +struct stmt_tree_s { + /* The last statement added to the tree. */ + tree x_last_stmt; + /* The type of the last expression statement. (This information is + needed to implement the statement-expression extension.) */ + tree x_last_expr_type; + /* In C++, Non-zero if we should treat statements as full + expressions. In particular, this variable is no-zero if at the + end of a statement we should destroy any temporaries created + during that statement. Similarly, if, at the end of a block, we + should destroy any local variables in this block. Normally, this + variable is non-zero, since those are the normal semantics of + C++. + + However, in order to represent aggregate initialization code as + tree structure, we use statement-expressions. The statements + within the statement expression should not result in cleanups + being run until the entire enclosing statement is complete. + + This flag has no effect in C. */ + int stmts_are_full_exprs_p; +}; + +typedef struct stmt_tree_s *stmt_tree; + +/* Global state pertinent to the current function. Some C dialects + extend this structure with additional fields. */ + +struct language_function { + /* While we are parsing the function, this contains information + about the statement-tree that we are building. */ + struct stmt_tree_s x_stmt_tree; +}; + +/* When building a statement-tree, this is the last statement added to + the tree. */ + +#define last_tree (current_stmt_tree ()->x_last_stmt) + +/* The type of the last expression-statement we have seen. */ + +#define last_expr_type (current_stmt_tree ()->x_last_expr_type) + +/* The type of a function that walks over tree structure. */ + +typedef tree (*walk_tree_fn) PARAMS ((tree *, + int *, + void *)); + +extern stmt_tree current_stmt_tree PARAMS ((void)); +extern void begin_stmt_tree PARAMS ((tree *)); +extern void add_stmt PARAMS ((tree)); +extern void finish_stmt_tree PARAMS ((tree *)); + +extern int statement_code_p PARAMS ((enum tree_code)); +extern int (*lang_statement_code_p) PARAMS ((enum tree_code)); +extern tree walk_stmt_tree PARAMS ((tree *, + walk_tree_fn, + void *)); + /* The variant of the C language being processed. Each C language front-end defines this variable. */ @@ -337,8 +404,13 @@ extern tree build_va_arg PARAMS ((tree, tree)); extern int self_promoting_args_p PARAMS ((tree)); extern tree simple_type_promotes_to PARAMS ((tree)); -/* These macros provide convenient access to the various _STMT nodes - created when parsing template declarations. */ +/* These macros provide convenient access to the various _STMT nodes. */ + +/* Nonzero if this statement should be considered a full-expression, + i.e., if temporaries created during this statement should have + their destructors run at the end of this statement. (In C, this + will always be false, since there are no destructors.) */ +#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE)) /* IF_STMT accessors. These give access to the condtion of the if statement, the then block of the if statement, and the else block diff --git a/gcc/c-decl.c b/gcc/c-decl.c index af9428b0125..a5dc3d64e98 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -6761,8 +6761,9 @@ finish_function (nested) that keep track of the progress of compilation of the current function. Used for nested functions. */ -struct language_function +struct c_language_function { + struct language_function base; tree named_labels; tree shadowed_labels; int returns_value; @@ -6779,9 +6780,10 @@ void push_c_function_context (f) struct function *f; { - struct language_function *p; - p = (struct language_function *) xmalloc (sizeof (struct language_function)); - f->language = p; + struct c_language_function *p; + p = ((struct c_language_function *) + xmalloc (sizeof (struct c_language_function))); + f->language = (struct language_function *) p; p->named_labels = named_labels; p->shadowed_labels = shadowed_labels; @@ -6798,7 +6800,8 @@ void pop_c_function_context (f) struct function *f; { - struct language_function *p = f->language; + struct c_language_function *p + = (struct c_language_function *) f->language; tree link; /* Bring back all the labels that were shadowed. */ @@ -6834,7 +6837,8 @@ void mark_c_function_context (f) struct function *f; { - struct language_function *p = f->language; + struct c_language_function *p + = (struct c_language_function *) f->language; if (p == 0) return; @@ -6899,6 +6903,16 @@ stmts_are_full_exprs_p () return 0; } +/* Returns the stmt_tree (if any) to which statements are currently + being added. If there is no active statement-tree, NULL is + returned. */ + +stmt_tree +current_stmt_tree () +{ + return cfun ? &cfun->language->x_stmt_tree : NULL; +} + /* Nonzero if TYPE is an anonymous union or struct type. Always 0 in C. */ diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c index 2e0d537f1ae..eea9f9209e5 100644 --- a/gcc/c-semantics.c +++ b/gcc/c-semantics.c @@ -36,6 +36,119 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "timevar.h" +static tree prune_unused_decls PARAMS ((tree *, int *, void *)); + +/* Create an empty statement tree rooted at T. */ + +void +begin_stmt_tree (t) + tree *t; +{ + /* 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; +} + +/* T is a statement. Add it to the statement-tree. */ + +void +add_stmt (t) + tree t; +{ + /* 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-expresions. We record that fact here. */ + STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p (); +} + +/* Remove declarations of internal variables that are not used from a + stmt tree. To qualify, the variable must have a name and must have + a zero DECL_SOURCE_LINE. We tried to remove all variables for + which TREE_USED was false, but it turns out that there's tons of + variables for which TREE_USED is false but that are still in fact + used. */ + +static tree +prune_unused_decls (tp, walk_subtrees, data) + tree *tp; + int *walk_subtrees ATTRIBUTE_UNUSED; + void *data ATTRIBUTE_UNUSED; +{ + tree t = *tp; + + if (t == NULL_TREE) + { + *walk_subtrees = 0; + return NULL_TREE; + } + + if (TREE_CODE (t) == DECL_STMT) + { + tree d = DECL_STMT_DECL (t); + if (!TREE_USED (d) && DECL_NAME (d) && DECL_SOURCE_LINE (d) == 0) + { + *tp = TREE_CHAIN (t); + /* Recurse on the new value of tp, otherwise we will skip + the next statement. */ + return prune_unused_decls (tp, walk_subtrees, data); + } + } + else if (TREE_CODE (t) == SCOPE_STMT) + { + /* Remove all unused decls from the BLOCK of this SCOPE_STMT. */ + tree block = SCOPE_STMT_BLOCK (t); + + if (block) + { + tree *vp; + + for (vp = &BLOCK_VARS (block); *vp; ) + { + tree v = *vp; + if (! TREE_USED (v) && DECL_NAME (v) && DECL_SOURCE_LINE (v) == 0) + *vp = TREE_CHAIN (v); /* drop */ + else + vp = &TREE_CHAIN (v); /* advance */ + } + /* If there are now no variables, the entire BLOCK can be dropped. + (This causes SCOPE_NULLIFIED_P (t) to be true.) */ + if (BLOCK_VARS (block) == NULL_TREE) + SCOPE_STMT_BLOCK (t) = NULL_TREE; + } + } + return NULL_TREE; +} + +/* Finish the statement tree rooted at T. */ + +void +finish_stmt_tree (t) + tree *t; +{ + tree stmt; + + /* Remove the fake extra statement added in begin_stmt_tree. */ + stmt = TREE_CHAIN (*t); + *t = stmt; + last_tree = NULL_TREE; + + /* Remove unused decls from the stmt tree. */ + walk_stmt_tree (t, prune_unused_decls, NULL); + + if (cfun) + { + /* The line-number recorded in the outermost statement in a function + is the line number of the end of the function. */ + STMT_LINENO (stmt) = lineno; + STMT_LINENO_FOR_FN_P (stmt) = 1; + } +} + /* Build a generic statement based on the given type of node and arguments. Similar to `build_nt', except that we set TREE_COMPLEXITY to be the current line number. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4b28703e6d2..5f6ea876428 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,78 @@ +2000-09-06 Mark Mitchell + + 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. + 2000-09-06 Zack Weinberg Integrated preprocessor. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 0306df79df9..6477261b9a0 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5265,7 +5265,7 @@ finish_struct (t, attributes) { tree scope = current_scope (); if (scope && TREE_CODE (scope) == FUNCTION_DECL) - add_tree (build_min (TAG_DEFN, t)); + add_stmt (build_min (TAG_DEFN, t)); } return t; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b32367ba3aa..9fb04e52a37 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -559,7 +559,6 @@ enum cp_tree_index CPTI_JAVA_CHAR_TYPE, CPTI_JAVA_BOOLEAN_TYPE, - CPTI_VOID_ZERO, CPTI_WCHAR_DECL, CPTI_VTABLE_ENTRY_TYPE, CPTI_DELTA_TYPE, @@ -652,7 +651,6 @@ extern tree cp_global_trees[CPTI_MAX]; #define java_char_type_node cp_global_trees[CPTI_JAVA_CHAR_TYPE] #define java_boolean_type_node cp_global_trees[CPTI_JAVA_BOOLEAN_TYPE] -#define void_zero_node cp_global_trees[CPTI_VOID_ZERO] #define wchar_decl_node cp_global_trees[CPTI_WCHAR_DECL] #define vtable_entry_type cp_global_trees[CPTI_VTABLE_ENTRY_TYPE] /* The type used to represent an offset by which to adjust the `this' @@ -784,23 +782,6 @@ extern tree cp_global_trees[CPTI_MAX]; /* Global state. */ -struct stmt_tree { - tree x_last_stmt; - tree x_last_expr_type; -/* Non-zero if we should treat statements as full expressions. In - particular, this variable is no-zero if at the end of a statement - we should destroy any temporaries created during that statement. - Similarly, if, at the end of a block, we should destroy any local - variables in this block. Normally, this variable is non-zero, - since those are the normal semantics of C++. - - However, in order to represent aggregate initialization code as - tree structure, we use statement-expressions. The statements - within the statement expression should not result in cleanups being - run until the entire enclosing statement is complete. */ - int stmts_are_full_exprs_p; -}; - struct saved_scope { tree old_bindings; tree old_namespace; @@ -824,7 +805,7 @@ struct saved_scope { int x_processing_explicit_instantiation; int need_pop_function_context; - struct stmt_tree x_stmt_tree; + struct stmt_tree_s x_stmt_tree; struct binding_level *class_bindings; struct binding_level *bindings; @@ -890,8 +871,10 @@ extern struct saved_scope *scope_chain; /* Global state pertinent to the current function. */ -struct language_function +struct cp_language_function { + struct language_function base; + tree x_ctor_label; tree x_dtor_label; tree x_current_class_ptr; @@ -912,8 +895,6 @@ struct language_function int name_declared; int vtbls_set_up_p; - struct stmt_tree x_stmt_tree; - struct named_label_use_list *x_named_label_uses; struct named_label_list *x_named_labels; struct binding_level *bindings; @@ -923,7 +904,8 @@ struct language_function /* The current C++-specific per-function global variables. */ -#define cp_function_chain (cfun->language) +#define cp_function_chain \ + ((struct cp_language_function *) (cfun->language)) /* In a destructor, the point at which all derived class destroying has been done, just before any base class destroying will be done. */ @@ -944,24 +926,6 @@ struct language_function #define current_class_ref \ (cfun ? cp_function_chain->x_current_class_ref : NULL_TREE) -/* Information about the current statement tree. */ - -#define current_stmt_tree \ - (cfun \ - ? &cp_function_chain->x_stmt_tree \ - : &scope_chain->x_stmt_tree) - -/* When building a statement-tree, this is the last statement added to - the tree. */ - -#define last_tree current_stmt_tree->x_last_stmt - -/* The type of the last expression-statement we have seen. This is - required because the type of a statement-expression is the type of - the last expression statement. */ - -#define last_expr_type current_stmt_tree->x_last_expr_type - /* The TRY_BLOCK for the exception-specifiers for the current function, if any. */ @@ -1927,7 +1891,7 @@ struct lang_decl { tree sorted_fields; struct unparsed_text *pending_inline_info; - struct language_function *saved_language_function; + struct cp_language_function *saved_language_function; } u; union { @@ -2474,9 +2438,6 @@ struct lang_decl #define AGGR_INIT_VIA_CTOR_P(NODE) \ TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE)) -/* Nonzero if this statement should be considered a full-expression. */ -#define STMT_IS_FULL_EXPR_P(NODE) TREE_LANG_FLAG_1 ((NODE)) - /* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a TEMPLATE_DECL. This macro determines whether or not a given class type is really a template type, as opposed to an instantiation or @@ -4231,7 +4192,6 @@ extern void do_decl_instantiation PARAMS ((tree, tree, tree)); extern void do_type_instantiation PARAMS ((tree, tree, int)); extern tree instantiate_decl PARAMS ((tree, int)); extern tree get_bindings PARAMS ((tree, tree, tree)); -extern void add_tree PARAMS ((tree)); extern void add_maybe_template PARAMS ((tree, tree)); extern void pop_tinst_level PARAMS ((void)); extern int more_specialized_class PARAMS ((tree, tree)); @@ -4409,8 +4369,6 @@ extern void add_decl_stmt PARAMS ((tree)); extern void finish_decl_cleanup PARAMS ((tree, tree)); extern void finish_named_return_value PARAMS ((tree, tree)); extern void expand_body PARAMS ((tree)); -extern void begin_stmt_tree PARAMS ((tree *)); -extern void finish_stmt_tree PARAMS ((tree *)); extern void prep_stmt PARAMS ((tree)); extern tree add_scope_stmt PARAMS ((int, int)); extern void do_pushlevel PARAMS ((void)); @@ -4494,7 +4452,6 @@ extern void debug_binfo PARAMS ((tree)); extern tree build_dummy_object PARAMS ((tree)); extern tree maybe_dummy_object PARAMS ((tree, tree *)); extern int is_dummy_object PARAMS ((tree)); -typedef tree (*walk_tree_fn) PARAMS ((tree *, int *, void *)); extern tree walk_tree PARAMS ((tree *, walk_tree_fn, void *, @@ -4502,9 +4459,6 @@ extern tree walk_tree PARAMS ((tree *, extern tree walk_tree_without_duplicates PARAMS ((tree *, walk_tree_fn, void *)); -extern tree walk_stmt_tree PARAMS ((tree *, - walk_tree_fn, - void *)); extern tree copy_tree_r PARAMS ((tree *, int *, void *)); extern int cp_valid_lang_attribute PARAMS ((tree, tree, tree, tree)); extern tree make_ptrmem_cst PARAMS ((tree, tree)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 03d8c6a1336..5ca1e5597d5 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -169,8 +169,8 @@ static void mark_binding_level PARAMS ((void *)); static void mark_named_label_lists PARAMS ((void *, void *)); static void mark_cp_function_context PARAMS ((struct function *)); static void mark_saved_scope PARAMS ((void *)); -static void mark_lang_function PARAMS ((struct language_function *)); -static void mark_stmt_tree PARAMS ((struct stmt_tree *)); +static void mark_lang_function PARAMS ((struct cp_language_function *)); +static void mark_stmt_tree PARAMS ((stmt_tree)); static void save_function_data PARAMS ((tree)); static void check_function_type PARAMS ((tree)); static void destroy_local_var PARAMS ((tree)); @@ -200,7 +200,6 @@ tree error_mark_list; C++ extensions tree wchar_decl_node; - tree void_zero_node; tree vtable_entry_type; tree delta_type_node; @@ -2453,7 +2452,7 @@ struct saved_scope *scope_chain; static void mark_stmt_tree (st) - struct stmt_tree *st; + stmt_tree st; { ggc_mark_tree (st->x_last_stmt); ggc_mark_tree (st->x_last_expr_type); @@ -6471,10 +6470,6 @@ init_decl_processing () void_list_node = build_tree_list (NULL_TREE, void_type_node); TREE_PARMLIST (void_list_node) = 1; - /* Used for expressions that do nothing, but are not errors. */ - void_zero_node = build_int_2 (0, 0); - TREE_TYPE (void_zero_node) = void_type_node; - string_type_node = build_pointer_type (char_type_node); const_string_type_node = build_pointer_type (build_qualified_type (char_type_node, @@ -7965,12 +7960,13 @@ initialize_local_var (decl, init, flags) emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p (); - current_stmt_tree->stmts_are_full_exprs_p = 1; + current_stmt_tree ()->stmts_are_full_exprs_p = 1; if (building_stmt_tree ()) finish_expr_stmt (build_aggr_init (decl, init, flags)); else genrtl_expr_stmt (build_aggr_init (decl, init, flags)); - current_stmt_tree->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p; + current_stmt_tree ()->stmts_are_full_exprs_p = + saved_stmts_are_full_exprs_p; } /* Set this to 0 so we can tell whether an aggregate which was @@ -13244,7 +13240,7 @@ finish_enum (enumtype) { tree scope = current_scope (); if (scope && TREE_CODE (scope) == FUNCTION_DECL) - add_tree (build_min (TAG_DEFN, enumtype)); + add_stmt (build_min (TAG_DEFN, enumtype)); } else { @@ -14037,7 +14033,7 @@ static void save_function_data (decl) tree decl; { - struct language_function *f; + struct cp_language_function *f; /* Save the language-specific per-function data so that we can get it back when we really expand this function. */ @@ -14045,15 +14041,15 @@ save_function_data (decl) 19990908); /* Make a copy. */ - f = ((struct language_function *) - xmalloc (sizeof (struct language_function))); + f = ((struct cp_language_function *) + xmalloc (sizeof (struct cp_language_function))); bcopy ((char *) cp_function_chain, (char *) f, - sizeof (struct language_function)); + sizeof (struct cp_language_function)); DECL_SAVED_FUNCTION_DATA (decl) = f; /* Clear out the bits we don't need. */ - f->x_stmt_tree.x_last_stmt = NULL_TREE; - f->x_stmt_tree.x_last_expr_type = NULL_TREE; + f->base.x_stmt_tree.x_last_stmt = NULL_TREE; + f->base.x_stmt_tree.x_last_expr_type = NULL_TREE; f->x_result_rtx = NULL_RTX; f->x_named_label_uses = NULL; f->bindings = NULL; @@ -14075,7 +14071,7 @@ finish_constructor_body () { /* Any return from a constructor will end up here. */ if (ctor_label) - add_tree (build_stmt (LABEL_STMT, ctor_label)); + add_stmt (build_stmt (LABEL_STMT, ctor_label)); /* Clear CTOR_LABEL so that finish_return_stmt knows to really generate the return, rather than a goto to CTOR_LABEL. */ @@ -14084,7 +14080,7 @@ finish_constructor_body () constructor to a return of `this'. */ finish_return_stmt (NULL_TREE); /* Mark the end of the constructor. */ - add_tree (build_stmt (CTOR_STMT)); + add_stmt (build_stmt (CTOR_STMT)); } /* At the end of every destructor we generate code to restore virtual @@ -14103,7 +14099,7 @@ finish_destructor_body () compound_stmt = begin_compound_stmt (/*has_no_scope=*/0); /* Any return from a destructor will end up here. */ - add_tree (build_stmt (LABEL_STMT, dtor_label)); + add_stmt (build_stmt (LABEL_STMT, dtor_label)); /* Generate the code to call destructor on base class. If this destructor belongs to a class with virtual functions, then set @@ -14896,10 +14892,10 @@ static void push_cp_function_context (f) struct function *f; { - struct language_function *p - = ((struct language_function *) - xcalloc (1, sizeof (struct language_function))); - f->language = p; + struct cp_language_function *p + = ((struct cp_language_function *) + xcalloc (1, sizeof (struct cp_language_function))); + f->language = (struct language_function *) p; /* It takes an explicit call to expand_body to generate RTL for a function. */ @@ -14907,7 +14903,7 @@ push_cp_function_context (f) /* Whenever we start a new function, we destroy temporaries in the usual way. */ - current_stmt_tree->stmts_are_full_exprs_p = 1; + current_stmt_tree ()->stmts_are_full_exprs_p = 1; } /* Free the language-specific parts of F, now that we've finished @@ -14926,7 +14922,7 @@ pop_cp_function_context (f) static void mark_lang_function (p) - struct language_function *p; + struct cp_language_function *p; { if (!p) return; @@ -14941,7 +14937,7 @@ mark_lang_function (p) ggc_mark_rtx (p->x_result_rtx); mark_named_label_lists (&p->x_named_labels, &p->x_named_label_uses); - mark_stmt_tree (&p->x_stmt_tree); + mark_stmt_tree (&p->base.x_stmt_tree); mark_binding_level (&p->bindings); } @@ -14951,7 +14947,7 @@ static void mark_cp_function_context (f) struct function *f; { - mark_lang_function (f->language); + mark_lang_function ((struct cp_language_function *) f->language); } void diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 68f92b6835b..f39f37f4e9b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1228,11 +1228,11 @@ build_aggr_init (exp, init, flags) TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); begin_init_stmts (&stmt_expr, &compound_stmt); destroy_temps = stmts_are_full_exprs_p (); - current_stmt_tree->stmts_are_full_exprs_p = 0; + current_stmt_tree ()->stmts_are_full_exprs_p = 0; expand_aggr_init_1 (TYPE_BINFO (type), exp, exp, init, LOOKUP_NORMAL|flags); stmt_expr = finish_init_stmts (stmt_expr, compound_stmt); - current_stmt_tree->stmts_are_full_exprs_p = destroy_temps; + current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps; TREE_TYPE (exp) = type; TREE_READONLY (exp) = was_const; TREE_THIS_VOLATILE (exp) = was_volatile; @@ -2873,7 +2873,7 @@ build_vec_init (decl, base, maxindex, init, from_array) begin_init_stmts (&stmt_expr, &compound_stmt); destroy_temps = stmts_are_full_exprs_p (); - current_stmt_tree->stmts_are_full_exprs_p = 0; + current_stmt_tree ()->stmts_are_full_exprs_p = 0; rval = get_temp_regvar (ptype, cp_convert (ptype, default_conversion (base))); base = get_temp_regvar (ptype, rval); @@ -3035,9 +3035,9 @@ build_vec_init (decl, base, maxindex, init, from_array) } else { - current_stmt_tree->stmts_are_full_exprs_p = 1; + current_stmt_tree ()->stmts_are_full_exprs_p = 1; finish_expr_stmt (elt_init); - current_stmt_tree->stmts_are_full_exprs_p = 0; + current_stmt_tree ()->stmts_are_full_exprs_p = 0; } finish_expr_stmt (build_modify_expr @@ -3087,7 +3087,7 @@ build_vec_init (decl, base, maxindex, init, from_array) finish_expr_stmt (rval); stmt_expr = finish_init_stmts (stmt_expr, compound_stmt); - current_stmt_tree->stmts_are_full_exprs_p = destroy_temps; + current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps; return stmt_expr; } diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 8b1efab9917..0435e2f3e50 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -48,27 +48,20 @@ static tree maybe_convert_cond PARAMS ((tree)); static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *)); -static tree prune_unused_decls PARAMS ((tree *, int *, void *)); static void deferred_type_access_control PARAMS ((void)); static void emit_associated_thunks PARAMS ((tree)); -/* Record the fact that STMT was the last statement added to the - statement tree. */ - -#define SET_LAST_STMT(stmt) \ - (current_stmt_tree->x_last_stmt = (stmt)) - /* When parsing a template, LAST_TREE contains the last statement parsed. These are chained together through the TREE_CHAIN field, but often need to be re-organized since the parse is performed bottom-up. This macro makes LAST_TREE the indicated SUBSTMT of STMT. */ -#define RECHAIN_STMTS(stmt, substmt) \ - do { \ - substmt = TREE_CHAIN (stmt); \ - TREE_CHAIN (stmt) = NULL_TREE; \ - SET_LAST_STMT (stmt); \ +#define RECHAIN_STMTS(stmt, substmt) \ + do { \ + substmt = TREE_CHAIN (stmt); \ + TREE_CHAIN (stmt) = NULL_TREE; \ + last_tree = stmt; \ } while (0) /* Finish processing the COND, the SUBSTMT condition for STMT. */ @@ -108,7 +101,19 @@ set_current_function_name_declared (i) int stmts_are_full_exprs_p () { - return current_stmt_tree->stmts_are_full_exprs_p; + return current_stmt_tree ()->stmts_are_full_exprs_p; +} + +/* Returns the stmt_tree (if any) to which statements are currently + being added. If there is no active statement-tree, NULL is + returned. */ + +stmt_tree +current_stmt_tree () +{ + return (cfun + ? &cfun->language->x_stmt_tree + : &scope_chain->x_stmt_tree); } /* One if we have already declared __FUNCTION__ (and related @@ -170,20 +175,6 @@ do_pushlevel () } } -/* T is a statement. Add it to the statement-tree. */ - -void -add_tree (t) - tree t; -{ - /* Add T to the statement-tree. */ - TREE_CHAIN (last_tree) = t; - SET_LAST_STMT (t); - /* When we expand a statement-tree, we must know whether or not the - statements are full-expresions. We record that fact here. */ - STMT_IS_FULL_EXPR_P (last_tree) = stmts_are_full_exprs_p (); -} - /* Finish a goto-statement. */ void @@ -207,7 +198,7 @@ finish_goto_stmt (destination) check_goto (destination); - add_tree (build_stmt (GOTO_STMT, destination)); + add_stmt (build_stmt (GOTO_STMT, destination)); } /* COND is the condition-expression for an if, while, etc., @@ -251,7 +242,7 @@ finish_expr_stmt (expr) if (!processing_template_decl) expr = break_out_cleanups (expr); - add_tree (build_stmt (EXPR_STMT, expr)); + add_stmt (build_stmt (EXPR_STMT, expr)); } finish_stmt (); @@ -271,7 +262,7 @@ begin_if_stmt () tree r; do_pushlevel (); r = build_stmt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE); - add_tree (r); + add_stmt (r); return r; } @@ -295,7 +286,7 @@ finish_then_clause (if_stmt) tree if_stmt; { RECHAIN_STMTS (if_stmt, THEN_CLAUSE (if_stmt)); - SET_LAST_STMT (if_stmt); + last_tree = if_stmt; return if_stmt; } @@ -346,7 +337,7 @@ begin_while_stmt () { tree r; r = build_stmt (WHILE_STMT, NULL_TREE, NULL_TREE); - add_tree (r); + add_stmt (r); do_pushlevel (); return r; } @@ -382,7 +373,7 @@ tree begin_do_stmt () { tree r = build_stmt (DO_STMT, NULL_TREE, NULL_TREE); - add_tree (r); + add_stmt (r); return r; } @@ -440,7 +431,7 @@ finish_return_stmt (expr) return; } } - add_tree (build_stmt (RETURN_STMT, expr)); + add_stmt (build_stmt (RETURN_STMT, expr)); finish_stmt (); } @@ -454,7 +445,7 @@ begin_for_stmt () r = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE); NEW_FOR_SCOPE_P (r) = flag_new_for_scope > 0; - add_tree (r); + add_stmt (r); if (NEW_FOR_SCOPE_P (r)) { do_pushlevel (); @@ -521,7 +512,7 @@ finish_for_stmt (for_stmt) void finish_break_stmt () { - add_tree (build_stmt (BREAK_STMT)); + add_stmt (build_stmt (BREAK_STMT)); } /* Finish a continue-statement. */ @@ -529,7 +520,7 @@ finish_break_stmt () void finish_continue_stmt () { - add_tree (build_stmt (CONTINUE_STMT)); + add_stmt (build_stmt (CONTINUE_STMT)); } /* Begin a switch-statement. Returns a new SWITCH_STMT if @@ -540,7 +531,7 @@ begin_switch_stmt () { tree r; r = build_stmt (SWITCH_STMT, NULL_TREE, NULL_TREE); - add_tree (r); + add_stmt (r); do_pushlevel (); return r; } @@ -593,7 +584,7 @@ finish_case_label (low_value, high_value) { /* Add a representation for the case label to the statement tree. */ - add_tree (build_stmt (CASE_LABEL, low_value, high_value)); + add_stmt (build_stmt (CASE_LABEL, low_value, high_value)); /* And warn about crossing initializations, etc. */ if (!processing_template_decl) define_case_label (); @@ -649,7 +640,7 @@ tree begin_try_block () { tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE); - add_tree (r); + add_stmt (r); return r; } @@ -660,7 +651,7 @@ begin_function_try_block () { tree r = build_stmt (TRY_BLOCK, NULL_TREE, NULL_TREE); FN_TRY_BLOCK_P (r) = 1; - add_tree (r); + add_stmt (r); return r; } @@ -761,7 +752,7 @@ begin_handler () { tree r; r = build_stmt (HANDLER, NULL_TREE, NULL_TREE); - add_tree (r); + add_stmt (r); do_pushlevel (); return r; } @@ -813,7 +804,7 @@ void begin_catch_block (type) tree type; { - add_tree (build (START_CATCH_STMT, type)); + add_stmt (build (START_CATCH_STMT, type)); } /* Finish a handler, which may be given by HANDLER. The BLOCKs are @@ -861,7 +852,7 @@ begin_compound_stmt (has_no_scope) if (last_tree && TREE_CODE (last_tree) == TRY_BLOCK) is_try = 1; - add_tree (r); + add_stmt (r); if (has_no_scope) COMPOUND_STMT_NO_SCOPE (r) = 1; @@ -957,7 +948,7 @@ finish_asm_stmt (cv_qualifier, string, output_operands, r = build_stmt (ASM_STMT, cv_qualifier, string, output_operands, input_operands, clobbers); - add_tree (r); + add_stmt (r); } /* Finish a label with the indicated NAME. */ @@ -967,7 +958,7 @@ finish_label_stmt (name) tree name; { tree decl = define_label (input_filename, lineno, name); - add_tree (build_stmt (LABEL_STMT, decl)); + add_stmt (build_stmt (LABEL_STMT, decl)); } /* Finish a series of declarations for local labels. G++ allows users @@ -993,7 +984,7 @@ add_decl_stmt (decl) /* We need the type to last until instantiation time. */ decl_stmt = build_stmt (DECL_STMT, decl); - add_tree (decl_stmt); + add_stmt (decl_stmt); } /* Generate the RTL for a SUBOBJECT. */ @@ -1014,7 +1005,7 @@ finish_subobject (cleanup) tree cleanup; { tree r = build_stmt (SUBOBJECT, cleanup); - add_tree (r); + add_stmt (r); } /* When DECL goes out of scope, make sure that CLEANUP is executed. */ @@ -1024,7 +1015,7 @@ finish_decl_cleanup (decl, cleanup) tree decl; tree cleanup; { - add_tree (build_stmt (CLEANUP_STMT, decl, cleanup)); + add_stmt (build_stmt (CLEANUP_STMT, decl, cleanup)); } /* Generate the RTL for a RETURN_INIT. */ @@ -1103,10 +1094,10 @@ finish_named_return_value (return_id, init) if (!processing_template_decl) { cp_finish_decl (decl, init, NULL_TREE, 0); - add_tree (build_stmt (RETURN_INIT, NULL_TREE, NULL_TREE)); + add_stmt (build_stmt (RETURN_INIT, NULL_TREE, NULL_TREE)); } else - add_tree (build_stmt (RETURN_INIT, return_id, init)); + add_stmt (build_stmt (RETURN_INIT, return_id, init)); } /* Don't use tree-inlining for functions with named return values. @@ -1192,7 +1183,7 @@ setup_vtbl_ptr (member_init_list, base_init_list) if (DECL_CONSTRUCTOR_P (current_function_decl)) { if (processing_template_decl) - add_tree (build_min_nt + add_stmt (build_min_nt (CTOR_INITIALIZER, member_init_list, base_init_list)); else @@ -1202,7 +1193,7 @@ setup_vtbl_ptr (member_init_list, base_init_list) /* Mark the beginning of the constructor. */ ctor_stmt = build_stmt (CTOR_STMT); CTOR_BEGIN_P (ctor_stmt) = 1; - add_tree (ctor_stmt); + add_stmt (ctor_stmt); /* And actually initialize the base-classes and members. */ emit_base_init (member_init_list, base_init_list); @@ -1299,7 +1290,7 @@ add_scope_stmt (begin_p, partial_p) } /* Add the new statement to the statement-tree. */ - add_tree (ss); + add_stmt (ss); return top; } @@ -1391,7 +1382,7 @@ finish_stmt_expr (rtl_expr) /* Remove the compound statement from the tree structure; it is now saved in the STMT_EXPR. */ - SET_LAST_STMT (rtl_expr); + last_tree = rtl_expr; TREE_CHAIN (last_tree) = NULL_TREE; /* If we created a statement-tree for this statement-expression, @@ -2223,103 +2214,6 @@ finish_typeof (expr) return TREE_TYPE (expr); } -/* Remove declarations of internal variables that are not used from a - stmt tree. To qualify, the variable must have a name and must have - a zero DECL_SOURCE_LINE. We tried to remove all variables for - which TREE_USED was false, but it turns out that there's tons of - variables for which TREE_USED is false but that are still in fact - used. */ - -static tree -prune_unused_decls (tp, walk_subtrees, data) - tree *tp; - int *walk_subtrees ATTRIBUTE_UNUSED; - void *data ATTRIBUTE_UNUSED; -{ - tree t = *tp; - - if (t == NULL_TREE) - { - *walk_subtrees = 0; - return NULL_TREE; - } - - if (TREE_CODE (t) == DECL_STMT) - { - tree d = DECL_STMT_DECL (t); - if (!TREE_USED (d) && DECL_NAME (d) && DECL_SOURCE_LINE (d) == 0) - { - *tp = TREE_CHAIN (t); - /* Recurse on the new value of tp, otherwise we will skip - the next statement. */ - return prune_unused_decls (tp, walk_subtrees, data); - } - } - else if (TREE_CODE (t) == SCOPE_STMT) - { - /* Remove all unused decls from the BLOCK of this SCOPE_STMT. */ - tree block = SCOPE_STMT_BLOCK (t); - - if (block) - { - tree *vp; - - for (vp = &BLOCK_VARS (block); *vp; ) - { - tree v = *vp; - if (! TREE_USED (v) && DECL_NAME (v) && DECL_SOURCE_LINE (v) == 0) - *vp = TREE_CHAIN (v); /* drop */ - else - vp = &TREE_CHAIN (v); /* advance */ - } - /* If there are now no variables, the entire BLOCK can be dropped. - (This causes SCOPE_NULLIFIED_P (t) to be true.) */ - if (BLOCK_VARS (block) == NULL_TREE) - SCOPE_STMT_BLOCK (t) = NULL_TREE; - } - } - return NULL_TREE; -} - -/* Create an empty statement tree rooted at T. */ - -void -begin_stmt_tree (t) - tree *t; -{ - /* 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); - SET_LAST_STMT (*t); - last_expr_type = NULL_TREE; -} - -/* Finish the statement tree rooted at T. */ - -void -finish_stmt_tree (t) - tree *t; -{ - tree stmt; - - /* Remove the fake extra statement added in begin_stmt_tree. */ - stmt = TREE_CHAIN (*t); - *t = stmt; - SET_LAST_STMT (NULL_TREE); - - /* Remove unused decls from the stmt tree. */ - walk_stmt_tree (t, prune_unused_decls, NULL); - - if (cfun) - { - /* The line-number recorded in the outermost statement in a function - is the line number of the end of the function. */ - STMT_LINENO (stmt) = lineno; - STMT_LINENO_FOR_FN_P (stmt) = 1; - } -} - /* We're about to expand T, a statement. Set up appropriate context for the substitution. */ @@ -2329,7 +2223,7 @@ prep_stmt (t) { if (!STMT_LINENO_FOR_FN_P (t)) lineno = STMT_LINENO (t); - current_stmt_tree->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t); + current_stmt_tree ()->stmts_are_full_exprs_p = STMT_IS_FULL_EXPR_P (t); } /* Generate RTL for the statement T, and its substatements, and any @@ -2453,7 +2347,8 @@ lang_expand_stmt (t) } /* Restore saved state. */ - current_stmt_tree->stmts_are_full_exprs_p = saved_stmts_are_full_exprs_p; + current_stmt_tree ()->stmts_are_full_exprs_p = + saved_stmts_are_full_exprs_p; /* Go on to the next statement in this scope. */ t = TREE_CHAIN (t); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 0f886692bbd..396b5c4f807 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -42,7 +42,6 @@ static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int)); static tree no_linkage_helper PARAMS ((tree *, int *, void *)); static tree build_srcloc PARAMS ((const char *, int)); static void mark_list_hash PARAMS ((void *)); -static int statement_code_p PARAMS ((enum tree_code)); static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *)); static tree cp_unsave_r PARAMS ((tree *, int *, void *)); static void cp_unsave PARAMS ((tree *)); @@ -50,6 +49,7 @@ static tree build_target_expr PARAMS ((tree, tree)); static tree count_trees_r PARAMS ((tree *, int *, void *)); static tree verify_stmt_tree_r PARAMS ((tree *, int *, void *)); static tree find_tree_r PARAMS ((tree *, int *, void *)); +extern int cp_statement_code_p PARAMS ((enum tree_code)); /* If REF is an lvalue, returns the kind of lvalue that REF is. Otherwise, returns clk_none. If TREAT_CLASS_RVALUES_AS_LVALUES is @@ -1071,33 +1071,18 @@ is_aggr_type_2 (t1, t2) /* Returns non-zero if CODE is the code for a statement. */ -static int -statement_code_p (code) +int +cp_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 SUBOBJECT: case CLEANUP_STMT: case START_CATCH_STMT: case CTOR_STMT: case SCOPE_STMT: case CTOR_INITIALIZER: - case CASE_LABEL: case RETURN_INIT: case TRY_BLOCK: case HANDLER: @@ -1223,9 +1208,9 @@ copy_template_template_parm (t, newargs) /* 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. The FLAGS govern the way in - which nodes are walked. If HTAB is non-NULL it is used to record - the nodes visited, and to avoid visiting a node more than once. */ + value returned by FUNC is returned. If HTAB is non-NULL it is used + to record the nodes visited, and to avoid visiting a node more than + once. */ tree walk_tree (tp, func, data, htab) @@ -1455,73 +1440,6 @@ walk_tree_without_duplicates (tp, func, data) return result; } -/* Like walk_tree, but only examines statement nodes. 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 -} - /* Called from count_trees via walk_tree. */ static tree @@ -2477,6 +2395,7 @@ init_tree () { make_lang_type_fn = cp_make_lang_type; lang_unsave = cp_unsave; + lang_statement_code_p = cp_statement_code_p; ggc_add_root (list_hash_table, ARRAY_SIZE (list_hash_table), sizeof (struct list_hash *), diff --git a/libio/editbuf.h b/libio/editbuf.h index c548133d88d..21574a96285 100644 --- a/libio/editbuf.h +++ b/libio/editbuf.h @@ -1,5 +1,5 @@ /* This is part of libio/iostream, providing -*- C++ -*- input/output. -Copyright (C) 1993 Free Software Foundation +Copyright (C) 1993, 2000 Free Software Foundation This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or modify it under the diff --git a/libobjc/encoding.c b/libobjc/encoding.c index 7841196cd5e..ea60b7b3c58 100644 --- a/libobjc/encoding.c +++ b/libobjc/encoding.c @@ -1,5 +1,5 @@ /* Encoding of types for Objective C. - Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1993, 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc. Contributed by Kresten Krab Thorup Bitfield support by Ovidiu Predescu