This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] C++ simplification patch
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 02 Jan 2003 19:37:57 -0500
- Subject: [tree-ssa] C++ simplification patch
At long last, here's the patch which implements simplification of C++. The
remaining failures are mostly for line number differences and -Wswitch, as
with the C frontend.
At first I had thought I only needed to add EH support, but of course that
was naive; most of the work had to do with various quirks of how the C++
frontend handles initialization.
Some things I'm still uncomfortable with:
The hoops I'm jumping through to deal with C++ initialization semantics,
particularly in returns, by adding new parms for simplify_modify_expr and
simplify_cond_expr. Suggestions of a better way are welcome.
Handling of temporary variables created by the frontends. Currently the
genericizer assumes that an artificial decl with no name has not been
pushed into a block, so it should be added to the main list of temps.
This seems rather fragile, but it also seems to match existing practice.
EH_FILTER_MUST_NOT_THROW is kind of a kludge, but doing better would
require the backend to understand the difference between terminate and
unexpected.
EH handling of cleanups -- C++ says that if a cleanup run as a result of
throwing an exception also throws, we call terminate. However, if a
cleanup run as a result of flowing off the end of a block throws, we
propagate that exception. This distinction is currently handled by the
expander, controlled by lang_protect_cleanup_actions. This works, but
it's flow information which is hidden from the tree optimizers. Lowering
TRY_FINALLY_EXPR should solve this problem.
Other notes:
Note that with this patch all the testcases which use old-style named
return values will crash. I don't care, as Mark has removed that support
from the new parser.
All tree optimizers are currently disabled for C++. Remove the "&& 0" in
cp/optimize.c:optimize_function to enable them.
Tested i686-pc-linux-gnu.
ChangeLog:
2003-01-02 Jason Merrill <jason@redhat.com>
* c-common.c (finish_fname_decls): Put the DECL_STMTs inside the
outermost scope.
* c-decl.c (c_make_fname_decl): Push the decls there, too.
* fold-const.c (fold) [COND_EXPR]: Avoid NOP_EXPRs better.
* integrate.c (copy_decl_for_inlining): Don't clear the rtl for
static/external decls.
ChangeLog.tree-ssa:
2003-01-02 Jason Merrill <jason@redhat.com>
* c-simplify.c (c_genericize): Dump more info about the function.
Use dump_function.
* tree-dump.c (dump_function): Move from cp/optimize.c.
* tree-dump.h: Declare it.
* gimplify.c (mostly_copy_tree_r): Remove unnecessary cases.
(unshare_expr): New fn.
* tree-inline.c (mark_local_for_remap_r, unsave_r): New fns, adapted
from C++ versions.
(lhd_unsave_expr_now): Likewise.
* tree.c (unsave_expr_now): Remove.
(unsafe_for_reeval): Labels and BIND_EXPRs are only somewhat unsafe.
* gimplify.c (simplify_function_tree): Add an outer BIND_EXPR if
needed.
(voidify_wrapper_expr): Not static. Abort if we try to voidify an
expression with TREE_ADDRESSABLE type. Be clever with INDIRECT_REFs.
(foreach_stmt): Avoid redundant work.
(create_tmp_var): Abort if we try to create a temp of ADDRESSABLE type.
(simplify_expr): Simplify VTABLE_REF.
* c-simplify.c (simplify_decl_stmt): Ignore DECL_EXTERNAL decls.
(simplify_stmt_expr): Fix thinko.
(simplify_block): Don't ignore partial scopes.
(simplify_condition): New fn.
(simplify_c_loop, simplify_if_stmt, simplify_switch_stmt): Call it.
* expr.c (expand_expr) [BIND_EXPR]: Handle statics better.
* tree-inline.c (remap_decl): Remap all decls.
(declare_return_variable): Be clever with INDIRECT_REFs.
(expand_call_inline): If we have an explicit return slot, the inlined
body is void.
(walk_tree): Fix type handling.
(copy_tree_r): Don't walk into decls.
* tree-simple.c (is_simple_unary_expr): Handle VTABLE_REF.
(is_simple_id): Allow RESULT_DECL.
* tree-simple.h (gsi_stmt): Strip WFLs and NOPs.
* gimplify.c (simplify_cond_expr): Handle void arms. Add target parm.
(simplify_modify_expr): Pass it. Add special handling for COND_EXPR
and CONSTRUCTOR (from Daniel Berlin). Add want_value parm.
(simplify_expr): Pass new args. Loop sooner if language-specific
simplification happened.
(simplify_return_expr): Pass the whole MODIFY_EXPR to simplify_expr.
(simplify_target_expr): Simplify.
* tree.def (CATCH_EXPR, EH_FILTER_EXPR): New tree codes.
* except.c (expand_eh_handler): New fn.
(expand_eh_region_end_allowed): If no types are allowed, hand off to
expand_eh_region_end_must_not_throw.
* except.h: Declare expand_eh_handler.
* expr.c (expand_expr) [TRY_CATCH_EXPR]: Use it.
[CATCH_EXPR, EH_FILTER_EXPR]: New cases.
* gimplify.c (simplify_expr) [EXC_PTR_EXPR, CATCH_EXPR,
EH_FILTER_EXPR]: New cases.
(gimple_build_eh_filter): New fn.
(maybe_protect_cleanup): New fn.
(gimple_push_cleanup): Call it.
(simplify_cleanup_point_expr): Fix thinko.
* c-simplify.c (simplify_cleanup): Call it.
* tree-simple.h: Declare it.
* Makefile.in (gimplify.o): Depend on except.h.
* tree.h (CATCH_TYPES, CATCH_BODY): New macros.
(EH_FILTER_TYPES, EH_FILTER_FAILURE): New macros.
* tree-simple.c (is_simple_id): Allow EXC_PTR_EXPR.
* c-pretty-print.c (dump_c_node) [CLEANUP_POINT_EXPR]: Support.
* tree-pretty-print.c (dump_generic_node): Likewise.
[CATCH_EXPR, EH_FILTER_EXPR, EXC_PTR_EXPR]: Support.
* c-pretty-print.c (NIY): Print operands.
(dump_c_tree): Don't look at TREE_CHAIN if it doesn't matter.
(dump_c_node) [ARRAY_TYPE]: Handle non-constant array bounds.
[CALL_EXPR]: Pass spc down.
[VTABLE_REF]: Support.
(op_prio) [TARGET_EXPR]: Support.
(print_call_name): Handle function pointers.
* tree-pretty-print.c: Likewise.
cp/ChangeLog:
2003-01-02 Jason Merrill <jason@redhat.com>
* call.c (build_conditional_expr): Stabilize lvalues properly.
* cvt.c (ocp_convert): Don't build NOP_EXPRs of class type.
* call.c (convert_like_real): Call decl_constant_value for an
IDENTITY_CONV even if there are no more conversions.
* cvt.c (build_up_reference): Don't push unnamed temps.
* decl.c (cp_make_fname_decl): Push the decls inside the
outermost scope.
* decl2.c (do_namespace_alias): Namespace aliases are DECL_EXTERNAL.
* dump.c (cp_dump_tree): Don't try to dump class-specific fields
for a backend struct.
* except.c (wrap_cleanups_r, build_throw): Make
MUST_NOT_THROW_EXPRs void.
* init.c (expand_default_init): Update to handle MUST_NOT_THROW_EXPR.
* init.c (build_vec_delete_1): Pre-evaluate the base address.
* init.c (get_temp_regvar): Tweak.
* tree.c (lvalue_p_1): Don't allow sloppy NOP_EXPRs as lvalues.
Don't allow CALL_EXPR or VA_ARG_EXPR, either.
* tree.c (cp_copy_res_decl_for_inlining): Only do debug tweaks if
our replacement is a decl.
cp/ChangeLog.tree-ssa:
2003-01-02 Jason Merrill <jason@redhat.com>
* Make-lang.in (CXX_C_OBJS): Replace old-tree-inline.o with
tree-inline.o.
* optimize.c (dump_function): Move to ../tree-dump.c.
* cp-simplify.c (cp_simplify_expr): Handle PTRMEM_CST, INIT_EXPR,
MODIFY_EXPR and EMPTY_CLASS_EXPR.
(cp_simplify_stmt): Handle USING_STMT.
(cp_simplify_init_expr): New fn.
* cvt.c (build_up_reference): Don't push the decl.
* class.c (build_vtable_entry_ref, build_vtbl_ref_1): Unshare the
vtable address.
* init.c (build_vtbl_address): Likewise.
* cp-lang.c (LANG_HOOKS_UNSAVE_EXPR_NOW): Remove.
* decl.c (lookup_name_real): Unshare the expansion of an ALIAS_DECL.
(finish_function): Don't genericize templates.
* parse.y (parse_asm_stmt): Fix prototype.
* semantics.c (expand_body): Don't expand if we saw errors.
Drop support for expanding non-GENERIC code.
* cp-simplify.c (cp_simplify_stmt): Handle HANDLER and EH_SPEC_BLOCK.
(genericize_try_block): Always build a TRY_CATCH_EXPR.
(genericize_catch_block): New fn.
(genericize_eh_spec_block): New fn.
(cp_simplify_expr): Handle THROW_EXPR and MUST_NOT_THROW_EXPR.
(simplify_must_not_throw_expr): New fn.
* except.c (wrap_cleanups_r): Make the MUST_NOT_THROW_EXPR void.
(build_throw): Likewise.
*** ./cp/Make-lang.in.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./cp/Make-lang.in 2002-12-14 23:07:36.000000000 -0500
*************** g++-cross$(exeext): g++$(exeext)
*** 80,86 ****
# Shared with C front end:
CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
c-dump.o $(CXX_TARGET_OBJS) c-opts.o c-simplify.o c-pretty-print.o \
! old-tree-inline.o
# Language-specific object files.
CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
--- 80,86 ----
# Shared with C front end:
CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
c-dump.o $(CXX_TARGET_OBJS) c-opts.o c-simplify.o c-pretty-print.o \
! tree-inline.o
# Language-specific object files.
CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
*** ./cp/call.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./cp/call.c 2003-01-02 11:43:03.000000000 -0500
*************** build_conditional_expr (tree arg1, tree
*** 2997,3003 ****
{
if (pedantic)
pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
! arg1 = arg2 = save_expr (arg1);
}
/* [expr.cond]
--- 2997,3006 ----
{
if (pedantic)
pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression");
! if (real_lvalue_p (arg1))
! arg2 = arg1 = stabilize_reference (arg1);
! else
! arg2 = arg1 = save_expr (arg1);
}
/* [expr.cond]
*************** convert_like_real (tree convs, tree expr
*** 3974,3979 ****
--- 3977,3988 ----
case IDENTITY_CONV:
if (type_unknown_p (expr))
expr = instantiate_type (totype, expr, tf_error | tf_warning);
+ /* Convert a non-array constant variable to its underlying value, unless we
+ are about to bind it to a reference, in which case we need to
+ leave it as an lvalue. */
+ if (inner >= 0
+ && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
+ expr = decl_constant_value (expr);
return expr;
case AMBIG_CONV:
/* Call build_user_type_conversion again for the error. */
*************** convert_like_real (tree convs, tree expr
*** 3989,4001 ****
if (expr == error_mark_node)
return error_mark_node;
- /* Convert a non-array constant variable to its underlying value, unless we
- are about to bind it to a reference, in which case we need to
- leave it as an lvalue. */
- if (TREE_CODE (convs) != REF_BIND
- && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
- expr = decl_constant_value (expr);
-
switch (TREE_CODE (convs))
{
case RVALUE_CONV:
--- 3998,4003 ----
*** ./cp/class.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./cp/class.c 2003-01-02 11:43:05.000000000 -0500
*************** build_vtable_entry_ref (array_ref, insta
*** 396,402 ****
basetype = TREE_TYPE (basetype);
vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
! first_fn = TYPE_BINFO_VTABLE (basetype);
i = fold (build_array_ref (first_fn, idx));
i = fold (build_c_cast (ptrdiff_type_node,
--- 396,402 ----
basetype = TREE_TYPE (basetype);
vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
! first_fn = unshare_expr (TYPE_BINFO_VTABLE (basetype));
i = fold (build_array_ref (first_fn, idx));
i = fold (build_c_cast (ptrdiff_type_node,
*************** build_vtbl_ref_1 (instance, idx)
*** 439,445 ****
tree binfo = lookup_base (fixed_type, basetype,
ba_ignore|ba_quiet, NULL);
if (binfo)
! vtbl = BINFO_VTABLE (binfo);
}
if (!vtbl)
--- 439,445 ----
tree binfo = lookup_base (fixed_type, basetype,
ba_ignore|ba_quiet, NULL);
if (binfo)
! vtbl = unshare_expr (BINFO_VTABLE (binfo));
}
if (!vtbl)
*** ./cp/cp-lang.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./cp/cp-lang.c 2002-12-31 18:25:20.000000000 -0500
*************** static bool cp_var_mod_type_p PARAMS ((t
*** 65,72 ****
#define LANG_HOOKS_PARSE_FILE c_common_parse_file
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL cxx_dup_lang_specific_decl
- #undef LANG_HOOKS_UNSAVE_EXPR_NOW
- #define LANG_HOOKS_UNSAVE_EXPR_NOW cxx_unsave_expr_now
#undef LANG_HOOKS_MAYBE_BUILD_CLEANUP
#define LANG_HOOKS_MAYBE_BUILD_CLEANUP cxx_maybe_build_cleanup
#undef LANG_HOOKS_TRUTHVALUE_CONVERSION
--- 65,70 ----
*** ./cp/cp-simplify.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./cp/cp-simplify.c 2003-01-02 16:26:45.000000000 -0500
*************** Software Foundation, 59 Temple Place - S
*** 31,36 ****
--- 31,40 ----
#include "tree-simple.h"
static void genericize_try_block PARAMS ((tree *));
+ static void genericize_catch_block PARAMS ((tree *));
+ static void genericize_eh_spec_block PARAMS ((tree *));
+ static void simplify_must_not_throw_expr PARAMS ((tree *, tree *));
+ static void cp_simplify_init_expr PARAMS ((tree *, tree *, tree *));
/* Genericize a C++ _STMT. Called from c_simplify_stmt. */
*************** cp_simplify_stmt (stmt_p, next_p)
*** 46,51 ****
--- 50,69 ----
genericize_try_block (stmt_p);
return 1;
+ case HANDLER:
+ genericize_catch_block (stmt_p);
+ return 1;
+
+ case EH_SPEC_BLOCK:
+ genericize_eh_spec_block (stmt_p);
+ return 1;
+
+ case USING_STMT:
+ /* Just ignore for now. Eventually we will want to pass this on to
+ the debugger. */
+ *stmt_p = empty_stmt_node;
+ return 1;
+
default:
break;
}
*************** static void
*** 58,78 ****
genericize_try_block (stmt_p)
tree *stmt_p;
{
! tree stmt = *stmt_p;
! if (CLEANUP_P (stmt))
! {
! /* Just convert to a TRY_CATCH_EXPR. */
! tree body = TRY_STMTS (stmt);
! tree cleanup = TRY_HANDLERS (stmt);
! c_simplify_stmt (&body);
! *stmt_p = build (TRY_CATCH_EXPR, void_type_node, body, cleanup);
! }
! else
! /* FIXME a real try block. */
! abort ();
}
/* Do C++-specific simplification. Args are as for simplify_expr. */
--- 76,120 ----
genericize_try_block (stmt_p)
tree *stmt_p;
{
! tree body = TRY_STMTS (*stmt_p);
! tree cleanup = TRY_HANDLERS (*stmt_p);
! c_simplify_stmt (&body);
! /* cleanup is an expression, so it doesn't need to be genericized. */
! *stmt_p = build (TRY_CATCH_EXPR, void_type_node, body, cleanup);
! }
! /* Genericize a HANDLER by converting to a CATCH_EXPR. */
!
! static void
! genericize_catch_block (stmt_p)
! tree *stmt_p;
! {
! tree type = HANDLER_TYPE (*stmt_p);
! tree body = HANDLER_BODY (*stmt_p);
!
! c_simplify_stmt (&body);
!
! /* FIXME should the caught type go in TREE_TYPE? */
! *stmt_p = build (CATCH_EXPR, void_type_node, type, body);
! }
!
! /* Genericize an EH_SPEC_BLOCK by converting it to a
! TRY_CATCH_EXPR/EH_FILTER_EXPR pair. */
!
! static void
! genericize_eh_spec_block (stmt_p)
! tree *stmt_p;
! {
! tree body = EH_SPEC_STMTS (*stmt_p);
! tree allowed = EH_SPEC_RAISES (*stmt_p);
! tree failure = build_call (call_unexpected_node,
! tree_cons (NULL_TREE, build_exc_ptr (),
! NULL_TREE));
! c_simplify_stmt (&body);
!
! *stmt_p = gimple_build_eh_filter (body, allowed, failure);
}
/* Do C++-specific simplification. Args are as for simplify_expr. */
*************** cp_simplify_expr (expr_p, pre_p, post_p)
*** 85,94 ****
--- 127,159 ----
{
switch (TREE_CODE (*expr_p))
{
+ case PTRMEM_CST:
+ *expr_p = cplus_expand_constant (*expr_p);
+ return 1;
+
case AGGR_INIT_EXPR:
simplify_aggr_init_expr (expr_p);
+ return 1;
+
+ case THROW_EXPR:
+ /* FIXME communicate throw type to backend, probably by moving
+ THROW_EXPR into ../tree.def. */
+ *expr_p = TREE_OPERAND (*expr_p, 0);
+ return 1;
+
+ case MUST_NOT_THROW_EXPR:
+ simplify_must_not_throw_expr (expr_p, pre_p);
+ return 1;
+
+ case INIT_EXPR:
+ case MODIFY_EXPR:
+ cp_simplify_init_expr (expr_p, pre_p, post_p);
break;
+ case EMPTY_CLASS_EXPR:
+ *expr_p = integer_zero_node;
+ return 1;
+
default:
break;
}
*************** cp_simplify_expr (expr_p, pre_p, post_p)
*** 96,101 ****
--- 161,200 ----
return c_simplify_expr (expr_p, pre_p, post_p);
}
+ /* Simplify initialization from an AGGR_INIT_EXPR. */
+
+ static void
+ cp_simplify_init_expr (expr_p, pre_p, post_p)
+ tree *expr_p;
+ tree *pre_p;
+ tree *post_p;
+ {
+ tree from = TREE_OPERAND (*expr_p, 1);
+ tree to = TREE_OPERAND (*expr_p, 0);
+
+ /* If we are initializing something from a TARGET_EXPR, strip the
+ TARGET_EXPR and initialize it directly. */
+ /* What about code that pulls out the temp and uses it elsewhere? I
+ think that such code never uses the TARGET_EXPR as an initializer. If
+ I'm wrong, we'll abort because the temp won't have any RTL. In that
+ case, I guess we'll need to replace references somehow. */
+ if (TREE_CODE (from) == TARGET_EXPR)
+ from = TARGET_EXPR_INITIAL (from);
+
+ /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
+ replace the slot operand with our target.
+
+ Should we add a target parm to simplify_expr instead? No, as in this
+ case we want to replace the INIT_EXPR. */
+ if (TREE_CODE (from) == AGGR_INIT_EXPR)
+ {
+ simplify_expr (&to, pre_p, post_p, is_simple_modify_expr_lhs, fb_lvalue);
+ TREE_OPERAND (from, 2) = to;
+ *expr_p = from;
+ simplify_aggr_init_expr (expr_p);
+ }
+ }
+
/* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. */
void
*************** simplify_aggr_init_expr (tp)
*** 177,179 ****
--- 276,303 ----
TREE_CHAIN (call_expr) = TREE_CHAIN (aggr_init_expr);
*tp = call_expr;
}
+
+ /* Simplify a MUST_NOT_THROW_EXPR. */
+
+ static void
+ simplify_must_not_throw_expr (expr_p, pre_p)
+ tree *expr_p;
+ tree *pre_p;
+ {
+ tree stmt = *expr_p;
+ tree temp = voidify_wrapper_expr (stmt);
+ tree body = TREE_OPERAND (stmt, 0);
+
+ simplify_stmt (&body);
+
+ stmt = gimple_build_eh_filter (body, NULL_TREE,
+ build_call (terminate_node, NULL_TREE));
+
+ if (temp)
+ {
+ add_tree (stmt, pre_p);
+ *expr_p = temp;
+ }
+ else
+ *expr_p = stmt;
+ }
*** ./cp/cvt.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./cp/cvt.c 2002-12-31 12:53:37.000000000 -0500
*************** build_up_reference (type, arg, flags, de
*** 386,392 ****
{
/* Automatic; make sure we handle the cleanup properly. */
maybe_push_cleanup_level (argtype);
! arg = pushdecl (arg);
}
/* Process the initializer for the declaration. */
--- 386,393 ----
{
/* Automatic; make sure we handle the cleanup properly. */
maybe_push_cleanup_level (argtype);
! /* Don't push unnamed temps. Do set DECL_CONTEXT, though. */
! DECL_CONTEXT (arg) = current_function_decl;
}
/* Process the initializer for the declaration. */
*************** ocp_convert (type, expr, convtype, flags
*** 671,676 ****
--- 672,686 ----
conversion. */
else if (TREE_CODE (type) == COMPLEX_TYPE)
return fold (convert_to_complex (type, e));
+ else if (TREE_CODE (e) == TARGET_EXPR)
+ {
+ /* Don't build a NOP_EXPR of class type. Instead, change the
+ type of the temporary. */
+ TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type;
+ return e;
+ }
+ else if (CLASS_TYPE_P (type))
+ abort ();
else
return fold (build1 (NOP_EXPR, type, e));
}
*** ./cp/decl.c.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/decl.c 2003-01-02 16:29:59.000000000 -0500
*************** does not match lookup in the current sco
*** 6235,6241 ****
val = from_obj;
if (val && TREE_CODE (val) == ALIAS_DECL)
! val = DECL_INITIAL (val);
return val;
}
--- 6235,6241 ----
val = from_obj;
if (val && TREE_CODE (val) == ALIAS_DECL)
! val = unshare_expr (DECL_INITIAL (val));
return val;
}
*************** cxx_init_decl_processing ()
*** 6706,6714 ****
say -fwritable-strings? */
if (flag_writable_strings)
flag_const_strings = 0;
-
- /* Disable for now. */
- flag_disable_simple = 1;
}
/* Generate an initializer for a function naming variable from
--- 6706,6711 ----
*************** cp_make_fname_decl (id, type_dep)
*** 6760,6766 ****
tree init = cp_fname_init (name);
tree decl = build_decl (VAR_DECL, id, TREE_TYPE (init));
! /* As we don't push the decl here, we must set the context. */
DECL_CONTEXT (decl) = current_function_decl;
DECL_PRETTY_FUNCTION_P (decl) = type_dep;
--- 6757,6763 ----
tree init = cp_fname_init (name);
tree decl = build_decl (VAR_DECL, id, TREE_TYPE (init));
! /* As we're using pushdecl_with_scope, we must set the context. */
DECL_CONTEXT (decl) = current_function_decl;
DECL_PRETTY_FUNCTION_P (decl) = type_dep;
*************** cp_make_fname_decl (id, type_dep)
*** 6771,6776 ****
--- 6768,6781 ----
TREE_USED (decl) = 1;
+ if (current_function_decl)
+ {
+ struct cp_binding_level *b = current_binding_level;
+ while (b->level_chain->parm_flag == 0)
+ b = b->level_chain;
+ pushdecl_with_scope (decl, b);
+ }
+
cp_finish_decl (decl, init, NULL_TREE, LOOKUP_ONLYCONVERTING);
return decl;
*************** finish_function (flags)
*** 14563,14569 ****
warning ("no return statement in function returning non-void");
/* Genericize before inlining. */
! if (!flag_disable_simple)
c_genericize (fndecl);
/* Clear out memory we no longer need. */
--- 14568,14574 ----
warning ("no return statement in function returning non-void");
/* Genericize before inlining. */
! if (!flag_disable_simple && !processing_template_decl)
c_genericize (fndecl);
/* Clear out memory we no longer need. */
*** ./cp/decl2.c.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/decl2.c 2003-01-02 11:43:08.000000000 -0500
*************** do_namespace_alias (alias, namespace)
*** 4326,4331 ****
--- 4326,4332 ----
/* Build the alias. */
alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);
DECL_NAMESPACE_ALIAS (alias) = namespace;
+ DECL_EXTERNAL (alias) = 1;
pushdecl (alias);
}
*** ./cp/dump.c.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/dump.c 2002-12-19 13:54:13.000000000 -0500
*************** cp_dump_tree (dump_info, t)
*** 265,270 ****
--- 265,273 ----
return 1;
}
+ if (! IS_AGGR_TYPE (t))
+ break;
+
dump_child ("vfld", TYPE_VFIELD (t));
if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t))
dump_string(di, "spec");
*** ./cp/except.c.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/except.c 2002-12-22 16:04:20.000000000 -0500
*************** wrap_cleanups_r (tp, walk_subtrees, data
*** 561,567 ****
cleanup = TARGET_EXPR_CLEANUP (exp);
if (cleanup)
{
! cleanup = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (cleanup), cleanup);
TARGET_EXPR_CLEANUP (exp) = cleanup;
}
--- 561,567 ----
cleanup = TARGET_EXPR_CLEANUP (exp);
if (cleanup)
{
! cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup);
TARGET_EXPR_CLEANUP (exp) = cleanup;
}
*************** build_throw (exp)
*** 733,739 ****
return error_mark_node;
}
! exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
/* Prepend the allocation. */
exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
if (temp_expr != void_zero_node)
--- 733,739 ----
return error_mark_node;
}
! exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp);
/* Prepend the allocation. */
exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp);
if (temp_expr != void_zero_node)
*** ./cp/init.c.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/init.c 2003-01-02 15:41:46.000000000 -0500
*************** Boston, MA 02111-1307, USA. */
*** 35,40 ****
--- 35,41 ----
#include "except.h"
#include "toplev.h"
#include "ggc.h"
+ #include "tree-inline.h"
static void construct_virtual_base (tree, tree);
static void expand_aggr_init_1 PARAMS ((tree, tree, tree, tree, int));
*************** build_vtbl_address (binfo)
*** 737,743 ****
TREE_USED (vtbl) = 1;
/* Now compute the address to use when initializing the vptr. */
! vtbl = BINFO_VTABLE (binfo_for);
if (TREE_CODE (vtbl) == VAR_DECL)
{
vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
--- 738,744 ----
TREE_USED (vtbl) = 1;
/* Now compute the address to use when initializing the vptr. */
! vtbl = unshare_expr (BINFO_VTABLE (binfo_for));
if (TREE_CODE (vtbl) == VAR_DECL)
{
vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
*************** expand_default_init (binfo, true_exp, ex
*** 1193,1205 ****
else
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
! if (TREE_CODE (init) == TRY_CATCH_EXPR)
! /* We need to protect the initialization of a catch parm
! with a call to terminate(), which shows up as a TRY_CATCH_EXPR
around the TARGET_EXPR for the copy constructor. See
! expand_start_catch_block. */
! TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp,
! TREE_OPERAND (init, 0));
else
init = build (INIT_EXPR, TREE_TYPE (exp), exp, init);
TREE_SIDE_EFFECTS (init) = 1;
--- 1194,1209 ----
else
init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
! if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
! /* We need to protect the initialization of a catch parm with a
! call to terminate(), which shows up as a MUST_NOT_THROW_EXPR
around the TARGET_EXPR for the copy constructor. See
! initialize_handler_parm. */
! {
! TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp,
! TREE_OPERAND (init, 0));
! TREE_TYPE (init) = void_type_node;
! }
else
init = build (INIT_EXPR, TREE_TYPE (exp), exp, init);
TREE_SIDE_EFFECTS (init) = 1;
*************** build_vec_delete_1 (base, maxindex, type
*** 2639,2648 ****
if (controller)
{
TREE_OPERAND (controller, 1) = body;
! return controller;
}
! else
! return cp_convert (void_type_node, body);
}
/* Create an unnamed variable of the indicated TYPE. */
--- 2643,2656 ----
if (controller)
{
TREE_OPERAND (controller, 1) = body;
! body = controller;
}
!
! if (TREE_CODE (base) == SAVE_EXPR)
! /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */
! body = build (COMPOUND_EXPR, void_type_node, base, body);
!
! return cp_convert (void_type_node, body);
}
/* Create an unnamed variable of the indicated TYPE. */
*************** get_temp_regvar (type, init)
*** 2680,2686 ****
decl = create_temporary_var (type);
if (building_stmt_tree ())
add_decl_stmt (decl);
! if (!building_stmt_tree ())
SET_DECL_RTL (decl, assign_temp (type, 2, 0, 1));
finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
--- 2688,2694 ----
decl = create_temporary_var (type);
if (building_stmt_tree ())
add_decl_stmt (decl);
! else
SET_DECL_RTL (decl, assign_temp (type, 2, 0, 1));
finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init));
*** ./cp/optimize.c.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/optimize.c 2003-01-02 15:50:29.000000000 -0500
*************** Software Foundation, 59 Temple Place - S
*** 39,50 ****
#include "flags.h"
#include "langhooks.h"
#include "diagnostic.h"
/* Prototypes. */
static tree calls_setjmp_r (tree *, int *, void *);
static void update_cloned_parm (tree, tree);
- static void dump_function (enum tree_dump_index, tree);
/* Optimize the body of FN. */
--- 39,50 ----
#include "flags.h"
#include "langhooks.h"
#include "diagnostic.h"
+ #include "tree-dump.h"
/* Prototypes. */
static tree calls_setjmp_r (tree *, int *, void *);
static void update_cloned_parm (tree, tree);
/* Optimize the body of FN. */
*************** optimize_function (tree fn)
*** 86,92 ****
dump_function (TDI_simple, fn);
/* Invoke the SSA tree optimizer. */
! if (optimize >= 1)
optimize_function_tree (fn);
}
--- 86,92 ----
dump_function (TDI_simple, fn);
/* Invoke the SSA tree optimizer. */
! if (optimize >= 1 && 0)
optimize_function_tree (fn);
}
*************** maybe_clone_body (tree fn)
*** 283,311 ****
/* We don't need to process the original function any further. */
return 1;
}
-
- /* Dump FUNCTION_DECL FN as tree dump PHASE. */
-
- static void
- dump_function (enum tree_dump_index phase, tree fn)
- {
- FILE *stream;
- int flags;
-
- stream = dump_begin (phase, &flags);
- if (stream)
- {
- fprintf (stream, "\n;; Function %s",
- decl_as_string (fn, TFF_DECL_SPECIFIERS));
- fprintf (stream, " (%s)\n",
- decl_as_string (DECL_ASSEMBLER_NAME (fn), 0));
- fprintf (stream, ";; enabled by -%s\n", dump_flag_name (phase));
- fprintf (stream, "\n");
-
- if (flags & TDF_RAW)
- dump_node (fn, TDF_SLIM | flags, stream);
- else
- print_generic_stmt (stream, DECL_SAVED_TREE (fn), 0);
- dump_end (phase, stream);
- }
- }
--- 283,285 ----
*** ./cp/parse.y.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/parse.y 2003-01-02 11:39:29.000000000 -0500
*************** static tree parse_handle_class_head (tre
*** 132,138 ****
static void parse_decl_instantiation (tree, tree, tree);
static int parse_begin_function_definition (tree, tree);
static tree parse_finish_call_expr (tree, tree, int);
! extern tree parse_asm_stmt PARAMS ((tree, tree, tree, tree, tree));
/* Cons up an empty parameter list. */
static inline tree
--- 132,138 ----
static void parse_decl_instantiation (tree, tree, tree);
static int parse_begin_function_definition (tree, tree);
static tree parse_finish_call_expr (tree, tree, int);
! static tree parse_asm_stmt PARAMS ((tree, tree, tree, tree, tree));
/* Cons up an empty parameter list. */
static inline tree
*** ./cp/semantics.c.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/semantics.c 2003-01-02 11:43:11.000000000 -0500
***************
*** 41,46 ****
--- 41,47 ----
#include "output.h"
#include "timevar.h"
#include "debug.h"
+ #include "diagnostic.h"
/* There routines provide a modular interface to perform many parsing
operations. They may therefore be used during actual parsing, or
*************** expand_body (fn)
*** 2316,2321 ****
--- 2317,2328 ----
if (DECL_EXTERNAL (fn))
return;
+ if (errorcount || sorrycount)
+ {
+ TREE_ASM_WRITTEN (fn) = 1;
+ return;
+ }
+
/* Save the current file name and line number. When we expand the
body of the function, we'll set LINENO and INPUT_FILENAME so that
error-mesages come out in the right places. */
*************** expand_body (fn)
*** 2339,2356 ****
/* Expand the body. */
if (statement_code_p (TREE_CODE (DECL_SAVED_TREE (fn))))
! expand_stmt (DECL_SAVED_TREE (fn));
! else
! expand_expr_stmt_value (DECL_SAVED_TREE (fn), 0, 0);
/* Statements should always be full-expressions at the outermost set
of curly braces for a function. */
my_friendly_assert (stmts_are_full_exprs_p (), 19990831);
- /* The outermost statement for a function contains the line number
- recorded when we finished processing the function. */
- lineno = STMT_LINENO (DECL_SAVED_TREE (fn));
-
/* Generate code for the function. */
genrtl_finish_function (fn);
--- 2346,2359 ----
/* Expand the body. */
if (statement_code_p (TREE_CODE (DECL_SAVED_TREE (fn))))
! abort ();
!
! expand_expr_stmt_value (DECL_SAVED_TREE (fn), 0, 0);
/* Statements should always be full-expressions at the outermost set
of curly braces for a function. */
my_friendly_assert (stmts_are_full_exprs_p (), 19990831);
/* Generate code for the function. */
genrtl_finish_function (fn);
*** ./cp/tree.c.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./cp/tree.c 2002-12-31 19:34:24.000000000 -0500
*************** lvalue_p_1 (ref, treat_class_rvalues_as_
*** 93,105 ****
allow_cast_as_lvalue);
case NOP_EXPR:
! /* If expression doesn't change the type, we consider it as an
! lvalue even when cast_as_lvalue extension isn't selected.
! That's because parts of the compiler are alleged to be sloppy
! about sticking in NOP_EXPR node for no good reason. */
! if (allow_cast_as_lvalue ||
! same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ref)),
! TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (ref, 0)))))
return lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
--- 93,99 ----
allow_cast_as_lvalue);
case NOP_EXPR:
! if (allow_cast_as_lvalue)
return lvalue_p_1 (TREE_OPERAND (ref, 0),
treat_class_rvalues_as_lvalues,
allow_cast_as_lvalue);
*************** lvalue_p_1 (ref, treat_class_rvalues_as_
*** 179,187 ****
case CALL_EXPR:
case VA_ARG_EXPR:
! return ((treat_class_rvalues_as_lvalues
! && IS_AGGR_TYPE (TREE_TYPE (ref)))
! ? clk_class : clk_none);
case FUNCTION_DECL:
/* All functions (except non-static-member functions) are
--- 173,180 ----
case CALL_EXPR:
case VA_ARG_EXPR:
! /* Any class-valued call would be wrapped in a TARGET_EXPR. */
! return clk_none;
case FUNCTION_DECL:
/* All functions (except non-static-member functions) are
*************** cp_copy_res_decl_for_inlining (result, f
*** 2368,2380 ****
/* We have a named return value; copy the name and source
position so we can get reasonable debugging information, and
register the return variable as its equivalent. */
! DECL_NAME (var) = DECL_NAME (nrv);
! DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
! DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
! /* Don't lose initialization info. */
! DECL_INITIAL (var) = DECL_INITIAL (nrv);
! /* Don't forget that it needs to go in the stack. */
! TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
splay_tree_insert (decl_map,
(splay_tree_key) nrv,
--- 2361,2376 ----
/* We have a named return value; copy the name and source
position so we can get reasonable debugging information, and
register the return variable as its equivalent. */
! if (TREE_CODE (var) == VAR_DECL)
! {
! DECL_NAME (var) = DECL_NAME (nrv);
! DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv);
! DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv);
! /* Don't lose initialization info. */
! DECL_INITIAL (var) = DECL_INITIAL (nrv);
! /* Don't forget that it needs to go in the stack. */
! TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv);
! }
splay_tree_insert (decl_map,
(splay_tree_key) nrv,
*** ./Makefile.in.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./Makefile.in 2003-01-02 11:41:14.000000000 -0500
*************** c-simplify.o : c-simplify.c $(CONFIG_H)
*** 1446,1452 ****
$(TM_H) coretypes.h
gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
diagnostic.h tree-simple.h tree-inline.h varray.h langhooks.h \
! langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) errors.h tree-inline.h diagnostic.h $(HASHTAB_H) \
$(TM_H) coretypes.h
--- 1446,1452 ----
$(TM_H) coretypes.h
gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
diagnostic.h tree-simple.h tree-inline.h varray.h langhooks.h \
! langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) errors.h tree-inline.h diagnostic.h $(HASHTAB_H) \
$(TM_H) coretypes.h
*** ./c-common.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./c-common.c 2002-12-31 02:23:41.000000000 -0500
*************** finish_fname_decls ()
*** 1055,1067 ****
if (body)
{
! /* They were called into existence, so add to statement tree. */
! body = chainon (body,
! TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)));
! body = build_stmt (COMPOUND_STMT, body);
!
! COMPOUND_STMT_NO_SCOPE (body) = 1;
! TREE_CHAIN (DECL_SAVED_TREE (current_function_decl)) = body;
}
for (ix = 0; fname_vars[ix].decl; ix++)
--- 1055,1072 ----
if (body)
{
! /* They were called into existence, so add to statement tree. Add
! the DECL_STMTs inside the outermost scope. */
! tree *p = &DECL_SAVED_TREE (current_function_decl);
! /* Skip the dummy EXPR_STMT and any EH_SPEC_BLOCK. */
! while (TREE_CODE (*p) != COMPOUND_STMT)
! p = &TREE_CHAIN (*p);
! p = &COMPOUND_BODY (*p);
! if (TREE_CODE (*p) == SCOPE_STMT)
! p = &TREE_CHAIN (*p);
!
! body = chainon (body, *p);
! *p = body;
}
for (ix = 0; fname_vars[ix].decl; ix++)
*************** finish_fname_decls ()
*** 1084,1090 ****
saved_function_name_decls = stack;
}
! /* Return the text name of the current function, suitable prettified
by PRETTY_P. */
const char *
--- 1089,1095 ----
saved_function_name_decls = stack;
}
! /* Return the text name of the current function, suitably prettified
by PRETTY_P. */
const char *
*************** fname_decl (rid, id)
*** 1168,1174 ****
}
if (!ix && !current_function_decl)
pedwarn_with_decl (decl, "`%s' is not defined outside of function scope");
!
return decl;
}
--- 1173,1179 ----
}
if (!ix && !current_function_decl)
pedwarn_with_decl (decl, "`%s' is not defined outside of function scope");
!
return decl;
}
*** ./c-decl.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./c-decl.c 2003-01-02 11:41:16.000000000 -0500
*************** c_make_fname_decl (id, type_dep)
*** 2552,2557 ****
--- 2552,2569 ----
DECL_INITIAL (decl) = init;
TREE_USED (decl) = 1;
+
+ if (current_function_decl)
+ {
+ /* Add the decls to the outermost block. */
+ struct binding_level *b = current_binding_level;
+ struct binding_level *old = b;
+ while (b->level_chain->parm_flag == 0)
+ b = b->level_chain;
+ current_binding_level = b;
+ pushdecl (decl);
+ current_binding_level = old;
+ }
finish_decl (decl, init, NULL_TREE);
*** ./c-pretty-print.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./c-pretty-print.c 2003-01-02 15:51:21.000000000 -0500
*************** Software Foundation, 59 Temple Place - S
*** 30,35 ****
--- 30,36 ----
#include "diagnostic.h"
#include "real.h"
#include "hashtab.h"
+ #include "langhooks.h"
static int op_prio PARAMS ((tree));
static const char *op_symbol PARAMS ((tree));
*************** static void dump_c_tree PARAMS ((outp
*** 49,72 ****
int));
static int dump_c_node PARAMS ((output_buffer *, tree,
int, int));
!
#define INDENT(SPACE) do { \
int i; for (i = 0; i<SPACE; i++) output_add_space (buffer); } while (0)
! #define NIY do { \
! output_add_string (buffer, "<<< Unknown tree: "); \
! output_add_string (buffer, tree_code_name[(int) TREE_CODE (node)]); \
! output_add_string (buffer, " >>>\n"); } while (0)
#define PRINT_FUNCTION_NAME(NODE) output_printf \
(buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
! IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (NODE, 0))) : \
! IDENTIFIER_POINTER (DECL_NAME (NODE)))
!
static output_buffer buffer;
static int initialized = 0;
/* Print the tree T in full, on file FILE. */
void
--- 50,93 ----
int));
static int dump_c_node PARAMS ((output_buffer *, tree,
int, int));
! static void do_niy PARAMS ((output_buffer *,
! tree));
#define INDENT(SPACE) do { \
int i; for (i = 0; i<SPACE; i++) output_add_space (buffer); } while (0)
!
! #define NIY do_niy(buffer,node)
#define PRINT_FUNCTION_NAME(NODE) output_printf \
(buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
! (*lang_hooks.decl_printable_name) (TREE_OPERAND (NODE, 0), 1) : \
! (*lang_hooks.decl_printable_name) (NODE, 1))
static output_buffer buffer;
static int initialized = 0;
+ /* Try to print something for an unknown tree code. */
+
+ static void
+ do_niy (buffer, node)
+ output_buffer *buffer;
+ tree node;
+ {
+ int i, len;
+
+ output_add_string (buffer, "<<< Unknown tree: ");
+ output_add_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
+
+ len = first_rtl_op (TREE_CODE (node));
+ for (i = 0; i < len; ++i)
+ {
+ newline_and_indent (buffer, 2);
+ dump_c_node (buffer, TREE_OPERAND (node, i), 2, 0);
+ }
+
+ output_add_string (buffer, " >>>\n");
+ }
+
/* Print the tree T in full, on file FILE. */
void
*************** dump_c_tree (buffer, t, spc)
*** 185,190 ****
--- 206,215 ----
default:
break;
}
+
+ if (!(*lang_hooks.tree_inlining.tree_chain_matters_p) (node))
+ break;
+
node = TREE_CHAIN (node);
if (htab_find (htab, node))
{
*************** dump_c_node (buffer, node, spc, brief_du
*** 379,387 ****
{
output_add_character (buffer, '[');
if (TYPE_SIZE (tmp))
! output_decimal (buffer,
! TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
! TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
output_add_character (buffer, ']');
tmp = TREE_TYPE (tmp);
}
--- 404,419 ----
{
output_add_character (buffer, '[');
if (TYPE_SIZE (tmp))
! {
! tree size = TYPE_SIZE (tmp);
! if (TREE_CODE (size) == INTEGER_CST)
! output_decimal (buffer,
! TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
! TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
! else if (TREE_CODE (size) == MULT_EXPR)
! dump_c_node (buffer, TREE_OPERAND (size, 0), spc, brief_dump);
! /* else punt. */
! }
output_add_character (buffer, ']');
tmp = TREE_TYPE (tmp);
}
*************** dump_c_node (buffer, node, spc, brief_du
*** 790,796 ****
output_add_character (buffer, '(');
op1 = TREE_OPERAND (node, 1);
if (op1)
! dump_c_node (buffer, op1, 0, brief_dump);
output_add_character (buffer, ')');
break;
--- 822,828 ----
output_add_character (buffer, '(');
op1 = TREE_OPERAND (node, 1);
if (op1)
! dump_c_node (buffer, op1, spc, brief_dump);
output_add_character (buffer, ')');
break;
*************** dump_c_node (buffer, node, spc, brief_du
*** 803,809 ****
break;
case CLEANUP_POINT_EXPR:
! NIY;
break;
case PLACEHOLDER_EXPR:
--- 835,843 ----
break;
case CLEANUP_POINT_EXPR:
! output_add_string (buffer, "<<cleanup_point ");
! dump_c_node (buffer, TREE_OPERAND (node, 0), spc, brief_dump);
! output_add_string (buffer, ">>");
break;
case PLACEHOLDER_EXPR:
*************** dump_c_node (buffer, node, spc, brief_du
*** 1451,1456 ****
--- 1485,1500 ----
dump_c_node (buffer, op0, spc, brief_dump);
break;
+ case VTABLE_REF:
+ output_add_string (buffer, "VTABLE_REF <(");
+ dump_c_node (buffer, TREE_OPERAND (node, 0), spc, brief_dump);
+ output_add_string (buffer, "),");
+ dump_c_node (buffer, TREE_OPERAND (node, 1), spc, brief_dump);
+ output_add_character (buffer, ',');
+ dump_c_node (buffer, TREE_OPERAND (node, 2), spc, brief_dump);
+ output_add_character (buffer, '>');
+ break;
+
default:
NIY;
}
*************** op_prio (op)
*** 1749,1754 ****
--- 1793,1799 ----
case FIX_CEIL_EXPR:
case FIX_FLOOR_EXPR:
case FIX_ROUND_EXPR:
+ case TARGET_EXPR:
return 14;
case CALL_EXPR:
*************** print_call_name (buffer, node)
*** 1935,1943 ****
case ADDR_EXPR:
case INDIRECT_REF:
case NOP_EXPR:
! PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
break;
!
case EXPR_WITH_FILE_LOCATION:
if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
--- 1980,1988 ----
case ADDR_EXPR:
case INDIRECT_REF:
case NOP_EXPR:
! dump_c_node (buffer, TREE_OPERAND (op0, 0), 0, 0);
break;
!
case EXPR_WITH_FILE_LOCATION:
if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL)
PRINT_FUNCTION_NAME (TREE_OPERAND (op0, 0));
*** ./java/parse.y.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./java/parse.y 2003-01-02 11:39:33.000000000 -0500
*************** catch_clause_parameter:
*** 1933,1939 ****
declare_local_variables (0, TREE_VALUE ($3),
build_tree_list (TREE_PURPOSE ($3),
init));
! $$ = build1 (CATCH_EXPR, NULL_TREE, ccpb);
EXPR_WFL_LINECOL ($$) = $1.location;
}
| CATCH_TK error
--- 1933,1939 ----
declare_local_variables (0, TREE_VALUE ($3),
build_tree_list (TREE_PURPOSE ($3),
init));
! $$ = build1 (JAVA_CATCH_EXPR, NULL_TREE, ccpb);
EXPR_WFL_LINECOL ($$) = $1.location;
}
| CATCH_TK error
*************** encapsulate_with_try_catch (location, ty
*** 15475,15482 ****
/* Add the catch statements */
add_stmt_to_block (catch_block, NULL_TREE, catch_stmts);
! /* Now we can build a CATCH_EXPR */
! catch_block = build1 (CATCH_EXPR, NULL_TREE, catch_block);
return build_try_statement (location, try_block, catch_block);
}
--- 15475,15482 ----
/* Add the catch statements */
add_stmt_to_block (catch_block, NULL_TREE, catch_stmts);
! /* Now we can build a JAVA_CATCH_EXPR */
! catch_block = build1 (JAVA_CATCH_EXPR, NULL_TREE, catch_block);
return build_try_statement (location, try_block, catch_block);
}
*************** patch_try_statement (node)
*** 15522,15528 ****
int unreachable;
/* At this point, the structure of the catch clause is
! CATCH_EXPR (catch node)
BLOCK (with the decl of the parameter)
COMPOUND_EXPR
MODIFY_EXPR (assignment of the catch parameter)
--- 15522,15528 ----
int unreachable;
/* At this point, the structure of the catch clause is
! JAVA_CATCH_EXPR (catch node)
BLOCK (with the decl of the parameter)
COMPOUND_EXPR
MODIFY_EXPR (assignment of the catch parameter)
*** ./java/java-tree.def.~1~ 2003-01-02 12:14:46.000000000 -0500
--- ./java/java-tree.def 2003-01-02 00:23:28.000000000 -0500
*************** DEFTREECODE (TRY_EXPR, "try-catch", 'e',
*** 55,61 ****
/* Catch clause.
Operand 0 is the catch clause block, which contains the declaration of
the catch clause parameter. */
! DEFTREECODE (CATCH_EXPR, "catch", '1', 1)
/* Synchronized statement.
Operand 0 is the expression on which we wish to synchronize,
--- 55,61 ----
/* Catch clause.
Operand 0 is the catch clause block, which contains the declaration of
the catch clause parameter. */
! DEFTREECODE (JAVA_CATCH_EXPR, "catch", '1', 1)
/* Synchronized statement.
Operand 0 is the expression on which we wish to synchronize,
*** ./except.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./except.c 2003-01-01 20:21:33.000000000 -0500
*************** expand_eh_region_end ()
*** 534,539 ****
--- 534,573 ----
return cur_region;
}
+ /* Expand HANDLER, which is the operand 1 of a TRY_CATCH_EXPR. Catch
+ blocks and C++ exception-specifications are handled specially. */
+
+ void
+ expand_eh_handler (handler)
+ tree handler;
+ {
+ tree inner = handler;
+ while (TREE_CODE (inner) == COMPOUND_EXPR
+ || TREE_CODE (inner) == EXPR_WITH_FILE_LOCATION)
+ inner = TREE_OPERAND (inner, 0);
+
+ switch (TREE_CODE (inner))
+ {
+ case CATCH_EXPR:
+ expand_start_all_catch ();
+ expand_expr (handler, const0_rtx, VOIDmode, 0);
+ expand_end_all_catch ();
+ break;
+
+ case EH_FILTER_EXPR:
+ if (EH_FILTER_MUST_NOT_THROW (handler))
+ expand_eh_region_end_must_not_throw (EH_FILTER_FAILURE (handler));
+ else
+ expand_eh_region_end_allowed (EH_FILTER_TYPES (handler),
+ EH_FILTER_FAILURE (handler));
+ break;
+
+ default:
+ expand_eh_region_end_cleanup (handler);
+ break;
+ }
+ }
+
/* End an exception handling region for a cleanup. HANDLER is an
expression to expand for the cleanup. */
*** ./c-simplify.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./c-simplify.c 2003-01-02 16:28:04.000000000 -0500
*************** Software Foundation, 59 Temple Place - S
*** 44,49 ****
--- 44,50 ----
#include "flags.h"
#include "rtl.h"
#include "toplev.h"
+ #include "tree-dump.h"
/* The simplification pass converts the language-dependent trees
(ld-trees) emitted by the parser into language-independent trees
*************** static void pop_context PAR
*** 89,94 ****
--- 90,96 ----
static tree c_build_bind_expr PARAMS ((tree, tree));
static void add_block_to_enclosing PARAMS ((tree));
static tree mostly_copy_tree_r PARAMS ((tree *, int *, void *));
+ static void simplify_condition PARAMS ((tree *));
enum bc_t { bc_break = 0, bc_continue = 1 };
static tree begin_bc_block PARAMS ((enum bc_t));
*************** c_genericize (fndecl)
*** 137,143 ****
dump_file = dump_begin (TDI_original, &dump_flags);
if (dump_file)
{
! fprintf (dump_file, "%s()\n", IDENTIFIER_POINTER (DECL_NAME (fndecl)));
if (dump_flags & TDF_RAW)
dump_node (DECL_SAVED_TREE (fndecl), TDF_SLIM | dump_flags, dump_file);
--- 139,150 ----
dump_file = dump_begin (TDI_original, &dump_flags);
if (dump_file)
{
! fprintf (dump_file, "\n;; Function %s",
! (*lang_hooks.decl_printable_name) (fndecl, 2));
! fprintf (dump_file, " (%s)\n",
! IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
! fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
! fprintf (dump_file, "\n");
if (dump_flags & TDF_RAW)
dump_node (DECL_SAVED_TREE (fndecl), TDF_SLIM | dump_flags, dump_file);
*************** c_genericize (fndecl)
*** 154,172 ****
pop_context ();
/* Dump the genericized tree IR. */
! dump_file = dump_begin (TDI_generic, &dump_flags);
! if (dump_file)
! {
! fprintf (dump_file, "%s()\n", IDENTIFIER_POINTER (DECL_NAME (fndecl)));
!
! if (dump_flags & TDF_RAW)
! dump_node (DECL_SAVED_TREE (fndecl), TDF_SLIM | dump_flags, dump_file);
! else
! print_generic_stmt (dump_file, DECL_SAVED_TREE (fndecl), 0);
! fprintf (dump_file, "\n");
!
! dump_end (TDI_generic, dump_file);
! }
}
/* Entry point for the tree lowering pass. Recursively scan
--- 161,167 ----
pop_context ();
/* Dump the genericized tree IR. */
! dump_function (TDI_generic, fndecl);
}
/* Entry point for the tree lowering pass. Recursively scan
*************** simplify_block (stmt_p, next_p)
*** 398,408 ****
for (p = &TREE_CHAIN (*stmt_p);; p = &TREE_CHAIN (*p))
if (TREE_CODE (*p) == SCOPE_STMT)
{
! if (SCOPE_PARTIAL_P (*p))
! /* Throw away partial scopes. Hmm, that probably won't work;
! we need to remember them to handle goto cleanups. */
! abort ();
! else if (SCOPE_BEGIN_P (*p))
++depth;
else if (--depth == 0)
break;
--- 393,399 ----
for (p = &TREE_CHAIN (*stmt_p);; p = &TREE_CHAIN (*p))
if (TREE_CODE (*p) == SCOPE_STMT)
{
! if (SCOPE_BEGIN_P (*p))
++depth;
else if (--depth == 0)
break;
*************** simplify_cleanup (stmt_p, next_p)
*** 428,439 ****
{
tree stmt = *stmt_p;
tree body = TREE_CHAIN (stmt);
enum tree_code code
= (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR);
c_simplify_stmt (&body);
! *stmt_p = build (code, void_type_node, body, CLEANUP_EXPR (stmt));
*next_p = NULL_TREE;
}
--- 419,433 ----
{
tree stmt = *stmt_p;
tree body = TREE_CHAIN (stmt);
+ tree cleanup = CLEANUP_EXPR (stmt);
enum tree_code code
= (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR);
+ cleanup = maybe_protect_cleanup (cleanup);
+
c_simplify_stmt (&body);
! *stmt_p = build (code, void_type_node, body, cleanup);
*next_p = NULL_TREE;
}
*************** simplify_expr_stmt (stmt_p)
*** 482,487 ****
--- 476,499 ----
*stmt_p = stmt;
}
+ /* If the condition for a loop (or the like) is a decl, it will be a
+ TREE_LIST where the TREE_PURPOSE is a DECL_STMT and the TREE_VALUE is
+ a use of the decl. Turn such a thing into a COMPOUND_EXPR. */
+
+ static void
+ simplify_condition (cond_p)
+ tree *cond_p;
+ {
+ tree cond = *cond_p;
+ if (cond && TREE_CODE (cond) == TREE_LIST)
+ {
+ tree decl = TREE_PURPOSE (cond);
+ tree value = TREE_VALUE (cond);
+ c_simplify_stmt (&decl);
+ *cond_p = build (COMPOUND_EXPR, TREE_TYPE (value), decl, value);
+ }
+ }
+
/* Begin a scope which can be exited by a break or continue statement. BC
indicates which.
*************** simplify_c_loop (cond, body, incr, cond_
*** 575,580 ****
--- 587,593 ----
if (cond)
{
+ simplify_condition (&cond);
exit = build_bc_goto (bc_break);
exit = build (COND_EXPR, void_type_node, cond, empty_stmt_node, exit);
exit = fold (exit);
*************** simplify_if_stmt (stmt_p)
*** 662,667 ****
--- 675,682 ----
tree else_ = ELSE_CLAUSE (stmt);
tree cond = IF_COND (stmt);
+ simplify_condition (&cond);
+
c_simplify_stmt (&then_);
c_simplify_stmt (&else_);
*************** simplify_switch_stmt (stmt_p)
*** 679,684 ****
--- 694,701 ----
tree break_block, switch_;
tree cond = SWITCH_COND (stmt);
+ simplify_condition (&cond);
+
break_block = begin_bc_block (bc_break);
c_simplify_stmt (&body);
*************** simplify_decl_stmt (stmt_p, next_p)
*** 728,734 ****
tree decl = DECL_STMT_DECL (stmt);
tree pre = NULL_TREE;
! if (TREE_CODE (decl) == VAR_DECL)
{
tree init = DECL_INITIAL (decl);
--- 745,751 ----
tree decl = DECL_STMT_DECL (stmt);
tree pre = NULL_TREE;
! if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
{
tree init = DECL_INITIAL (decl);
*************** simplify_decl_stmt (stmt_p, next_p)
*** 739,744 ****
--- 756,763 ----
its size, and so that any other local variables used in those
expressions will have been initialized. */
+ /* FIXME break the allocation out into a separate statement. */
+
tree size = DECL_SIZE (decl);
tree usize = DECL_SIZE_UNIT (decl);
tree bind;
*************** simplify_decl_stmt (stmt_p, next_p)
*** 763,769 ****
add_tree (bind, &pre);
! *next_p = NULL_TREE;
}
if (init && init != error_mark_node && !TREE_STATIC (decl))
--- 782,789 ----
add_tree (bind, &pre);
! if (next_p)
! *next_p = NULL_TREE;
}
if (init && init != error_mark_node && !TREE_STATIC (decl))
*************** simplify_decl_stmt (stmt_p, next_p)
*** 774,785 ****
init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
add_tree (init, &pre);
}
- }
! /* This decl isn't mentioned in the enclosing block, so add it to
! the list of temps. */
! if (DECL_ARTIFICIAL (decl))
! gimple_add_tmp_var (decl);
*stmt_p = pre;
}
--- 794,806 ----
init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
add_tree (init, &pre);
}
! /* 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);
! }
*stmt_p = pre;
}
*************** simplify_stmt_expr (expr_p)
*** 860,865 ****
--- 881,889 ----
}
last_expr = EXPR_STMT_EXPR (last_expr_stmt);
+ if (stmts_are_full_exprs_p ())
+ last_expr = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (last_expr),
+ last_expr);
EXPR_STMT_EXPR (last_expr_stmt) = empty_stmt_node;
#if defined ENABLE_CHECKING
if (!is_last_stmt_of_scope (last_expr_stmt))
*************** simplify_stmt_expr (expr_p)
*** 890,895 ****
--- 914,921 ----
BIND_EXPR_BODY (bind) = substmt;
TREE_TYPE (bind) = TREE_TYPE (body) = TREE_TYPE (last_expr);
}
+ else
+ body = substmt;
}
*expr_p = body;
*** ./except.h.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./except.h 2002-11-28 10:04:35.000000000 -0500
*************** extern void expand_eh_region_end_throw
*** 83,88 ****
--- 83,91 ----
destroying an object twice. */
extern void expand_eh_region_end_fixup PARAMS ((tree));
+ /* End some sort of EH region, depending on the argument. */
+ extern void expand_eh_handler PARAMS ((tree));
+
/* Invokes CALLBACK for every exception handler label. Only used by old
loop hackery; should not be used by new code. */
extern void for_each_eh_label PARAMS ((void (*) (rtx)));
*** ./expr.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./expr.c 2003-01-02 11:41:25.000000000 -0500
*************** expand_expr (exp, target, tmode, modifie
*** 6986,7010 ****
/* If VARS have not yet been expanded, expand them now. */
for (vars = BIND_EXPR_VARS (exp); vars; vars = TREE_CHAIN (vars))
{
! if (DECL_EXTERNAL (vars))
! /* Do nothing. */;
! else if (TREE_STATIC (vars)
! ? !TREE_ASM_WRITTEN (vars)
! : !DECL_RTL_SET_P (vars))
{
! if ((*lang_hooks.expand_decl) (vars))
/* OK. */;
! else if (TREE_CODE (vars) == VAR_DECL && !TREE_STATIC (vars))
! expand_decl (vars);
! else if (TREE_CODE (vars) == VAR_DECL && TREE_STATIC (vars))
! rest_of_decl_compilation (vars, NULL, 0, 0);
! else if (TREE_CODE (vars) == TYPE_DECL
! || TREE_CODE (vars) == CONST_DECL)
/* No expansion needed. */;
else
abort ();
}
! expand_decl_init (vars);
}
temp = expand_expr (BIND_EXPR_BODY (exp), target, tmode, modifier);
--- 6986,7018 ----
/* If VARS have not yet been expanded, expand them now. */
for (vars = BIND_EXPR_VARS (exp); vars; vars = TREE_CHAIN (vars))
{
! tree var = vars;
!
! if (DECL_EXTERNAL (var))
! continue;
!
! if (TREE_STATIC (var))
! /* If this is an inlined copy of a static local variable,
! look up the original decl. */
! var = DECL_ORIGIN (var);
!
! if (TREE_STATIC (var)
! ? !TREE_ASM_WRITTEN (var)
! : !DECL_RTL_SET_P (var))
{
! if ((*lang_hooks.expand_decl) (var))
/* OK. */;
! else if (TREE_CODE (var) == VAR_DECL && !TREE_STATIC (var))
! expand_decl (var);
! else if (TREE_CODE (var) == VAR_DECL && TREE_STATIC (var))
! rest_of_decl_compilation (var, NULL, 0, 0);
! else if (TREE_CODE (var) == TYPE_DECL
! || TREE_CODE (var) == CONST_DECL)
/* No expansion needed. */;
else
abort ();
}
! expand_decl_init (var);
}
temp = expand_expr (BIND_EXPR_BODY (exp), target, tmode, modifier);
*************** expand_expr (exp, target, tmode, modifie
*** 7017,7022 ****
--- 7025,7031 ----
{
if (TREE_CODE (vars) == FUNCTION_DECL
&& DECL_CONTEXT (vars) == current_function_decl
+ && DECL_SAVED_INSNS (vars)
&& !TREE_ASM_WRITTEN (vars)
&& TREE_ADDRESSABLE (vars))
{
*************** expand_expr (exp, target, tmode, modifie
*** 9248,9267 ****
tree handler = TREE_OPERAND (exp, 1);
expand_eh_region_start ();
-
op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
!
! expand_eh_region_end_cleanup (handler);
return op0;
}
case TRY_FINALLY_EXPR:
{
tree try_block = TREE_OPERAND (exp, 0);
tree finally_block = TREE_OPERAND (exp, 1);
! if (!optimize || unsafe_for_reeval (finally_block) > 1)
{
/* In this case, wrapping FINALLY_BLOCK in an UNSAVE_EXPR
is not sufficient, so we cannot expand the block twice.
--- 9257,9285 ----
tree handler = TREE_OPERAND (exp, 1);
expand_eh_region_start ();
op0 = expand_expr (TREE_OPERAND (exp, 0), 0, VOIDmode, 0);
! expand_eh_handler (handler);
return op0;
}
+ case CATCH_EXPR:
+ expand_start_catch (CATCH_TYPES (exp));
+ expand_expr (CATCH_BODY (exp), const0_rtx, VOIDmode, 0);
+ expand_end_catch ();
+ return op0;
+
+ case EH_FILTER_EXPR:
+ /* Should have been handled in expand_eh_handler. */
+ abort ();
+
case TRY_FINALLY_EXPR:
{
tree try_block = TREE_OPERAND (exp, 0);
tree finally_block = TREE_OPERAND (exp, 1);
! if ((!optimize && lang_protect_cleanup_actions == NULL)
! || unsafe_for_reeval (finally_block) > 1)
{
/* In this case, wrapping FINALLY_BLOCK in an UNSAVE_EXPR
is not sufficient, so we cannot expand the block twice.
*** ./fold-const.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./fold-const.c 2002-12-31 16:27:42.000000000 -0500
*************** fold (expr)
*** 7003,7009 ****
/* Avoid adding NOP_EXPRs in case this is an lvalue. */
if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type))
! comp_type = type;
switch (comp_code)
{
--- 7003,7013 ----
/* Avoid adding NOP_EXPRs in case this is an lvalue. */
if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type))
! {
! comp_type = type;
! comp_op0 = arg1;
! comp_op1 = arg2;
! }
switch (comp_code)
{
*** ./gimplify.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./gimplify.c 2003-01-02 15:16:50.000000000 -0500
*************** Software Foundation, 59 Temple Place - S
*** 36,41 ****
--- 36,42 ----
#include "langhooks-def.h"
#include "tree-flow.h"
#include "timevar.h"
+ #include "except.h"
static void simplify_constructor PARAMS ((tree, tree *, tree *));
static void simplify_array_ref PARAMS ((tree *, tree *, tree *));
*************** static void simplify_compound_lval PAR
*** 43,54 ****
static void simplify_component_ref PARAMS ((tree *, tree *, tree *));
static void simplify_call_expr PARAMS ((tree *, tree *, tree *));
static void simplify_tree_list PARAMS ((tree *, tree *, tree *));
! static void simplify_modify_expr PARAMS ((tree *, tree *, tree *));
static void simplify_compound_expr PARAMS ((tree *, tree *));
static void simplify_save_expr PARAMS ((tree *, tree *));
static void simplify_addr_expr PARAMS ((tree *, tree *, tree *));
static void simplify_self_mod_expr PARAMS ((tree *, tree *, tree *));
! static void simplify_cond_expr PARAMS ((tree *, tree *));
static void simplify_boolean_expr PARAMS ((tree *, tree *));
static void simplify_expr_wfl PARAMS ((tree *, tree *, tree *,
int (*) (tree)));
--- 44,55 ----
static void simplify_component_ref PARAMS ((tree *, tree *, tree *));
static void simplify_call_expr PARAMS ((tree *, tree *, tree *));
static void simplify_tree_list PARAMS ((tree *, tree *, tree *));
! static void simplify_modify_expr PARAMS ((tree *, tree *, tree *, int));
static void simplify_compound_expr PARAMS ((tree *, tree *));
static void simplify_save_expr PARAMS ((tree *, tree *));
static void simplify_addr_expr PARAMS ((tree *, tree *, tree *));
static void simplify_self_mod_expr PARAMS ((tree *, tree *, tree *));
! static void simplify_cond_expr PARAMS ((tree *, tree *, tree));
static void simplify_boolean_expr PARAMS ((tree *, tree *));
static void simplify_expr_wfl PARAMS ((tree *, tree *, tree *,
int (*) (tree)));
*************** static void simplify_cleanup_point_expr
*** 69,75 ****
static bool gimple_conditional_context PARAMS ((void));
static void gimple_push_condition PARAMS ((void));
static void gimple_pop_condition PARAMS ((tree *));
- static tree voidify_wrapper_expr PARAMS ((tree));
static void gimple_push_cleanup PARAMS ((tree, tree *));
static void gimplify_loop_expr PARAMS ((tree *));
static void gimplify_exit_expr PARAMS ((tree *, tree *));
--- 70,75 ----
*************** simplify_function_tree (fndecl)
*** 165,170 ****
--- 165,171 ----
tree fnbody;
int done;
tree oldfn;
+ tree tmp;
/* Don't bother doing anything if the program has errors. */
if (errorcount || sorrycount)
*************** simplify_function_tree (fndecl)
*** 195,200 ****
--- 196,207 ----
/* Unshare again, in case simplification was sloppy. */
unshare_all_trees (fnbody);
+ /* If there isn't an outer BIND_EXPR, add one. */
+ tmp = fnbody;
+ STRIP_WFL (tmp);
+ if (TREE_CODE (tmp) != BIND_EXPR)
+ fnbody = build (BIND_EXPR, void_type_node, NULL_TREE, fnbody, NULL_TREE);
+
DECL_SAVED_TREE (fndecl) = fnbody;
/* Declare the new temporary variables. */
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 270,289 ****
if (post_p == NULL)
post_p = &internal_post;
! /* First strip any uselessness. */
STRIP_TYPE_NOPS (*expr_p);
/* Loop over the specific simplifiers until the toplevel node remains the
same. */
do
{
! /* First do any language-specific simplification. */
(*lang_hooks.simplify_expr) (expr_p, pre_p, post_p);
if (*expr_p == NULL_TREE)
break;
!
! /* Then remember the expr. */
! save_expr = *expr_p;
switch (TREE_CODE (*expr_p))
{
--- 277,298 ----
if (post_p == NULL)
post_p = &internal_post;
! /* Strip any uselessness. */
STRIP_TYPE_NOPS (*expr_p);
/* Loop over the specific simplifiers until the toplevel node remains the
same. */
do
{
! /* Remember the expr. */
! save_expr = *expr_p;
!
! /* Do any language-specific simplification. */
(*lang_hooks.simplify_expr) (expr_p, pre_p, post_p);
if (*expr_p == NULL_TREE)
break;
! if (*expr_p != save_expr)
! continue;
switch (TREE_CODE (*expr_p))
{
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 305,311 ****
break;
case COND_EXPR:
! simplify_cond_expr (expr_p, pre_p);
break;
case CALL_EXPR:
--- 314,320 ----
break;
case COND_EXPR:
! simplify_cond_expr (expr_p, pre_p, NULL_TREE);
break;
case CALL_EXPR:
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 331,337 ****
case MODIFY_EXPR:
case INIT_EXPR:
! simplify_modify_expr (expr_p, pre_p, post_p);
break;
case TRUTH_ANDIF_EXPR:
--- 340,346 ----
case MODIFY_EXPR:
case INIT_EXPR:
! simplify_modify_expr (expr_p, pre_p, post_p, fallback != fb_none);
break;
case TRUTH_ANDIF_EXPR:
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 388,393 ****
--- 397,406 ----
case COMPLEX_CST:
break;
+ /* FIXME make this a decl. */
+ case EXC_PTR_EXPR:
+ break;
+
case BIND_EXPR:
simplify_bind_expr (expr_p, pre_p);
break;
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 475,480 ****
--- 488,509 ----
simplify_target_expr (expr_p, pre_p, post_p);
break;
+ case CATCH_EXPR:
+ simplify_stmt (&CATCH_BODY (*expr_p));
+ break;
+
+ case EH_FILTER_EXPR:
+ simplify_stmt (&EH_FILTER_FAILURE (*expr_p));
+ break;
+
+ case VTABLE_REF:
+ /* This moves much of the actual computation out of the
+ VTABLE_REF. Perhaps this should be revisited once we want to
+ do clever things with VTABLE_REFs. */
+ simplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+ is_simple_min_lval, fb_lvalue);
+ break;
+
/* FIXME
case MIN_EXPR:
case MAX_EXPR:
*************** simplify_expr (expr_p, pre_p, post_p, si
*** 589,595 ****
and give it void_type_node. Returns the temporary, or NULL_TREE if
WRAPPER was already void. */
! static tree
voidify_wrapper_expr (wrapper)
tree wrapper;
{
--- 618,624 ----
and give it void_type_node. Returns the temporary, or NULL_TREE if
WRAPPER was already void. */
! tree
voidify_wrapper_expr (wrapper)
tree wrapper;
{
*************** voidify_wrapper_expr (wrapper)
*** 625,630 ****
--- 654,668 ----
/* The C++ frontend already did this for us. */;
temp = TREE_OPERAND (*p, 0);
}
+ else if (TREE_CODE (*p) == INDIRECT_REF)
+ {
+ /* If we're returning a dereference, move the dereference outside
+ the wrapper. */
+ tree ptr = TREE_OPERAND (*p, 0);
+ temp = create_tmp_var (TREE_TYPE (ptr), "retval");
+ *p = build (MODIFY_EXPR, TREE_TYPE (ptr), temp, ptr);
+ temp = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp)), temp);
+ }
else
{
temp = create_tmp_var (TREE_TYPE (wrapper), "retval");
*************** simplify_return_expr (stmt, pre_p)
*** 683,708 ****
if (ret_expr)
{
! if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))))
{
! /* We are trying to return an expression in a void function.
! Move the expression to before the return. */
! simplify_stmt (&ret_expr);
add_tree (ret_expr, pre_p);
TREE_OPERAND (stmt, 0) = NULL_TREE;
}
else
{
! #if defined ENABLE_CHECKING
! /* A return expression is represented by a MODIFY_EXPR node that
! assigns the return value into a RESULT_DECL. */
! if (TREE_CODE (ret_expr) != MODIFY_EXPR
! && TREE_CODE (ret_expr) != INIT_EXPR)
! abort ();
! #endif
!
simplify_expr (&TREE_OPERAND (ret_expr, 1), pre_p, NULL,
is_simple_rhs, fb_rvalue);
}
}
}
--- 721,745 ----
if (ret_expr)
{
! /* We need to pass the full MODIFY_EXPR down so that special handling
! can replace it with something else. FIXME this code is way too
! complicated. */
! simplify_expr (&ret_expr, pre_p, NULL, is_simple_stmt, fb_none);
! if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl)))
! || TREE_CODE (ret_expr) != MODIFY_EXPR)
{
! /* We are trying to return an expression in a void function, or
! our return expression isn't a simple bitwise copy. Move the
! expression to before the return. */
add_tree (ret_expr, pre_p);
TREE_OPERAND (stmt, 0) = NULL_TREE;
}
else
{
! /* Make sure the RHS is really simple. */
simplify_expr (&TREE_OPERAND (ret_expr, 1), pre_p, NULL,
is_simple_rhs, fb_rvalue);
+ TREE_OPERAND (stmt, 0) = ret_expr;
}
}
}
*************** simplify_tree_list (expr_p, pre_p, post_
*** 1089,1097 ****
*EXPR_P should be stored. */
static void
! simplify_cond_expr (expr_p, pre_p)
tree *expr_p;
tree *pre_p;
{
tree tmp = NULL_TREE;
tree expr = *expr_p;
--- 1126,1135 ----
*EXPR_P should be stored. */
static void
! simplify_cond_expr (expr_p, pre_p, target)
tree *expr_p;
tree *pre_p;
+ tree target;
{
tree tmp = NULL_TREE;
tree expr = *expr_p;
*************** simplify_cond_expr (expr_p, pre_p)
*** 1100,1114 ****
the arms. */
if (! VOID_TYPE_P (TREE_TYPE (expr)))
{
! tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
!
! /* Build the then clause, 't1 = a;'. */
! TREE_OPERAND (expr, 1)
! = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1));
/* Build the else clause, 't1 = b;'. */
! TREE_OPERAND (expr, 2)
! = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 2));
TREE_TYPE (expr) = void_type_node;
recalculate_side_effects (expr);
--- 1138,1158 ----
the arms. */
if (! VOID_TYPE_P (TREE_TYPE (expr)))
{
! if (target)
! tmp = target;
! else
! tmp = create_tmp_var (TREE_TYPE (expr), "iftmp");
!
! /* Build the then clause, 't1 = a;'. But don't build an assignment
! if this branch is void; in C++ it can be, if it's a throw. */
! if (TREE_TYPE (TREE_OPERAND (expr, 1)) != void_type_node)
! TREE_OPERAND (expr, 1)
! = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 1));
/* Build the else clause, 't1 = b;'. */
! if (TREE_TYPE (TREE_OPERAND (expr, 2)) != void_type_node)
! TREE_OPERAND (expr, 2)
! = build (MODIFY_EXPR, void_type_node, tmp, TREE_OPERAND (expr, 2));
TREE_TYPE (expr) = void_type_node;
recalculate_side_effects (expr);
*************** simplify_cond_expr (expr_p, pre_p)
*** 1157,1168 ****
*EXPR_P should be stored. */
static void
! simplify_modify_expr (expr_p, pre_p, post_p)
tree *expr_p;
tree *pre_p;
tree *post_p;
{
! tree *from;
#if defined ENABLE_CHECKING
if (TREE_CODE (*expr_p) != MODIFY_EXPR
--- 1201,1215 ----
*EXPR_P should be stored. */
static void
! simplify_modify_expr (expr_p, pre_p, post_p, want_value)
tree *expr_p;
tree *pre_p;
tree *post_p;
+ int want_value;
{
! tree *from_p = &TREE_OPERAND (*expr_p, 1);
! tree *to_p = &TREE_OPERAND (*expr_p, 0);
! tree type = TREE_TYPE (*expr_p);
#if defined ENABLE_CHECKING
if (TREE_CODE (*expr_p) != MODIFY_EXPR
*************** simplify_modify_expr (expr_p, pre_p, pos
*** 1170,1197 ****
abort ();
#endif
/* If we are initializing something from a TARGET_EXPR, strip the
TARGET_EXPR and initialize it directly. */
/* What about code that pulls out the temp and uses it elsewhere? I
think that such code never uses the TARGET_EXPR as an initializer. If
I'm wrong, we'll abort because the temp won't have any RTL. In that
case, I guess we'll need to replace references somehow. */
! from = &TREE_OPERAND (*expr_p, 1);
! if (TREE_CODE (*from) == TARGET_EXPR)
! *from = TARGET_EXPR_INITIAL (*from);
/* The distinction between MODIFY_EXPR and INIT_EXPR is no longer
useful. */
if (TREE_CODE (*expr_p) == INIT_EXPR)
TREE_SET_CODE (*expr_p, MODIFY_EXPR);
! simplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! is_simple_modify_expr_lhs, fb_lvalue);
! simplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p, is_simple_rhs,
! fb_rvalue);
! add_tree (*expr_p, pre_p);
! *expr_p = TREE_OPERAND (*expr_p, 0);
}
--- 1217,1289 ----
abort ();
#endif
+ simplify_expr (to_p, pre_p, post_p, is_simple_modify_expr_lhs, fb_lvalue);
+
/* If we are initializing something from a TARGET_EXPR, strip the
TARGET_EXPR and initialize it directly. */
/* What about code that pulls out the temp and uses it elsewhere? I
think that such code never uses the TARGET_EXPR as an initializer. If
I'm wrong, we'll abort because the temp won't have any RTL. In that
case, I guess we'll need to replace references somehow. */
! if (TREE_CODE (*from_p) == TARGET_EXPR)
! *from_p = TARGET_EXPR_INITIAL (*from_p);
!
! /* If we're assigning from a ?: expression with ADDRESSABLE type, push
! the assignment down into the branches, since we can't generate a
! temporary of such a type. */
! if (TREE_CODE (*from_p) == COND_EXPR
! && TREE_ADDRESSABLE (TREE_TYPE (*from_p)))
! {
! simplify_cond_expr (from_p, pre_p, *to_p);
! *expr_p = *from_p;
! /* Try again. */
! return;
! }
/* The distinction between MODIFY_EXPR and INIT_EXPR is no longer
useful. */
if (TREE_CODE (*expr_p) == INIT_EXPR)
TREE_SET_CODE (*expr_p, MODIFY_EXPR);
! /* Break out elements of a constructor into separate MODIFY_EXPRs. FIXME
! should also handle arrays/vectors.
! Note that we still need to clear any elements that don't have explicit
! initializers, so we keep the original MODIFY_EXPR, we just remove all
! of the constructor elements. FIXME should try to avoid clearing
! initialized elts, a la store_constructor. */
! if (TREE_CODE (*from_p) == CONSTRUCTOR && !TREE_STATIC (*from_p)
! && (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
! || TREE_CODE (type) == QUAL_UNION_TYPE))
! {
! tree elt_list = CONSTRUCTOR_ELTS (*from_p);
! CONSTRUCTOR_ELTS (*from_p) = NULL_TREE;
! add_tree (*expr_p, pre_p);
! for (; elt_list; elt_list = TREE_CHAIN (elt_list))
! {
! tree purpose = TREE_PURPOSE (elt_list);
! tree value = TREE_VALUE (elt_list);
! tree cref = build (COMPONENT_REF, TREE_TYPE (purpose),
! *to_p, purpose);
! tree init = build (MODIFY_EXPR, TREE_TYPE (purpose), cref, value);
! simplify_expr (&init, pre_p, NULL, is_simple_stmt, fb_none);
! add_tree (init, pre_p);
! }
! *expr_p = TREE_OPERAND (*expr_p, 0);
! return;
! }
!
! /* If this is for a RETURN_EXPR, we can't have any posteffects. */
! if (!want_value)
! post_p = NULL;
!
! simplify_expr (from_p, pre_p, post_p, is_simple_rhs, fb_rvalue);
!
! if (want_value)
! {
! add_tree (*expr_p, pre_p);
! *expr_p = TREE_OPERAND (*expr_p, 0);
! }
}
*************** foreach_stmt (stmt_p, fn)
*** 1465,1471 ****
tree *sub_p = &TREE_OPERAND (*stmt_p, 0);
if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
foreach_stmt (sub_p, fn);
! fn (sub_p);
}
fn (stmt_p);
}
--- 1557,1564 ----
tree *sub_p = &TREE_OPERAND (*stmt_p, 0);
if (TREE_CODE (*sub_p) == COMPOUND_EXPR)
foreach_stmt (sub_p, fn);
! else
! fn (sub_p);
}
fn (stmt_p);
}
*************** create_tmp_var (type, prefix)
*** 1567,1574 ****
ASM_FORMAT_PRIVATE_NAME (tmp_name, (prefix ? prefix : "T"), id_num++);
#if defined ENABLE_CHECKING
! /* If the type is an array, something is wrong. */
! if (TREE_CODE (type) == ARRAY_TYPE)
abort ();
#endif
--- 1660,1668 ----
ASM_FORMAT_PRIVATE_NAME (tmp_name, (prefix ? prefix : "T"), id_num++);
#if defined ENABLE_CHECKING
! /* If the type is an array or a type which must be created by the
! frontend, something is wrong. */
! if (TREE_CODE (type) == ARRAY_TYPE || TREE_ADDRESSABLE (type))
abort ();
#endif
*************** mostly_copy_tree_r (tp, walk_subtrees, d
*** 1840,1850 ****
void *data;
{
enum tree_code code = TREE_CODE (*tp);
! /* Don't unshare decls, blocks, types and SAVE_EXPR nodes. */
if (TREE_CODE_CLASS (code) == 't'
- || TREE_CODE_CLASS (code) == 'd'
- || TREE_CODE_CLASS (code) == 'c'
- || TREE_CODE_CLASS (code) == 'b'
|| code == SAVE_EXPR
|| *tp == empty_stmt_node)
*walk_subtrees = 0;
--- 1934,1941 ----
void *data;
{
enum tree_code code = TREE_CODE (*tp);
! /* Don't unshare types and SAVE_EXPR nodes. */
if (TREE_CODE_CLASS (code) == 't'
|| code == SAVE_EXPR
|| *tp == empty_stmt_node)
*walk_subtrees = 0;
*************** mostly_copy_tree_r (tp, walk_subtrees, d
*** 1861,1866 ****
--- 1952,1969 ----
return NULL_TREE;
}
+ /* Unconditionally make an unshared copy of EXPR. This is used when using
+ stored expressions which span multiple functions, such as BINFO_VTABLE,
+ as the normal unsharing process can't tell that they're shared. */
+
+ tree
+ unshare_expr (expr)
+ tree expr;
+ {
+ walk_tree (&expr, mostly_copy_tree_r, NULL, NULL);
+ return expr;
+ }
+
void
mark_not_simple (expr_p)
tree *expr_p;
*************** mark_not_simple (expr_p)
*** 1868,1873 ****
--- 1971,1988 ----
TREE_NOT_GIMPLE (*expr_p) = 1;
}
+ /* A terser interface for building a representation of a exception
+ specification. */
+
+ tree
+ gimple_build_eh_filter (body, allowed, failure)
+ tree body, allowed, failure;
+ {
+ /* FIXME should the allowed types go in TREE_TYPE? */
+ tree filter = build (EH_FILTER_EXPR, void_type_node, allowed, failure);
+ return build (TRY_CATCH_EXPR, void_type_node, body, filter);
+ }
+
/* Simplify a CLEANUP_POINT_EXPR. Currently this works by adding
WITH_CLEANUP_EXPRs to the prequeue as we encounter cleanups while
simplifying the body, and converting them to TRY_FINALLY_EXPRs when we
*************** simplify_cleanup_point_expr (expr_p, pre
*** 1913,1919 ****
if (TREE_CODE (*container) == COMPOUND_EXPR)
next = TREE_OPERAND (*container, 1);
else
! next = NULL_TREE;
tfe = build (TRY_FINALLY_EXPR, void_type_node,
next, TREE_OPERAND (wce, 1));
--- 2028,2034 ----
if (TREE_CODE (*container) == COMPOUND_EXPR)
next = TREE_OPERAND (*container, 1);
else
! next = empty_stmt_node;
tfe = build (TRY_FINALLY_EXPR, void_type_node,
next, TREE_OPERAND (wce, 1));
*************** simplify_cleanup_point_expr (expr_p, pre
*** 1933,1938 ****
--- 2048,2081 ----
*expr_p = body;
}
+ /* If the language requires some sort of exception protection of cleanup
+ actions (i.e. calling terminate in C++), modify the cleanup to reflect
+ that. */
+
+ tree
+ maybe_protect_cleanup (cleanup)
+ tree cleanup;
+ {
+ #if 0
+ /* Ack! We only want to protect the cleanup if it's run in the EH path.
+ There's currently no reasonable way to express this in GENERIC. FIXME
+ FIXME FIXME! Don't mess with this for now; it will still get handled
+ properly in the expander. */
+ tree protect_cleanup_actions
+ = (lang_protect_cleanup_actions
+ ? (*lang_protect_cleanup_actions) ()
+ : NULL_TREE);
+
+ if (protect_cleanup_actions)
+ /* Wrap cleanups in MUST_NOT_THROW equivalent if appropriate. FIXME
+ perhaps this should be done earlier in the frontend so we don't need
+ a hook. */
+ cleanup = gimple_build_eh_filter (cleanup, NULL_TREE,
+ protect_cleanup_actions);
+ #endif
+ return cleanup;
+ }
+
/* Insert a cleanup marker for simplify_cleanup_point_expr. CLEANUP
is the cleanup action required. */
*************** gimple_push_cleanup (cleanup, pre_p)
*** 1943,1948 ****
--- 2086,2093 ----
{
tree wce;
+ cleanup = maybe_protect_cleanup (cleanup);
+
if (gimple_conditional_context ())
{
/* If we're in a conditional context, this is more complex. We only
*************** simplify_target_expr (expr_p, pre_p, pos
*** 2000,2015 ****
temps list. */
gimple_add_tmp_var (temp);
! /* Add the initialization to pre_p. In some cases, such as C++
! constructors, the initialization will happen by side-effect in init;
! in such cases, init will simplify to temp, so we mustn't build a
! MODIFY_EXPR. */
! simplify_expr (&init, pre_p, post_p, is_simple_rhs, fb_rvalue);
! if (init != temp)
! {
! init = build (MODIFY_EXPR, void_type_node, temp, init);
! add_tree (init, pre_p);
! }
/* If needed, push the cleanup for the temp. */
if (TARGET_EXPR_CLEANUP (targ))
--- 2145,2154 ----
temps list. */
gimple_add_tmp_var (temp);
! /* Build up the initialization and add it to pre_p. */
! init = build (MODIFY_EXPR, void_type_node, temp, init);
! simplify_expr (&init, pre_p, post_p, is_simple_stmt, fb_none);
! add_tree (init, pre_p);
/* If needed, push the cleanup for the temp. */
if (TARGET_EXPR_CLEANUP (targ))
*** ./integrate.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./integrate.c 2003-01-02 11:41:36.000000000 -0500
*************** copy_decl_for_inlining (decl, from_fn, t
*** 394,400 ****
DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
/* The new variable/label has no RTL, yet. */
! SET_DECL_RTL (copy, NULL_RTX);
/* These args would always appear unused, if not for this. */
TREE_USED (copy) = 1;
--- 394,401 ----
DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
/* The new variable/label has no RTL, yet. */
! if (!TREE_STATIC (copy) && !DECL_EXTERNAL (copy))
! SET_DECL_RTL (copy, NULL_RTX);
/* These args would always appear unused, if not for this. */
TREE_USED (copy) = 1;
*************** copy_decl_for_inlining (decl, from_fn, t
*** 405,414 ****
;
else if (DECL_CONTEXT (decl) != from_fn)
/* Things that weren't in the scope of the function we're inlining
! from aren't in the scope we're inlining too, either. */
;
else if (TREE_STATIC (decl))
! /* Function-scoped static variables should say in the original
function. */
;
else
--- 406,415 ----
;
else if (DECL_CONTEXT (decl) != from_fn)
/* Things that weren't in the scope of the function we're inlining
! from aren't in the scope we're inlining to, either. */
;
else if (TREE_STATIC (decl))
! /* Function-scoped static variables should stay in the original
function. */
;
else
*** ./tree-dump.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree-dump.c 2002-12-16 12:09:42.000000000 -0500
*************** dump_switch_p (arg)
*** 850,852 ****
--- 850,878 ----
return 0;
}
+
+ /* Dump FUNCTION_DECL FN as tree dump PHASE. */
+
+ void
+ dump_function (enum tree_dump_index phase, tree fn)
+ {
+ FILE *stream;
+ int flags;
+
+ stream = dump_begin (phase, &flags);
+ if (stream)
+ {
+ fprintf (stream, "\n;; Function %s",
+ (*lang_hooks.decl_printable_name) (fn, 2));
+ fprintf (stream, " (%s)\n",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn)));
+ fprintf (stream, ";; enabled by -%s\n", dump_flag_name (phase));
+ fprintf (stream, "\n");
+
+ if (flags & TDF_RAW)
+ dump_node (fn, TDF_SLIM | flags, stream);
+ else
+ print_generic_stmt (stream, DECL_SAVED_TREE (fn), 0);
+ dump_end (phase, stream);
+ }
+ }
*** ./tree-dump.h.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree-dump.h 2002-12-16 12:10:40.000000000 -0500
*************** extern void queue_and_dump_index
*** 91,95 ****
--- 91,97 ----
PARAMS ((dump_info_p, const char *, tree, int));
extern void queue_and_dump_type
PARAMS ((dump_info_p, tree));
+ extern void dump_function
+ PARAMS ((enum tree_dump_index, tree));
#endif /* ! GCC_TREE_DUMP_H */
*** ./tree-inline.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree-inline.c 2003-01-02 11:41:53.000000000 -0500
*************** static void remap_block PARAMS ((tree *,
*** 112,117 ****
--- 112,119 ----
static void copy_bind_expr PARAMS ((tree *, int *, inline_data *));
static tree find_alloca_call_1 PARAMS ((tree *, int *, void *));
static tree find_alloca_call PARAMS ((tree));
+ static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *));
+ static tree unsave_r PARAMS ((tree *, int *, void *));
/* The approximate number of instructions per statement. This number
need not be particularly accurate; it is used only to make
*************** remap_decl (decl, id)
*** 130,137 ****
--- 132,144 ----
/* We only remap local variables in the current function. */
fn = VARRAY_TOP_TREE (id->fns);
+ #if 0
+ /* We need to remap statics, too, so that they get expanded even if the
+ inline function is never emitted out of line. We might as well also
+ remap extern decls so that they show up in the debug info. */
if (! (*lang_hooks.tree_inlining.auto_var_in_fn_p) (decl, fn))
return NULL_TREE;
+ #endif
/* See if we have remapped this declaration. */
n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
*************** initialize_inlined_parameters (id, args,
*** 603,609 ****
static tree
declare_return_variable (id, return_slot_addr, use_p)
! struct inline_data *id;
tree return_slot_addr;
tree *use_p;
{
--- 610,616 ----
static tree
declare_return_variable (id, return_slot_addr, use_p)
! inline_data *id;
tree return_slot_addr;
tree *use_p;
{
*************** declare_return_variable (id, return_slot
*** 635,640 ****
--- 642,652 ----
promoted, convert it back to the expected type. */
if (TREE_TYPE (var) == TREE_TYPE (TREE_TYPE (fn)))
*use_p = var;
+ else if (TREE_CODE (var) == INDIRECT_REF)
+ *use_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (fn)),
+ TREE_OPERAND (var, 0));
+ else if (TREE_ADDRESSABLE (TREE_TYPE (var)))
+ abort ();
else
*use_p = build1 (NOP_EXPR, TREE_TYPE (TREE_TYPE (fn)), var);
*************** expand_call_inline (tp, walk_subtrees, d
*** 908,913 ****
--- 920,926 ----
{
return_slot_addr = TREE_VALUE (args);
args = TREE_CHAIN (args);
+ TREE_TYPE (expr) = void_type_node;
}
arg_inits = initialize_inlined_parameters (id, args, fn, expr);
*************** walk_tree (tp, func, data, htab_)
*** 1240,1342 ****
{
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. */
! else switch (code)
! {
! case ERROR_MARK:
! case IDENTIFIER_NODE:
! case INTEGER_CST:
! case REAL_CST:
! case VECTOR_CST:
! case STRING_CST:
! case REAL_TYPE:
! case COMPLEX_TYPE:
! case VECTOR_TYPE:
! case VOID_TYPE:
! case BOOLEAN_TYPE:
! case UNION_TYPE:
! case ENUMERAL_TYPE:
! case BLOCK:
! case RECORD_TYPE:
! /* None of thse have subtrees other than those already walked
! above. */
! break;
! case POINTER_TYPE:
! case REFERENCE_TYPE:
! WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
! break;
! case TREE_LIST:
! WALK_SUBTREE (TREE_VALUE (*tp));
! WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
! break;
!
! case TREE_VEC:
! {
! int len = TREE_VEC_LENGTH (*tp);
! if (len == 0)
break;
! /* Walk all elements but the first. */
! while (--len)
! WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
!
! /* Now walk the first one as a tail call. */
! WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
! }
!
! case COMPLEX_CST:
! WALK_SUBTREE (TREE_REALPART (*tp));
! WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
!
! case CONSTRUCTOR:
! WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
!
! case METHOD_TYPE:
! WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
! /* Fall through. */
!
! case FUNCTION_TYPE:
! WALK_SUBTREE (TREE_TYPE (*tp));
! {
! tree arg = TYPE_ARG_TYPES (*tp);
!
! /* We never want to walk into default arguments. */
! for (; arg; arg = TREE_CHAIN (arg))
! WALK_SUBTREE (TREE_VALUE (arg));
! }
! break;
!
! case ARRAY_TYPE:
! WALK_SUBTREE (TREE_TYPE (*tp));
! WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
!
! case INTEGER_TYPE:
! WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
! WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
!
! case OFFSET_TYPE:
! 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));
! default:
! abort ();
}
/* We didn't find what we were looking for. */
--- 1253,1358 ----
{
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)
! {
! case ERROR_MARK:
! case IDENTIFIER_NODE:
! case INTEGER_CST:
! case REAL_CST:
! case VECTOR_CST:
! case STRING_CST:
! case REAL_TYPE:
! case COMPLEX_TYPE:
! case VECTOR_TYPE:
! case VOID_TYPE:
! case BOOLEAN_TYPE:
! case UNION_TYPE:
! case ENUMERAL_TYPE:
! case BLOCK:
! case RECORD_TYPE:
! /* None of thse have subtrees other than those already walked
! above. */
! break;
! case POINTER_TYPE:
! case REFERENCE_TYPE:
! WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
! break;
! case TREE_LIST:
! WALK_SUBTREE (TREE_VALUE (*tp));
! WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
break;
! case TREE_VEC:
! {
! int len = TREE_VEC_LENGTH (*tp);
!
! if (len == 0)
! break;
!
! /* Walk all elements but the first. */
! while (--len)
! WALK_SUBTREE (TREE_VEC_ELT (*tp, len));
!
! /* Now walk the first one as a tail call. */
! WALK_SUBTREE_TAIL (TREE_VEC_ELT (*tp, 0));
! }
!
! case COMPLEX_CST:
! WALK_SUBTREE (TREE_REALPART (*tp));
! WALK_SUBTREE_TAIL (TREE_IMAGPART (*tp));
!
! case CONSTRUCTOR:
! WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
!
! case METHOD_TYPE:
! WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
! /* Fall through. */
!
! case FUNCTION_TYPE:
! WALK_SUBTREE (TREE_TYPE (*tp));
! {
! tree arg = TYPE_ARG_TYPES (*tp);
!
! /* We never want to walk into default arguments. */
! for (; arg; arg = TREE_CHAIN (arg))
! WALK_SUBTREE (TREE_VALUE (arg));
! }
! break;
! case ARRAY_TYPE:
! WALK_SUBTREE (TREE_TYPE (*tp));
! WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
!
! case INTEGER_TYPE:
! WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
! WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
!
! case OFFSET_TYPE:
! 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));
!
! default:
! abort ();
! }
}
/* We didn't find what we were looking for. */
*************** copy_tree_r (tp, walk_subtrees, data)
*** 1404,1409 ****
--- 1420,1427 ----
else if (TREE_CODE_CLASS (code) == 't' && !variably_modified_type_p (*tp))
/* Types only need to be copied if they are variably modified. */
*walk_subtrees = 0;
+ else if (TREE_CODE_CLASS (code) == 'd')
+ *walk_subtrees = 0;
return NULL_TREE;
}
*************** add_stmt_to_compound (existing, type, st
*** 1467,1469 ****
--- 1485,1605 ----
else
return stmt;
}
+
+ /* Called via walk_tree. If *TP points to a DECL_STMT for a local
+ declaration, copies the declaration and enters it in the splay_tree
+ in DATA (which is really an `inline_data *'). */
+
+ static tree
+ mark_local_for_remap_r (tp, walk_subtrees, data)
+ tree *tp;
+ int *walk_subtrees ATTRIBUTE_UNUSED;
+ void *data;
+ {
+ tree t = *tp;
+ inline_data *id = (inline_data *) data;
+ splay_tree st = id->decl_map;
+ 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 (decl)
+ {
+ tree copy;
+
+ /* Make a copy. */
+ copy = copy_decl_for_inlining (decl,
+ DECL_CONTEXT (decl),
+ DECL_CONTEXT (decl));
+
+ /* Remember the copy. */
+ splay_tree_insert (st,
+ (splay_tree_key) decl,
+ (splay_tree_value) copy);
+ }
+
+ return NULL_TREE;
+ }
+
+ /* Called via walk_tree when an expression is unsaved. Using the
+ splay_tree pointed to by ST (which is really a `splay_tree'),
+ remaps all local declarations to appropriate replacements. */
+
+ static tree
+ unsave_r (tp, walk_subtrees, data)
+ tree *tp;
+ int *walk_subtrees;
+ void *data;
+ {
+ inline_data *id = (inline_data *) data;
+ splay_tree st = id->decl_map;
+ splay_tree_node n;
+
+ /* Only a local declaration (variable or label). */
+ if ((TREE_CODE (*tp) == VAR_DECL && !TREE_STATIC (*tp))
+ || TREE_CODE (*tp) == LABEL_DECL)
+ {
+ /* Lookup the declaration. */
+ n = splay_tree_lookup (st, (splay_tree_key) *tp);
+
+ /* If it's there, remap it. */
+ if (n)
+ *tp = (tree) n->value;
+ }
+ else if (TREE_CODE (*tp) == BIND_EXPR)
+ copy_bind_expr (tp, walk_subtrees, id);
+ else if (TREE_CODE (*tp) == SAVE_EXPR)
+ remap_save_expr (tp, st, current_function_decl, walk_subtrees);
+ else
+ {
+ copy_tree_r (tp, walk_subtrees, NULL);
+
+ /* Do whatever unsaving is required. */
+ unsave_expr_1 (*tp);
+ }
+
+ /* Keep iterating. */
+ return NULL_TREE;
+ }
+
+ /* Default lang hook for "unsave_expr_now". Copies everything in EXPR and replaces
+ variables, labels and SAVE_EXPRs local to EXPR. */
+
+ tree
+ lhd_unsave_expr_now (expr)
+ tree expr;
+ {
+ inline_data id;
+
+ /* There's nothing to do for NULL_TREE. */
+ if (expr == 0)
+ return expr;
+
+ /* Set up ID. */
+ memset (&id, 0, sizeof (id));
+ VARRAY_TREE_INIT (id.fns, 1, "fns");
+ VARRAY_PUSH_TREE (id.fns, current_function_decl);
+ id.decl_map = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
+
+ /* Walk the tree once to find local labels. */
+ walk_tree_without_duplicates (&expr, mark_local_for_remap_r, &id);
+
+ /* Walk the tree again, copying, remapping, and unsaving. */
+ walk_tree (&expr, unsave_r, &id, NULL);
+
+ /* Clean up. */
+ splay_tree_delete (id.decl_map);
+
+ return expr;
+ }
*** ./tree.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree.c 2003-01-02 11:41:55.000000000 -0500
*************** unsave_expr_1 (expr)
*** 1531,1588 ****
}
}
- /* Default lang hook for "unsave_expr_now". */
-
- tree
- lhd_unsave_expr_now (expr)
- tree expr;
- {
- enum tree_code code;
-
- /* There's nothing to do for NULL_TREE. */
- if (expr == 0)
- return expr;
-
- unsave_expr_1 (expr);
-
- code = TREE_CODE (expr);
- switch (TREE_CODE_CLASS (code))
- {
- case 'c': /* a constant */
- case 't': /* a type node */
- case 'd': /* A decl node */
- case 'b': /* A block node */
- break;
-
- case 'x': /* miscellaneous: e.g., identifier, TREE_LIST or ERROR_MARK. */
- if (code == TREE_LIST)
- {
- lhd_unsave_expr_now (TREE_VALUE (expr));
- lhd_unsave_expr_now (TREE_CHAIN (expr));
- }
- break;
-
- case 'e': /* an expression */
- case 'r': /* a reference */
- case 's': /* an expression with side effects */
- case '<': /* a comparison expression */
- case '2': /* a binary arithmetic expression */
- case '1': /* a unary arithmetic expression */
- {
- int i;
-
- for (i = first_rtl_op (code) - 1; i >= 0; i--)
- lhd_unsave_expr_now (TREE_OPERAND (expr, i));
- }
- break;
-
- default:
- abort ();
- }
-
- return expr;
- }
-
/* Return 0 if it is safe to evaluate EXPR multiple times,
return 1 if it is safe if EXPR is unsaved afterward, or
return 2 if it is completely unsafe.
--- 1531,1536 ----
*************** unsafe_for_reeval (expr)
*** 1619,1629 ****
{
case SAVE_EXPR:
case RTL_EXPR:
/* A label can only be emitted once. */
case LABEL_EXPR:
case BIND_EXPR:
! return 2;
case TREE_LIST:
for (exp = expr; exp != 0; exp = TREE_CHAIN (exp))
--- 1567,1581 ----
{
case SAVE_EXPR:
case RTL_EXPR:
+ return 2;
/* A label can only be emitted once. */
case LABEL_EXPR:
+ return 1;
+
case BIND_EXPR:
! unsafeness = 1;
! break;
case TREE_LIST:
for (exp = expr; exp != 0; exp = TREE_CHAIN (exp))
*** ./tree-simple.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree-simple.c 2003-01-02 11:41:54.000000000 -0500
*************** is_simple_unary_expr (t)
*** 444,450 ****
/* Additions to the original grammar. Allow NON_LVALUE_EXPR and
EXPR_WITH_FILE_LOCATION wrappers. */
if (TREE_CODE (t) == EXPR_WITH_FILE_LOCATION
! || TREE_CODE (t) == NON_LVALUE_EXPR)
return is_simple_unary_expr (TREE_OPERAND (t, 0));
if (is_simple_varname (t) || is_simple_const (t))
--- 444,451 ----
/* Additions to the original grammar. Allow NON_LVALUE_EXPR and
EXPR_WITH_FILE_LOCATION wrappers. */
if (TREE_CODE (t) == EXPR_WITH_FILE_LOCATION
! || TREE_CODE (t) == NON_LVALUE_EXPR
! || TREE_CODE (t) == VTABLE_REF)
return is_simple_unary_expr (TREE_OPERAND (t, 0));
if (is_simple_varname (t) || is_simple_const (t))
*************** is_simple_id (t)
*** 682,689 ****
--- 683,693 ----
return (TREE_CODE (t) == VAR_DECL
|| TREE_CODE (t) == FUNCTION_DECL
|| TREE_CODE (t) == PARM_DECL
+ || TREE_CODE (t) == RESULT_DECL
|| TREE_CODE (t) == FIELD_DECL
|| TREE_CODE (t) == LABEL_DECL
+ /* FIXME make this a decl. */
+ || TREE_CODE (t) == EXC_PTR_EXPR
/* Allow the address of a function decl. */
|| (TREE_CODE (t) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
*************** right_assocify_expr (top)
*** 897,903 ****
TREE_SIDE_EFFECTS (lhs) = 1;
}
! /* Walk through the rhs chain from there until we find something
with a different code. In this case, c. */
for (q = &TREE_OPERAND (lhs, 1); TREE_CODE (*q) == code;
q = &TREE_OPERAND (*q, 1))
--- 901,907 ----
TREE_SIDE_EFFECTS (lhs) = 1;
}
! /* Walk through the op1 chain from there until we find something
with a different code. In this case, c. */
for (q = &TREE_OPERAND (lhs, 1); TREE_CODE (*q) == code;
q = &TREE_OPERAND (*q, 1))
*** ./tree-pretty-print.c.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree-pretty-print.c 2003-01-02 15:50:43.000000000 -0500
*************** Software Foundation, 59 Temple Place - S
*** 29,34 ****
--- 29,35 ----
#include "real.h"
#include "hashtab.h"
#include "tree-flow.h"
+ #include "langhooks.h"
/* Local functions, macros and variables. */
static int op_prio PARAMS ((tree));
*************** static void print_struct_decl PARAMS (
*** 45,68 ****
int));
static void dump_block_info PARAMS ((output_buffer *,
basic_block, int));
#define INDENT(SPACE) do { \
int i; for (i = 0; i<SPACE; i++) output_add_space (buffer); } while (0)
! #define NIY do { \
! output_add_string (buffer, "<<< Unknown tree >>>\n"); } while (0)
#define PRINT_FUNCTION_NAME(NODE) output_printf \
(buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
! IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (NODE, 0))) : \
! IDENTIFIER_POINTER (DECL_NAME (NODE)))
static output_buffer buffer;
static int initialized = 0;
static int last_bb;
static bool dumping_stmts;
/* Print tree T, and its successors, on file FILE. FLAGS specifies details
to show in the dump. See TDF_* in tree.h. */
--- 46,91 ----
int));
static void dump_block_info PARAMS ((output_buffer *,
basic_block, int));
+ static void do_niy PARAMS ((output_buffer *,
+ tree));
#define INDENT(SPACE) do { \
int i; for (i = 0; i<SPACE; i++) output_add_space (buffer); } while (0)
! #define NIY do_niy(buffer,node)
#define PRINT_FUNCTION_NAME(NODE) output_printf \
(buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ? \
! (*lang_hooks.decl_printable_name) (TREE_OPERAND (NODE, 0), 1) : \
! (*lang_hooks.decl_printable_name) (NODE, 1))
static output_buffer buffer;
static int initialized = 0;
static int last_bb;
static bool dumping_stmts;
+ /* Try to print something for an unknown tree code. */
+ static void
+ do_niy (buffer, node)
+ output_buffer *buffer;
+ tree node;
+ {
+ int i, len;
+
+ output_add_string (buffer, "<<< Unknown tree: ");
+ output_add_string (buffer, tree_code_name[(int) TREE_CODE (node)]);
+
+ len = first_rtl_op (TREE_CODE (node));
+ for (i = 0; i < len; ++i)
+ {
+ newline_and_indent (buffer, 2);
+ dump_generic_node (buffer, TREE_OPERAND (node, i), 2, 0);
+ }
+
+ output_add_string (buffer, " >>>\n");
+ }
+
/* Print tree T, and its successors, on file FILE. FLAGS specifies details
to show in the dump. See TDF_* in tree.h. */
*************** dump_generic_node (buffer, node, spc, fl
*** 288,296 ****
{
output_add_character (buffer, '[');
if (TYPE_SIZE (tmp))
! output_decimal (buffer,
! TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
! TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
output_add_character (buffer, ']');
tmp = TREE_TYPE (tmp);
}
--- 311,326 ----
{
output_add_character (buffer, '[');
if (TYPE_SIZE (tmp))
! {
! tree size = TYPE_SIZE (tmp);
! if (TREE_CODE (size) == INTEGER_CST)
! output_decimal (buffer,
! TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
! TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
! else if (TREE_CODE (size) == MULT_EXPR)
! dump_generic_node (buffer, TREE_OPERAND (size, 0), spc, flags);
! /* else punt. */
! }
output_add_character (buffer, ']');
tmp = TREE_TYPE (tmp);
}
*************** dump_generic_node (buffer, node, spc, fl
*** 704,710 ****
output_add_character (buffer, '(');
op1 = TREE_OPERAND (node, 1);
if (op1)
! dump_generic_node (buffer, op1, 0, flags);
output_add_character (buffer, ')');
break;
--- 734,740 ----
output_add_character (buffer, '(');
op1 = TREE_OPERAND (node, 1);
if (op1)
! dump_generic_node (buffer, op1, spc, flags);
output_add_character (buffer, ')');
break;
*************** dump_generic_node (buffer, node, spc, fl
*** 717,723 ****
break;
case CLEANUP_POINT_EXPR:
! NIY;
break;
case PLACEHOLDER_EXPR:
--- 747,755 ----
break;
case CLEANUP_POINT_EXPR:
! output_add_string (buffer, "<<cleanup_point ");
! dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags);
! output_add_string (buffer, ">>");
break;
case PLACEHOLDER_EXPR:
*************** dump_generic_node (buffer, node, spc, fl
*** 992,997 ****
--- 1024,1047 ----
output_add_string (buffer, "}");
break;
+ case CATCH_EXPR:
+ output_add_string (buffer, "catch (");
+ dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags);
+ output_add_string (buffer, ")");
+ newline_and_indent (buffer, spc+2);
+ output_add_string (buffer, "{");
+ newline_and_indent (buffer, spc+4);
+ dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags);
+ newline_and_indent (buffer, spc+2);
+ output_add_string (buffer, "}");
+ break;
+
+ case EH_FILTER_EXPR:
+ output_add_string (buffer, "<<<eh_filter (");
+ dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags);
+ output_add_string (buffer, ")>>>");
+ break;
+
case GOTO_SUBROUTINE_EXPR:
NIY;
break;
*************** dump_generic_node (buffer, node, spc, fl
*** 1057,1063 ****
break;
case EXC_PTR_EXPR:
! NIY;
break;
case LOOP_EXPR:
--- 1107,1113 ----
break;
case EXC_PTR_EXPR:
! output_add_string (buffer, "<<<exception object>>>");
break;
case LOOP_EXPR:
*************** dump_generic_node (buffer, node, spc, fl
*** 1175,1180 ****
--- 1225,1240 ----
output_add_character (buffer, ':');
break;
+ case VTABLE_REF:
+ output_add_string (buffer, "VTABLE_REF <(");
+ dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags);
+ output_add_string (buffer, "),");
+ dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags);
+ output_add_character (buffer, ',');
+ dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags);
+ output_add_character (buffer, '>');
+ break;
+
default:
NIY;
}
*************** op_prio (op)
*** 1434,1439 ****
--- 1494,1500 ----
case FIX_CEIL_EXPR:
case FIX_FLOOR_EXPR:
case FIX_ROUND_EXPR:
+ case TARGET_EXPR:
return 14;
case CALL_EXPR:
*** ./tree-simple.h.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree-simple.h 2002-12-15 14:39:17.000000000 -0500
*************** void gimple_push_bind_expr PARAM
*** 96,101 ****
--- 96,104 ----
void gimple_pop_bind_expr PARAMS ((void));
void mark_not_simple PARAMS ((tree *));
void unshare_all_trees PARAMS ((tree));
+ tree voidify_wrapper_expr PARAMS ((tree));
+ tree gimple_build_eh_filter PARAMS ((tree, tree, tree));
+ tree maybe_protect_cleanup PARAMS ((tree));
/* Iterator object for GIMPLE statements. */
*************** gsi_stmt (i)
*** 165,170 ****
--- 168,175 ----
gimple_stmt_iterator i;
{
tree t = *(gsi_stmt_ptr (i));
+ STRIP_WFL (t);
+ STRIP_NOPS (t);
if (t == empty_stmt_node || t == error_mark_node)
t = NULL_TREE;
return t;
*** ./tree.def.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree.def 2003-01-02 15:30:19.000000000 -0500
*************** DEFTREECODE (CASE_LABEL_EXPR, "case_labe
*** 863,868 ****
--- 863,878 ----
for the statement. */
DEFTREECODE (ASM_EXPR, "asm_expr", 's', 4)
+ /* Used to represent a typed exception handler. CATCH_TYPES is the type (or
+ list of types) handled, and CATCH_BODY is the code for the handler. */
+ DEFTREECODE (CATCH_EXPR, "catch_expr", 's', 2)
+
+ /* Used to represent an exception specification. EH_FILTER_TYPES is a list
+ of allowed types, and EH_FILTER_FAILURE is an expression to evaluate on
+ failure. EH_FILTER_MUST_NOT_THROW controls which range type to use when
+ expanding. */
+ DEFTREECODE (EH_FILTER_EXPR, "eh_filter_expr", 's', 2)
+
/*
Local variables:
mode:c
*** ./tree.h.~1~ 2003-01-02 12:14:45.000000000 -0500
--- ./tree.h 2003-01-02 11:41:55.000000000 -0500
*************** struct tree_common GTY(())
*** 188,193 ****
--- 188,194 ----
TREE_LIST elements of a block's cleanup list.
ASM_INPUT_P in
ASM_EXPR
+ EH_FILTER_MUST_NOT_THROW in EH_FILTER_EXPR
public_flag:
*************** struct tree_vec GTY(())
*** 872,878 ****
#define SAVE_EXPR_NOPLACEHOLDER(NODE) TREE_UNSIGNED (SAVE_EXPR_CHECK (NODE))
/* Nonzero if the SAVE_EXPRs value should be kept, even if it occurs
both in normal code and in a handler. (Normally, in a handler, all
! SAVE_EXPRs are unsaved, meaning that there values are
recalculated.) */
#define SAVE_EXPR_PERSISTENT_P(NODE) TREE_ASM_WRITTEN (SAVE_EXPR_CHECK (NODE))
--- 873,879 ----
#define SAVE_EXPR_NOPLACEHOLDER(NODE) TREE_UNSIGNED (SAVE_EXPR_CHECK (NODE))
/* Nonzero if the SAVE_EXPRs value should be kept, even if it occurs
both in normal code and in a handler. (Normally, in a handler, all
! SAVE_EXPRs are unsaved, meaning that their values are
recalculated.) */
#define SAVE_EXPR_PERSISTENT_P(NODE) TREE_ASM_WRITTEN (SAVE_EXPR_CHECK (NODE))
*************** struct tree_vec GTY(())
*** 971,976 ****
--- 972,986 ----
the given label expression. */
#define LABEL_EXPR_LABEL(NODE) TREE_OPERAND (LABEL_EXPR_CHECK (NODE), 0)
+ /* CATCH_EXPR accessors. */
+ #define CATCH_TYPES(NODE) TREE_OPERAND (CATCH_EXPR_CHECK (NODE), 0)
+ #define CATCH_BODY(NODE) TREE_OPERAND (CATCH_EXPR_CHECK (NODE), 1)
+
+ /* EH_FILTER_EXPR accessors. */
+ #define EH_FILTER_TYPES(NODE) TREE_OPERAND (EH_FILTER_EXPR_CHECK (NODE), 0)
+ #define EH_FILTER_FAILURE(NODE) TREE_OPERAND (EH_FILTER_EXPR_CHECK (NODE), 1)
+ #define EH_FILTER_MUST_NOT_THROW(NODE) TREE_STATIC (EH_FILTER_EXPR_CHECK (NODE))
+
struct tree_exp GTY(())
{
struct tree_common common;
*************** const char *dump_flag_name PARAMS ((enu
*** 3285,3290 ****
--- 3295,3301 ----
extern int simplify_function_tree PARAMS ((tree));
extern const char *get_name PARAMS ((tree));
+ extern tree unshare_expr PARAMS ((tree));
/* Redefine abort to report an internal error w/o coredump, and
reporting the location of the error in the source file. This logic