summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-26 21:11:23 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>2004-06-26 21:11:23 +0000
commit7dd3724184cd6a9e911c4112d0942729405d0a5d (patch)
treeec365de72a39a5ef2d0a252b8496e9199f69fb3d
parent6b87a81c933c4fc156e9ea1c79d5dad399caef1f (diff)
downloadgcc-7dd3724184cd6a9e911c4112d0942729405d0a5d.tar.gz
2004-06-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* c-common.c (c_safe_from_p, c_walk_subtrees): Deleted. * c-common.def (DECL_STMT): Remove. * c-common.h (DECL_STMT_DECL): Deleted. (COMPOUNT_LITERAL_EXPR_DECL): Use DECL_EXPR_DECL. (c_safe_from_p, c_walk_subtrees): Deleted. * c-decl.c, c-parse.in, c-pretty-print.c: DECL_STMT now DECL_EXPR. * c-dump.c (c_dump_tree, case DECL_STMT): Deleted. * c-gimplify.c (gimplify_decl_stmt): Deleted. (gimplify_compound_literal_expr): Use DECL_EXPR_DECL and gimplify_and_add. (c_gimplify_expr, case DECL_EXPR): New case. (c_gimplify_expr, case DECL_STMT): Deleted. * c-lang.c (LANG_HOOKS_SAFE_FROM_P): Likewise. (LANG_HOOKS_TREE_INLINING_WALK_SUBTREES): Likewise. * expr.c (safe_from_p, case 's'): New case. * gimplify.c (gimplify_decl_expr): New function. (gimplify_expr, case DECL_EXPR): New case. * tree-inline.c (walk_tree): Walk into all fields of a type and decl only if they are in a DECL_EXPR. (mark_local_for_remap_r): Minor code cleanup. * tree-outof-ssa.c (discover_nonconstant_array_refs_r): Add else. * tree.c (has_cleanups, case DECL_EXPR): New case. * tree.def (DECL_EXPR): New code. * tree.h (DECL_EXPR_DECL): New macro. * objc/objc-lang.c (LANG_HOOKS_SAFE_FROM_P): Deleted. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83721 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/c-common.c69
-rw-r--r--gcc/c-common.def4
-rw-r--r--gcc/c-common.h12
-rw-r--r--gcc/c-decl.c8
-rw-r--r--gcc/c-dump.c5
-rw-r--r--gcc/c-gimplify.c96
-rw-r--r--gcc/c-lang.c5
-rw-r--r--gcc/c-parse.in6
-rw-r--r--gcc/c-pretty-print.c12
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/call.c2
-rw-r--r--gcc/cp/cp-lang.c2
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/cxx-pretty-print.c2
-rw-r--r--gcc/cp/decl.c14
-rw-r--r--gcc/cp/decl2.c2
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/name-lookup.c2
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/pt.c8
-rw-r--r--gcc/cp/semantics.c16
-rw-r--r--gcc/cp/tree.c19
-rw-r--r--gcc/expr.c8
-rw-r--r--gcc/gimplify.c72
-rw-r--r--gcc/objc/objc-lang.c2
-rw-r--r--gcc/tree-inline.c211
-rw-r--r--gcc/tree-outof-ssa.c2
-rw-r--r--gcc/tree.c4
-rw-r--r--gcc/tree.def3
-rw-r--r--gcc/tree.h4
30 files changed, 270 insertions, 334 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 0edbd5f7925..f48ac09fbdd 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -3718,28 +3718,6 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode,
}
}
-/* Hook used by safe_from_p to handle language-specific tree codes. */
-
-int
-c_safe_from_p (rtx target, tree exp)
-{
- /* We can see statements here when processing the body of a
- statement-expression. For a declaration statement declaring a
- variable, look at the variable's initializer. */
- if (TREE_CODE (exp) == DECL_STMT)
- {
- tree decl = DECL_STMT_DECL (exp);
-
- if (TREE_CODE (decl) == VAR_DECL
- && DECL_INITIAL (decl)
- && !safe_from_p (target, DECL_INITIAL (decl), /*top_p=*/0))
- return 0;
- }
-
- /* Assume everything else is safe. */
- return 1;
-}
-
/* Hook used by unsafe_for_reeval to handle language-specific tree codes. */
int
@@ -5125,53 +5103,6 @@ check_function_arguments_recurse (void (*callback)
(*callback) (ctx, param, param_num);
}
-/* C implementation of lang_hooks.tree_inlining.walk_subtrees. Tracks the
- locus from EXPR_LOCUS and handles DECL_STMT specially. */
-
-tree
-c_walk_subtrees (tree *tp, int *walk_subtrees_p ATTRIBUTE_UNUSED,
- walk_tree_fn func, void *data, void *htab)
-{
- enum tree_code code = TREE_CODE (*tp);
- location_t save_locus;
- tree result;
-
-#define WALK_SUBTREE(NODE) \
- do \
- { \
- result = walk_tree (&(NODE), func, data, htab); \
- if (result) goto out; \
- } \
- while (0)
-
- if (code != DECL_STMT)
- return NULL_TREE;
-
- /* Set input_location here so we get the right instantiation context
- if we call instantiate_decl from inlinable_function_p. */
- save_locus = input_location;
- if (EXPR_LOCUS (*tp))
- input_location = *EXPR_LOCUS (*tp);
-
- /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
- into declarations that are just mentioned, rather than
- declared; they don't really belong to this part of the tree.
- And, we can see cycles: the initializer for a declaration can
- refer to the declaration itself. */
- WALK_SUBTREE (DECL_INITIAL (DECL_STMT_DECL (*tp)));
- WALK_SUBTREE (DECL_SIZE (DECL_STMT_DECL (*tp)));
- WALK_SUBTREE (DECL_SIZE_UNIT (DECL_STMT_DECL (*tp)));
- WALK_SUBTREE (TREE_CHAIN (*tp));
- *walk_subtrees_p = 0;
-
- /* We didn't find what we were looking for. */
- out:
- input_location = save_locus;
- return result;
-
-#undef WALK_SUBTREE
-}
-
/* Function to help qsort sort FIELD_DECLs by name order. */
int
diff --git a/gcc/c-common.def b/gcc/c-common.def
index 5d8c237831d..fa45ad0526a 100644
--- a/gcc/c-common.def
+++ b/gcc/c-common.def
@@ -33,10 +33,6 @@ DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1)
obtain the expression. */
DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1)
-/* Used to represent a local declaration. The operand is
- DECL_STMT_DECL. */
-DEFTREECODE (DECL_STMT, "decl_stmt", 'e', 1)
-
/* Used to represent a `for' statement. The operands are
FOR_INIT_STMT, FOR_COND, FOR_EXPR, and FOR_BODY, respectively. */
DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4)
diff --git a/gcc/c-common.h b/gcc/c-common.h
index ae5fbb690bc..454d4899237 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -733,10 +733,6 @@ extern void finish_file (void);
#define SWITCH_TYPE(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 2)
-/* DECL_STMT accessor. This gives access to the DECL associated with
- the given declaration statement. */
-#define DECL_STMT_DECL(NODE) TREE_OPERAND (DECL_STMT_CHECK (NODE), 0)
-
/* STMT_EXPR accessor. */
#define STMT_EXPR_STMT(NODE) TREE_OPERAND (STMT_EXPR_CHECK (NODE), 0)
@@ -748,7 +744,7 @@ extern void finish_file (void);
#define COMPOUND_LITERAL_EXPR_DECL_STMT(NODE) \
TREE_OPERAND (COMPOUND_LITERAL_EXPR_CHECK (NODE), 0)
#define COMPOUND_LITERAL_EXPR_DECL(NODE) \
- DECL_STMT_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE))
+ DECL_EXPR_DECL (COMPOUND_LITERAL_EXPR_DECL_STMT (NODE))
#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM,
@@ -761,7 +757,7 @@ enum c_tree_code {
#undef DEFTREECODE
#define c_common_stmt_codes \
- EXPR_STMT, DECL_STMT, FOR_STMT, \
+ EXPR_STMT, FOR_STMT, \
WHILE_STMT, DO_STMT, \
BREAK_STMT, CONTINUE_STMT, SWITCH_STMT
@@ -844,8 +840,6 @@ extern int vector_types_convertible_p (tree t1, tree t2);
extern rtx c_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
-extern int c_safe_from_p (rtx, tree);
-
extern int c_staticp (tree);
extern int c_common_unsafe_for_reeval (tree);
@@ -872,8 +866,6 @@ extern void dump_time_statistics (void);
extern bool c_dump_tree (void *, tree);
-extern tree c_walk_subtrees (tree*, int*, walk_tree_fn, void*, void*);
-
extern void c_warn_unused_result (tree *);
extern void verify_sequence_points (tree);
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 7aeba0896c2..4591ec95d7a 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -2943,7 +2943,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
}
if (TREE_CODE (decl) != FUNCTION_DECL)
- add_stmt (build_stmt (DECL_STMT, decl));
+ add_stmt (build_stmt (DECL_EXPR, decl));
}
if (!DECL_FILE_SCOPE_P (decl))
@@ -2970,7 +2970,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
{
if (!DECL_FILE_SCOPE_P (decl)
&& variably_modified_type_p (TREE_TYPE (decl)))
- add_stmt (build_stmt (DECL_STMT, decl));
+ add_stmt (build_stmt (DECL_EXPR, decl));
rest_of_decl_compilation (decl, NULL, DECL_FILE_SCOPE_P (decl), 0);
}
@@ -3072,7 +3072,7 @@ build_compound_literal (tree type, tree init)
{
/* We do not use start_decl here because we have a type, not a declarator;
and do not use finish_decl because the decl should be stored inside
- the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_STMT. */
+ the COMPOUND_LITERAL_EXPR rather than added elsewhere as a DECL_EXPR. */
tree decl = build_decl (VAR_DECL, NULL_TREE, type);
tree complit;
tree stmt;
@@ -3096,7 +3096,7 @@ build_compound_literal (tree type, tree init)
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
return error_mark_node;
- stmt = build_stmt (DECL_STMT, decl);
+ stmt = build_stmt (DECL_EXPR, decl);
complit = build1 (COMPOUND_LITERAL_EXPR, TREE_TYPE (decl), stmt);
TREE_SIDE_EFFECTS (complit) = 1;
diff --git a/gcc/c-dump.c b/gcc/c-dump.c
index 91acac844c7..73b973e235a 100644
--- a/gcc/c-dump.c
+++ b/gcc/c-dump.c
@@ -60,11 +60,6 @@ c_dump_tree (void *dump_info, tree t)
dump_stmt (di, t);
break;
- case DECL_STMT:
- dump_stmt (di, t);
- dump_child ("decl", DECL_STMT_DECL (t));
- break;
-
case DO_STMT:
dump_stmt (di, t);
dump_child ("body", DO_BODY (t));
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
index 811365e2746..d899ba3593c 100644
--- a/gcc/c-gimplify.c
+++ b/gcc/c-gimplify.c
@@ -465,90 +465,17 @@ gimplify_switch_stmt (tree *stmt_p)
return GS_ALL_DONE;
}
-/* Gimplifies a DECL_STMT node *STMT_P by making any necessary allocation
- and initialization explicit. */
-
-static enum gimplify_status
-gimplify_decl_stmt (tree *stmt_p)
-{
- tree stmt = *stmt_p;
- tree decl = DECL_STMT_DECL (stmt);
-
- *stmt_p = NULL_TREE;
-
- if (TREE_TYPE (decl) == error_mark_node)
- return GS_ERROR;
-
- if (TREE_CODE (decl) == TYPE_DECL)
- gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
-
- else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
- {
- tree init = DECL_INITIAL (decl);
-
- if (!TREE_CONSTANT (DECL_SIZE (decl)))
- {
- /* This is a variable-sized decl. Simplify its size and mark it
- for deferred expansion. Note that mudflap depends on the format
- of the emitted code: see mx_register_decls(). */
-
- tree t, args;
-
- gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
- gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
- gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
-
- args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL);
- t = build_fold_addr_expr (decl);
- args = tree_cons (NULL, t, args);
- t = implicit_built_in_decls[BUILT_IN_STACK_ALLOC];
- t = build_function_call_expr (t, args);
-
- gimplify_and_add (t, stmt_p);
- DECL_DEFER_OUTPUT (decl) = 1;
- }
-
- if (init && init != error_mark_node)
- {
- if (!TREE_STATIC (decl))
- {
- /* Do not warn about int x = x; as it is a GCC extension
- to turn off this warning but only if warn_init_self
- is zero. */
- if (init == decl && !warn_init_self)
- TREE_NO_WARNING (decl) = 1;
-
- DECL_INITIAL (decl) = NULL_TREE;
- init = build (MODIFY_EXPR, void_type_node, decl, init);
- gimplify_and_add (init, stmt_p);
- }
- else
- /* We must still examine initializers for static variables
- as they may contain a label address. */
- walk_tree (&init, force_labels_r, NULL, NULL);
- }
-
- /* This decl isn't mentioned in the enclosing block, so add it to the
- list of temps. FIXME it seems a bit of a kludge to say that
- anonymous artificial vars aren't pushed, but everything else is. */
- if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
- gimple_add_tmp_var (decl);
- }
-
- return GS_ALL_DONE;
-}
-
/* Gimplification of expression trees. */
/* Gimplify a C99 compound literal expression. This just means adding the
- DECL_STMT before the current EXPR_STMT and using its anonymous decl
+ DECL_EXPR before the current EXPR_STMT and using its anonymous decl
instead. */
static enum gimplify_status
gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
{
tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
- tree decl = DECL_STMT_DECL (decl_s);
+ tree decl = DECL_EXPR_DECL (decl_s);
/* This decl isn't mentioned in the enclosing block, so add it to the
list of temps. FIXME it seems a bit of a kludge to say that
@@ -556,8 +483,7 @@ gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
if (DECL_NAME (decl) == NULL_TREE)
gimple_add_tmp_var (decl);
- gimplify_decl_stmt (&decl_s);
- append_to_statement_list (decl_s, pre_p);
+ gimplify_and_add (decl_s, pre_p);
*expr_p = decl;
return GS_OK;
}
@@ -571,6 +497,19 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
switch (code)
{
+ case DECL_EXPR:
+ /* This is handled mostly by gimplify.c, but we have to deal with
+ not warning about int x = x; as it is a GCC extension to turn off
+ this warning but only if warn_init_self is zero. */
+ if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
+ && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
+ && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
+ && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p))
+ == DECL_EXPR_DECL (*expr_p))
+ && !warn_init_self)
+ TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
+ return GS_UNHANDLED;
+
case COMPOUND_LITERAL_EXPR:
return gimplify_compound_literal_expr (expr_p, pre_p);
@@ -589,9 +528,6 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
case EXPR_STMT:
return gimplify_expr_stmt (expr_p);
- case DECL_STMT:
- return gimplify_decl_stmt (expr_p);
-
case CONTINUE_STMT:
*expr_p = build_bc_goto (bc_continue);
return GS_ALL_DONE;
diff --git a/gcc/c-lang.c b/gcc/c-lang.c
index 74b04ebc17a..03b05b26efa 100644
--- a/gcc/c-lang.c
+++ b/gcc/c-lang.c
@@ -60,8 +60,6 @@ enum c_language_kind c_language = clk_c;
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
-#undef LANG_HOOKS_SAFE_FROM_P
-#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
#undef LANG_HOOKS_EXPAND_EXPR
#define LANG_HOOKS_EXPAND_EXPR c_expand_expr
#undef LANG_HOOKS_EXPAND_DECL
@@ -103,9 +101,6 @@ enum c_language_kind c_language = clk_c;
#undef LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE
#define LANG_HOOKS_FORMAT_ATTRIBUTE_TABLE c_common_format_attribute_table
-#undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
-#define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \
- c_walk_subtrees
#undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
#define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
c_cannot_inline_tree_fn
diff --git a/gcc/c-parse.in b/gcc/c-parse.in
index a96241a3e5c..96468279245 100644
--- a/gcc/c-parse.in
+++ b/gcc/c-parse.in
@@ -1537,7 +1537,7 @@ nested_function:
add_stmt ($6);
finish_function ();
pop_function_context ();
- add_stmt (build_stmt (DECL_STMT, decl)); }
+ add_stmt (build_stmt (DECL_EXPR, decl)); }
;
notype_nested_function:
@@ -1567,7 +1567,7 @@ notype_nested_function:
add_stmt ($6);
finish_function ();
pop_function_context ();
- add_stmt (build_stmt (DECL_STMT, decl)); }
+ add_stmt (build_stmt (DECL_EXPR, decl)); }
;
/* Any kind of declarator (thus, all declarators allowed
@@ -2016,7 +2016,7 @@ label_decl:
{
tree label = declare_label (TREE_VALUE (link));
C_DECLARED_LABEL_FLAG (label) = 1;
- add_stmt (build_stmt (DECL_STMT, label));
+ add_stmt (build_stmt (DECL_EXPR, label));
}
}
;
diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c
index 4d0b06d5de9..fd3ef82ac02 100644
--- a/gcc/c-pretty-print.c
+++ b/gcc/c-pretty-print.c
@@ -261,6 +261,13 @@ pp_c_pointer (c_pretty_printer *pp, tree t)
pp_c_type_qualifier_list (pp, t);
break;
+ /* ??? This node is now in GENERIC and so shouldn't be here. But
+ we'll fix that later. */
+ case DECL_EXPR:
+ pp_declaration (pp, DECL_EXPR_DECL (t));
+ pp_needs_newline (pp) = true;
+ break;
+
default:
pp_unsupported_tree (pp, t);
}
@@ -1982,11 +1989,6 @@ pp_c_statement (c_pretty_printer *pp, tree stmt)
pp_needs_newline (pp) = true;
break;
- case DECL_STMT:
- pp_declaration (pp, DECL_STMT_DECL (stmt));
- pp_needs_newline (pp) = true;
- break;
-
default:
dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
break;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f5d903cdb6f..6812f8b86a3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2004-06-26 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * call.c, cp-tree.h, cxx-pretty-print.c, decl.c, decl2.c:
+ Rename DECL_STMT to DECL_EXPR.
+ * init.c, name-lookup.c, parser.c, pt.c, semantics.c: Likewise.
+ * cp-lang.c (LANG_HOOKS_SAFE_FROM_P): Deleted.
+ * tree.c (cp_walk_subtrees): Don't call c_walk_subtrees.
+
2004-06-26 Jan Hubicka <jh@suse.cz>
PR C++/14865
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e02fa17e403..5cbf808d8ec 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -6468,7 +6468,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup)
init = build (INIT_EXPR, type, var, expr);
if (at_function_scope_p ())
{
- add_decl_stmt (var);
+ add_decl_expr (var);
*cleanup = cxx_maybe_build_cleanup (var);
/* We must be careful to destroy the temporary only
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index 5af5b97333d..98b94581793 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -72,8 +72,6 @@ static void cxx_initialize_diagnostics (diagnostic_context *);
#define LANG_HOOKS_EXPAND_EXPR cxx_expand_expr
#undef LANG_HOOKS_EXPAND_DECL
#define LANG_HOOKS_EXPAND_DECL c_expand_decl
-#undef LANG_HOOKS_SAFE_FROM_P
-#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
#undef LANG_HOOKS_PARSE_FILE
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 143c931aa3a..f2ebb649988 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4147,7 +4147,7 @@ extern void pop_to_parent_deferring_access_checks (void);
extern void perform_deferred_access_checks (void);
extern void perform_or_defer_access_check (tree, tree);
extern void init_cp_semantics (void);
-extern void add_decl_stmt (tree);
+extern void add_decl_expr (tree);
extern tree finish_expr_stmt (tree);
extern tree begin_if_stmt (void);
extern void finish_if_stmt_cond (tree, tree);
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index cd086117634..c1337a925ea 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -1446,7 +1446,7 @@ pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
static void
pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
{
- t = DECL_STMT_DECL (t);
+ t = DECL_EXPR_DECL (t);
pp_cxx_type_specifier_seq (pp, t);
if (TYPE_P (t))
pp_cxx_abstract_declarator (pp, t);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5f7fb81ee06..9d2aedb8123 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3873,8 +3873,8 @@ grok_reference_init (tree decl, tree type, tree init, tree *cleanup)
/* Convert INIT to the reference type TYPE. This may involve the
creation of a temporary, whose lifetime must be the same as that
- of the reference. If so, a DECL_STMT for the temporary will be
- added just after the DECL_STMT for DECL. That's why we don't set
+ of the reference. If so, a DECL_EXPR for the temporary will be
+ added just after the DECL_EXPR for DECL. That's why we don't set
DECL_INITIAL for local references (instead assigning to them
explicitly); we need to allow the temporary to be initialized
first. */
@@ -4527,7 +4527,7 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
return;
/* We defer emission of local statics until the corresponding
- DECL_STMT is expanded. */
+ DECL_EXPR is expanded. */
defer_p = DECL_FUNCTION_SCOPE_P (decl) || DECL_VIRTUAL_P (decl);
/* We try to defer namespace-scope static constants so that they are
@@ -4702,7 +4702,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
{
/* Add this declaration to the statement-tree. */
if (at_function_scope_p ())
- add_decl_stmt (decl);
+ add_decl_expr (decl);
if (init && DECL_INITIAL (decl))
DECL_INITIAL (decl) = init;
@@ -4808,10 +4808,10 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
}
/* Add this declaration to the statement-tree. This needs to happen
- after the call to check_initializer so that the DECL_STMT for a
- reference temp is added before the DECL_STMT for the reference itself. */
+ after the call to check_initializer so that the DECL_EXPR for a
+ reference temp is added before the DECL_EXPR for the reference itself. */
if (at_function_scope_p ())
- add_decl_stmt (decl);
+ add_decl_expr (decl);
if (TREE_CODE (decl) == VAR_DECL)
layout_var_decl (decl);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index ae310768b75..142bd4b7f87 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1227,7 +1227,7 @@ finish_anon_union (tree anon_union_decl)
pushdecl (anon_union_decl);
if (building_stmt_tree ()
&& at_function_scope_p ())
- add_decl_stmt (anon_union_decl);
+ add_decl_expr (anon_union_decl);
else if (!processing_template_decl)
rest_of_decl_compilation (anon_union_decl, NULL,
toplevel_bindings_p (), at_eof);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index ceb6c4bc32e..425a853186d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -2360,7 +2360,7 @@ get_temp_regvar (tree type, tree init)
tree decl;
decl = create_temporary_var (type);
- add_decl_stmt (decl);
+ add_decl_expr (decl);
finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 1b755c92320..b650d7443d1 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -2269,7 +2269,7 @@ do_local_using_decl (tree decl, tree scope, tree name)
if (building_stmt_tree ()
&& at_function_scope_p ())
- add_decl_stmt (decl);
+ add_decl_expr (decl);
oldval = lookup_name_current_level (name);
oldtype = lookup_type_current_level (name);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 346ad1cabcf..e6b1f920815 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10695,7 +10695,7 @@ cp_parser_init_declarator (cp_parser* parser,
/* Leave the SCOPE, now that we have processed the initializer. It
is important to do this before calling cp_finish_decl because it
- makes decisions about whether to create DECL_STMTs or not based
+ makes decisions about whether to create DECL_EXPRs or not based
on the current scope. */
if (pop_p)
pop_scope (scope);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index a0f140f13d0..a1142f3b358 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -4587,7 +4587,7 @@ struct pair_fn_data
/* Called from for_each_template_parm via walk_tree. */
static tree
-for_each_template_parm_r (tree* tp, int* walk_subtrees, void* d)
+for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
{
tree t = *tp;
struct pair_fn_data *pfd = (struct pair_fn_data *) d;
@@ -7764,12 +7764,12 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
args, complain, in_decl));
break;
- case DECL_STMT:
+ case DECL_EXPR:
{
tree decl;
tree init;
- decl = DECL_STMT_DECL (t);
+ decl = DECL_EXPR_DECL (t);
if (TREE_CODE (decl) == LABEL_DECL)
finish_label_decl (DECL_NAME (decl));
else if (TREE_CODE (decl) == USING_DECL)
@@ -7825,7 +7825,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
}
- /* A DECL_STMT can also be used as an expression, in the condition
+ /* A DECL_EXPR can also be used as an expression, in the condition
clause of an if/for/while construct. */
return decl;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c9f66d9dc1c..b4894607201 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -316,9 +316,9 @@ maybe_cleanup_point_expr (tree expr)
/* Create a declaration statement for the declaration given by the DECL. */
void
-add_decl_stmt (tree decl)
+add_decl_expr (tree decl)
{
- tree r = build_stmt (DECL_STMT, decl);
+ tree r = build_stmt (DECL_EXPR, decl);
if (DECL_INITIAL (decl))
r = maybe_cleanup_point_expr (r);
add_stmt (r);
@@ -382,7 +382,7 @@ push_cleanup (tree decl, tree cleanup, bool eh_only)
/* Begin a conditional that might contain a declaration. When generating
normal code, we want the declaration to appear before the statement
containing the conditional. When generating template code, we want the
- conditional to be rendered as the raw DECL_STMT. */
+ conditional to be rendered as the raw DECL_EXPR. */
static void
begin_cond (tree *cond_p)
@@ -399,7 +399,7 @@ finish_cond (tree *cond_p, tree expr)
if (processing_template_decl)
{
tree cond = pop_stmt_list (*cond_p);
- if (TREE_CODE (cond) == DECL_STMT)
+ if (TREE_CODE (cond) == DECL_EXPR)
expr = cond;
}
*cond_p = expr;
@@ -1141,7 +1141,7 @@ void
finish_label_decl (tree name)
{
tree decl = declare_local_label (name);
- add_decl_stmt (decl);
+ add_decl_expr (decl);
}
/* When DECL goes out of scope, make sure that CLEANUP is executed. */
@@ -2950,10 +2950,10 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
else if (TREE_CODE (*tp) == CLEANUP_STMT
&& CLEANUP_DECL (*tp) == dp->var)
CLEANUP_EH_ONLY (*tp) = 1;
- /* Replace the DECL_STMT for the NRV with an initialization of the
+ /* Replace the DECL_EXPR for the NRV with an initialization of the
RESULT_DECL, if needed. */
- else if (TREE_CODE (*tp) == DECL_STMT
- && DECL_STMT_DECL (*tp) == dp->var)
+ else if (TREE_CODE (*tp) == DECL_EXPR
+ && DECL_EXPR_DECL (*tp) == dp->var)
{
tree init;
if (DECL_INITIAL (dp->var)
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 527e9c27d50..4ae07798dee 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1962,14 +1962,11 @@ cp_build_type_attribute_variant (tree type, tree attributes)
}
/* Apply FUNC to all language-specific sub-trees of TP in a pre-order
- traversal. Called from walk_tree(). */
+ traversal. Called from walk_tree. */
tree
-cp_walk_subtrees (tree* tp,
- int* walk_subtrees_p,
- walk_tree_fn func,
- void* data,
- void* htab)
+cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
+ void *data, void *htab)
{
enum tree_code code = TREE_CODE (*tp);
location_t save_locus;
@@ -2030,7 +2027,7 @@ cp_walk_subtrees (tree* tp,
default:
input_location = save_locus;
- return c_walk_subtrees (tp, walk_subtrees_p, func, data, htab);
+ return NULL_TREE;
}
/* We didn't find what we were looking for. */
@@ -2201,7 +2198,7 @@ init_tree (void)
list_hash_table = htab_create_ggc (31, list_hash, list_hash_eq, NULL);
}
-/* Called via walk_tree. If *TP points to a DECL_STMT for a local
+/* Called via walk_tree. If *TP points to a DECL_EXPR for a local
declaration, copies the declaration and enters it in the splay_tree
pointed to by DATA (which is really a `splay_tree *'). */
@@ -2215,9 +2212,9 @@ mark_local_for_remap_r (tree* tp,
tree decl;
- if (TREE_CODE (t) == DECL_STMT
- && nonstatic_local_decl_p (DECL_STMT_DECL (t)))
- decl = DECL_STMT_DECL (t);
+ if (TREE_CODE (t) == DECL_EXPR
+ && nonstatic_local_decl_p (DECL_EXPR_DECL (t)))
+ decl = DECL_EXPR_DECL (t);
else if (TREE_CODE (t) == LABEL_EXPR)
decl = LABEL_EXPR_LABEL (t);
else if (TREE_CODE (t) == TARGET_EXPR
diff --git a/gcc/expr.c b/gcc/expr.c
index 259eac1c989..a92eab6f9d9 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -6002,6 +6002,14 @@ safe_from_p (rtx x, tree exp, int top_p)
else
return 0;
+ case 's':
+ /* The only case we look at here is the DECL_INITIAL inside a
+ DECL_EXPR. */
+ return (TREE_CODE (exp) != DECL_EXPR
+ || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL
+ || !DECL_INITIAL (DECL_EXPR_DECL (exp))
+ || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), 0));
+
case '2':
case '<':
if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 347e946e265..7ef88b565b3 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -660,7 +660,7 @@ copy_if_shared_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
/* Special-case BIND_EXPR. We should never be copying these, therefore
we can omit examining BIND_EXPR_VARS. Which also avoids problems with
double processing of the DECL_INITIAL, which could be seen via both
- the BIND_EXPR_VARS and a DECL_STMT. */
+ the BIND_EXPR_VARS and a DECL_EXPR. */
else if (code == BIND_EXPR)
{
if (TREE_VISITED (t))
@@ -1004,6 +1004,72 @@ gimplify_return_expr (tree stmt, tree *pre_p)
return GS_ALL_DONE;
}
+/* Gimplifies a DECL_EXPR node *STMT_P by making any necessary allocation
+ and initialization explicit. */
+
+static enum gimplify_status
+gimplify_decl_expr (tree *stmt_p)
+{
+ tree stmt = *stmt_p;
+ tree decl = DECL_EXPR_DECL (stmt);
+
+ *stmt_p = NULL_TREE;
+
+ if (TREE_TYPE (decl) == error_mark_node)
+ return GS_ERROR;
+
+ else if (TREE_CODE (decl) == TYPE_DECL)
+ gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+
+ else if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
+ {
+ tree init = DECL_INITIAL (decl);
+
+ if (!TREE_CONSTANT (DECL_SIZE (decl)))
+ {
+ /* This is a variable-sized decl. Simplify its size and mark it
+ for deferred expansion. Note that mudflap depends on the format
+ of the emitted code: see mx_register_decls(). */
+ tree t, args;
+
+ gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+ gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
+ gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
+
+ args = tree_cons (NULL, DECL_SIZE_UNIT (decl), NULL);
+ t = build_fold_addr_expr (decl);
+ args = tree_cons (NULL, t, args);
+ t = implicit_built_in_decls[BUILT_IN_STACK_ALLOC];
+ t = build_function_call_expr (t, args);
+
+ gimplify_and_add (t, stmt_p);
+ DECL_DEFER_OUTPUT (decl) = 1;
+ }
+
+ if (init && init != error_mark_node)
+ {
+ if (!TREE_STATIC (decl))
+ {
+ DECL_INITIAL (decl) = NULL_TREE;
+ init = build (MODIFY_EXPR, void_type_node, decl, init);
+ gimplify_and_add (init, stmt_p);
+ }
+ else
+ /* We must still examine initializers for static variables
+ as they may contain a label address. */
+ walk_tree (&init, force_labels_r, NULL, NULL);
+ }
+
+ /* This decl isn't mentioned in the enclosing block, so add it to the
+ list of temps. FIXME it seems a bit of a kludge to say that
+ anonymous artificial vars aren't pushed, but everything else is. */
+ if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
+ gimple_add_tmp_var (decl);
+ }
+
+ return GS_ALL_DONE;
+}
+
/* Gimplify a LOOP_EXPR. Normally this just involves gimplifying the body
and replacing the LOOP_EXPR with goto, but if the loop contains an
EXIT_EXPR, we need to append a label for it to jump to. */
@@ -3521,6 +3587,10 @@ gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p,
*expr_p = DECL_INITIAL (*expr_p);
break;
+ case DECL_EXPR:
+ ret = gimplify_decl_expr (expr_p);
+ break;
+
case EXC_PTR_EXPR:
/* FIXME make this a decl. */
ret = GS_ALL_DONE;
diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c
index f786369521c..aa0f388e843 100644
--- a/gcc/objc/objc-lang.c
+++ b/gcc/objc/objc-lang.c
@@ -53,8 +53,6 @@ enum c_language_kind c_language = clk_objc;
#define LANG_HOOKS_POST_OPTIONS c_common_post_options
#undef LANG_HOOKS_GET_ALIAS_SET
#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set
-#undef LANG_HOOKS_SAFE_FROM_P
-#define LANG_HOOKS_SAFE_FROM_P c_safe_from_p
#undef LANG_HOOKS_PARSE_FILE
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
#undef LANG_HOOKS_CLEAR_BINDING_STACK
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index e9bb3001555..ac5256220bc 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -2032,10 +2032,63 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
if (result || ! walk_subtrees)
return result;
- if (code != EXIT_BLOCK_EXPR
- && code != SAVE_EXPR
- && code != BIND_EXPR
- && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
+ /* If this is a DECL_EXPR, walk into various fields of the type or variable
+ that it's defining. We only want to walk into these fields of a decl
+ or type in this case.
+
+ ??? Precisely which fields of types that we are supposed to walk in
+ this case vs. the normal case aren't well defined. */
+ if (code == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (*tp)) != ERROR_MARK
+ && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
+ {
+ tree decl = DECL_EXPR_DECL (*tp);
+ tree type = TREE_TYPE (decl);
+
+ /* Walk into fields of the DECL if it's not a type, then into fields
+ of the type in both cases. */
+
+ if (TREE_CODE (decl) != TYPE_DECL
+ && TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != PARM_DECL)
+ {
+ WALK_SUBTREE (DECL_INITIAL (decl));
+ WALK_SUBTREE (DECL_SIZE (decl));
+ WALK_SUBTREE (DECL_SIZE_UNIT (decl));
+ }
+
+ /* First do the common fields via recursion, then the fields we only
+ do when we are declaring the type or object. */
+ WALK_SUBTREE (type);
+ WALK_SUBTREE (TYPE_SIZE (type));
+ WALK_SUBTREE (TYPE_SIZE_UNIT (type));
+
+ /* If this is a record type, also walk the fields. */
+ if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == QUAL_UNION_TYPE)
+ {
+ tree field;
+
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ /* We'd like to look at the type of the field, but we can easily
+ get infinite recursion. So assume it's pointed to elsewhere
+ in the tree. Also, ignore things that aren't fields. */
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
+
+ WALK_SUBTREE (DECL_FIELD_OFFSET (field));
+ WALK_SUBTREE (DECL_SIZE (field));
+ WALK_SUBTREE (DECL_SIZE_UNIT (field));
+ if (TREE_CODE (type) == QUAL_UNION_TYPE)
+ WALK_SUBTREE (DECL_QUALIFIER (field));
+ }
+ }
+ }
+
+ else if (code != EXIT_BLOCK_EXPR
+ && code != SAVE_EXPR
+ && code != BIND_EXPR
+ && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
{
int i, len;
@@ -2068,24 +2121,8 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
#endif
}
- /* Look inside the sizes of decls, but we don't ever use the values for
- FIELD_DECL and RESULT_DECL, so ignore them. */
- else if (TREE_CODE_CLASS (code) == 'd'
- && code != FIELD_DECL && code != RESULT_DECL)
- {
- WALK_SUBTREE (DECL_SIZE (*tp));
- WALK_SUBTREE (DECL_SIZE_UNIT (*tp));
- WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
- }
else
{
- if (TREE_CODE_CLASS (code) == 't')
- {
- WALK_SUBTREE (TYPE_SIZE (*tp));
- WALK_SUBTREE (TYPE_SIZE_UNIT (*tp));
- /* Also examine various special fields, below. */
- }
-
/* Not one of the easy cases. We must explicitly go through the
children. */
switch (code)
@@ -2107,12 +2144,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
above. */
break;
- case POINTER_TYPE:
- case REFERENCE_TYPE:
- case COMPLEX_TYPE:
- WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
- break;
-
case TREE_LIST:
WALK_SUBTREE (TREE_VALUE (*tp));
WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
@@ -2140,6 +2171,44 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
case CONSTRUCTOR:
WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
+ case EXIT_BLOCK_EXPR:
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1));
+
+ case SAVE_EXPR:
+ WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
+
+ case BIND_EXPR:
+ {
+ tree decl;
+ for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl))
+ {
+ /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
+ into declarations that are just mentioned, rather than
+ declared; they don't really belong to this part of the tree.
+ And, we can see cycles: the initializer for a declaration
+ can refer to the declaration itself. */
+ WALK_SUBTREE (DECL_INITIAL (decl));
+ WALK_SUBTREE (DECL_SIZE (decl));
+ WALK_SUBTREE (DECL_SIZE_UNIT (decl));
+ WALK_SUBTREE (TREE_TYPE (decl));
+ }
+ WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
+ }
+
+ case STATEMENT_LIST:
+ {
+ tree_stmt_iterator i;
+ for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
+ WALK_SUBTREE (*tsi_stmt_ptr (i));
+ }
+ break;
+
+ case POINTER_TYPE:
+ case REFERENCE_TYPE:
+ case COMPLEX_TYPE:
+ WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
+ break;
+
case METHOD_TYPE:
WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
@@ -2148,38 +2217,14 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
case FUNCTION_TYPE:
WALK_SUBTREE (TREE_TYPE (*tp));
{
- tree arg = TYPE_ARG_TYPES (*tp);
+ tree arg;
/* We never want to walk into default arguments. */
- for (; arg; arg = TREE_CHAIN (arg))
+ for (arg = TYPE_ARG_TYPES (*tp); arg; arg = TREE_CHAIN (arg))
WALK_SUBTREE (TREE_VALUE (arg));
}
break;
- case RECORD_TYPE:
- case UNION_TYPE:
- case QUAL_UNION_TYPE:
- {
- tree field;
-
- for (field = TYPE_FIELDS (*tp); field; field = TREE_CHAIN (field))
- {
- /* We would like to look at the type of the field, but we
- can easily get infinite recursion. So assume it's
- pointed to elsewhere in the tree. Also, ignore things that
- aren't fields. */
- if (TREE_CODE (field) != FIELD_DECL)
- continue;
-
- WALK_SUBTREE (DECL_FIELD_OFFSET (field));
- WALK_SUBTREE (DECL_SIZE (field));
- WALK_SUBTREE (DECL_SIZE_UNIT (field));
- if (code == QUAL_UNION_TYPE)
- WALK_SUBTREE (DECL_QUALIFIER (field));
- }
- }
- break;
-
case ARRAY_TYPE:
/* Don't follow this nodes's type if a pointer for fear that we'll
have infinite recursion. Those types are uninteresting anyway. */
@@ -2200,38 +2245,6 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, void *htab_)
WALK_SUBTREE (TREE_TYPE (*tp));
WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
- case EXIT_BLOCK_EXPR:
- WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1));
-
- case SAVE_EXPR:
- WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
-
- case BIND_EXPR:
- {
- tree decl;
- for (decl = BIND_EXPR_VARS (*tp); decl; decl = TREE_CHAIN (decl))
- {
- /* Walk the DECL_INITIAL and DECL_SIZE. We don't want to walk
- into declarations that are just mentioned, rather than
- declared; they don't really belong to this part of the tree.
- And, we can see cycles: the initializer for a declaration
- can refer to the declaration itself. */
- WALK_SUBTREE (DECL_INITIAL (decl));
- WALK_SUBTREE (DECL_SIZE (decl));
- WALK_SUBTREE (DECL_SIZE_UNIT (decl));
- WALK_SUBTREE (TREE_TYPE (decl));
- }
- WALK_SUBTREE_TAIL (BIND_EXPR_BODY (*tp));
- }
-
- case STATEMENT_LIST:
- {
- tree_stmt_iterator i;
- for (i = tsi_start (*tp); !tsi_end_p (i); tsi_next (&i))
- WALK_SUBTREE (*tsi_stmt_ptr (i));
- }
- break;
-
default:
/* ??? This could be a language-defined node. We really should make
a hook for it, but right now just ignore it. */
@@ -2358,34 +2371,20 @@ static tree
mark_local_for_remap_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
void *data)
{
- tree t = *tp;
inline_data *id = (inline_data *) data;
- tree decl;
/* Don't walk into types. */
- if (TYPE_P (t))
- {
- *walk_subtrees = 0;
- return NULL_TREE;
- }
-
- if (TREE_CODE (t) == LABEL_EXPR)
- decl = TREE_OPERAND (t, 0);
- else
- /* We don't need to handle anything else ahead of time. */
- decl = NULL_TREE;
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
- if (decl)
+ else if (TREE_CODE (*tp) == LABEL_EXPR)
{
- tree copy;
-
- /* Make a copy. */
- copy = copy_decl_for_inlining (decl,
- DECL_CONTEXT (decl),
- DECL_CONTEXT (decl));
+ tree decl = TREE_OPERAND (*tp, 0);
- /* Remember the copy. */
- insert_decl_map (id, decl, copy);
+ /* Copy the decl and remember the copy. */
+ insert_decl_map (id, decl,
+ copy_decl_for_inlining (decl, DECL_CONTEXT (decl),
+ DECL_CONTEXT (decl)));
}
return NULL_TREE;
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 7d195cc2e75..d1899981c1f 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -1763,7 +1763,7 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
if (TYPE_P (t) || DECL_P (t))
*walk_subtrees = 0;
- if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
+ else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
{
while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
&& is_gimple_min_invariant (TREE_OPERAND (t, 1))
diff --git a/gcc/tree.c b/gcc/tree.c
index 25431d4495b..e0a1c46ea36 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1856,6 +1856,10 @@ has_cleanups (tree exp)
}
return 0;
+ case DECL_EXPR:
+ return (DECL_INITIAL (DECL_EXPR_DECL (exp))
+ && has_cleanups (DECL_INITIAL (DECL_EXPR_DECL (exp))));
+
default:
break;
}
diff --git a/gcc/tree.def b/gcc/tree.def
index f7dabaf46c8..422817d3215 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -805,6 +805,9 @@ DEFTREECODE (TRY_FINALLY_EXPR, "try_finally", 's', 2)
/* These types of expressions have no useful value,
and always have side effects. */
+/* Used to represent a local declaration. The operand is DECL_EXPR_DECL. */
+DEFTREECODE (DECL_EXPR, "decl_expr", 's', 1)
+
/* A label definition, encapsulated as a statement.
Operand 0 is the LABEL_DECL node for the label that appears here.
The type should be void and the value should be ignored. */
diff --git a/gcc/tree.h b/gcc/tree.h
index a369827f461..57d1970b7c7 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1065,6 +1065,10 @@ struct tree_vec GTY(())
#define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1)
#define TARGET_EXPR_CLEANUP(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 2)
+/* DECL_EXPR accessor. This gives access to the DECL associated with
+ the given declaration statement. */
+#define DECL_EXPR_DECL(NODE) TREE_OPERAND (DECL_EXPR_CHECK (NODE), 0)
+
#define EXIT_EXPR_COND(NODE) TREE_OPERAND (EXIT_EXPR_CHECK (NODE), 0)
/* SWITCH_EXPR accessors. These give access to the condition, body and