diff options
Diffstat (limited to 'gcc/java')
-rw-r--r-- | gcc/java/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/java/java-gimplify.c | 43 | ||||
-rw-r--r-- | gcc/java/java-tree.def | 8 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 10 | ||||
-rw-r--r-- | gcc/java/jcf-write.c | 4 | ||||
-rw-r--r-- | gcc/java/lang.c | 11 | ||||
-rw-r--r-- | gcc/java/parse.y | 7 |
7 files changed, 93 insertions, 12 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index fa30e09..ab96bfc 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,25 @@ +2004-11-24 Steven Bosscher <stevenb@suse.de> + + * java-gimplify.c (java_gimplify_labeled_block_expr): New function. + (java_gimplify_exit_block_expr): New function. + (java_gimplify_expr): Use them to gimplify EXIT_BLOCK_EXPR and + LABELED_BLOCK_EXPR. + * java-tree.def (LABELED_BLOCK_EXPR): Moved from tree.def. + (EXIT_BLOCK_EXPR): Likewise. + * java-tree.h (LABELED_BLOCK_LABEL): Moved from tree.h. + (LABELED_BLOCK_BODY): Likewise. + (EXIT_BLOCK_LABELED_BLOCK): Likewise. + * jcf-write.c (generate_bytecode_insns): Don't handle the unused + EXIT_BLOCK_RETURN operand. Use EXIT_BLOCK_LABELED_BLOCK instead of + TREE_OPERAND. + * lang.c (java_tree_inlining_walk_subtrees): Handle EXIT_BLOCK_EXPR. + (java_dump_tree): Use LABELED_BLOCK_LABEL, LABELED_BLOCK_BODY, and + EXIT_BLOCK_LABELED_BLOCK instead of TREE_OPERAND. Don't handle the + second operand of EXIT_BLOCK_EXPR. + * parse.y (find_expr_with_wfl): Use LABELED_BLOCK_BODY instead of + TREE_OPERAND. + (build_bc_statement): Use build1 to build EXIT_BLOCK_EXPR nodes. + 2004-11-23 Ben Elliston <bje@au.ibm.com> * xref.h (xref_flag_value): Remove. diff --git a/gcc/java/java-gimplify.c b/gcc/java/java-gimplify.c index c8130a7..51fbb84 100644 --- a/gcc/java/java-gimplify.c +++ b/gcc/java/java-gimplify.c @@ -32,6 +32,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "tree-gimple.h" #include "toplev.h" +static tree java_gimplify_labeled_block_expr (tree); +static tree java_gimplify_exit_block_expr (tree); static tree java_gimplify_case_expr (tree); static tree java_gimplify_default_expr (tree); static tree java_gimplify_block (tree); @@ -79,6 +81,14 @@ java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED, SET_EXPR_LOCATION (*expr_p, input_location); break; + case LABELED_BLOCK_EXPR: + *expr_p = java_gimplify_labeled_block_expr (*expr_p); + break; + + case EXIT_BLOCK_EXPR: + *expr_p = java_gimplify_exit_block_expr (*expr_p); + break; + case CASE_EXPR: *expr_p = java_gimplify_case_expr (*expr_p); break; @@ -164,6 +174,39 @@ java_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED, return GS_OK; } +/* Gimplify a LABELED_BLOCK_EXPR into a LABEL_EXPR following + a (possibly empty) body. */ + +static tree +java_gimplify_labeled_block_expr (tree expr) +{ + tree body = LABELED_BLOCK_BODY (expr); + tree label = LABELED_BLOCK_LABEL (expr); + tree t; + + DECL_CONTEXT (label) = current_function_decl; + t = build (LABEL_EXPR, void_type_node, label); + if (body != NULL_TREE) + t = build (COMPOUND_EXPR, void_type_node, body, t); + return t; +} + +/* Gimplify a EXIT_BLOCK_EXPR into a GOTO_EXPR. */ + +static tree +java_gimplify_exit_block_expr (tree expr) +{ + tree labeled_block = EXIT_BLOCK_LABELED_BLOCK (expr); + tree label; + + /* First operand must be a LABELED_BLOCK_EXPR, which should + already be lowered (or partially lowered) when we get here. */ + gcc_assert (TREE_CODE (labeled_block) == LABELED_BLOCK_EXPR); + + label = LABELED_BLOCK_LABEL (labeled_block); + return build1 (GOTO_EXPR, void_type_node, label); +} + /* This is specific to the bytecode compiler. If a variable has LOCAL_SLOT_P set, replace an assignment to it with an assignment to the corresponding variable that holds all its aliases. */ diff --git a/gcc/java/java-tree.def b/gcc/java/java-tree.def index 1cdbc57..ac8f83a 100644 --- a/gcc/java/java-tree.def +++ b/gcc/java/java-tree.def @@ -41,6 +41,14 @@ DEFTREECODE (NEW_CLASS_EXPR, "new_class_expr", tcc_expression, 3) /* Defines `this' as an expression. */ DEFTREECODE (THIS_EXPR, "this", tcc_unary, 0) +/* A labeled block. Operand 0 is the label that will be generated to + mark the end of the block. Operand 1 is the labeled block body. */ +DEFTREECODE (LABELED_BLOCK_EXPR, "labeled_block_expr", tcc_expression, 2) + +/* Exit a labeled block, possibly returning a value. Operand 0 is a + LABELED_BLOCK_EXPR to exit. */ +DEFTREECODE (EXIT_BLOCK_EXPR, "exit_block_expr", tcc_statement, 1) + /* Case statement expression. Operand 1 is the case value. */ DEFTREECODE (CASE_EXPR, "case", tcc_expression, 1) diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index a43bc2e..558d0f5 100644 --- a/gcc/java/java-tree.h +++ b/gcc/java/java-tree.h @@ -1815,6 +1815,16 @@ enum #undef DEBUG_JAVA_BINDING_LEVELS +/* In a LABELED_BLOCK_EXPR node. */ +#define LABELED_BLOCK_LABEL(NODE) \ + TREE_OPERAND_CHECK_CODE (NODE, LABELED_BLOCK_EXPR, 0) +#define LABELED_BLOCK_BODY(NODE) \ + TREE_OPERAND_CHECK_CODE (NODE, LABELED_BLOCK_EXPR, 1) + +/* In an EXIT_BLOCK_EXPR node. */ +#define EXIT_BLOCK_LABELED_BLOCK(NODE) \ + TREE_OPERAND_CHECK_CODE (NODE, EXIT_BLOCK_EXPR, 0) + /* In an EXPR_WITH_FILE_LOCATION node. */ #define EXPR_WFL_EMIT_LINE_NOTE(NODE) \ (EXPR_WITH_FILE_LOCATION_CHECK (NODE)->common.public_flag) diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index 5f842ae..638f47b 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -1898,8 +1898,7 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state) case EXIT_BLOCK_EXPR: { struct jcf_block *label = state->labeled_blocks; - if (TREE_OPERAND (exp, 1) != NULL) goto notimpl; - while (label->u.labeled_block != TREE_OPERAND (exp, 0)) + while (label->u.labeled_block != EXIT_BLOCK_LABELED_BLOCK (exp)) label = label->next; call_cleanups (label, state); emit_goto (label, state); @@ -2653,7 +2652,6 @@ generate_bytecode_insns (tree exp, int target, struct jcf_partial *state) } } /* fall through */ - notimpl: default: error("internal error in generate_bytecode_insn - tree code not implemented: %s", tree_code_name [(int) TREE_CODE (exp)]); diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 39277ac..ad388da 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -731,6 +731,10 @@ java_tree_inlining_walk_subtrees (tree *tp ATTRIBUTE_UNUSED, WALK_SUBTREE (BLOCK_EXPR_BODY (t)); return NULL_TREE; + case EXIT_BLOCK_EXPR: + *subtrees = 0; + return NULL_TREE; + default: return NULL_TREE; } @@ -921,13 +925,12 @@ java_dump_tree (void *dump_info, tree t) return true; case LABELED_BLOCK_EXPR: - dump_child ("label", TREE_OPERAND (t, 0)); - dump_child ("block", TREE_OPERAND (t, 1)); + dump_child ("label", LABELED_BLOCK_LABEL (t)); + dump_child ("block", LABELED_BLOCK_BODY (t)); return true; case EXIT_BLOCK_EXPR: - dump_child ("block", TREE_OPERAND (t, 0)); - dump_child ("val", TREE_OPERAND (t, 1)); + dump_child ("block", EXIT_BLOCK_LABELED_BLOCK (t)); return true; case BLOCK: diff --git a/gcc/java/parse.y b/gcc/java/parse.y index d02a448..1c1a686 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -3255,7 +3255,7 @@ find_expr_with_wfl (tree node) continue; case LABELED_BLOCK_EXPR: - node = TREE_OPERAND (node, 1); + node = LABELED_BLOCK_BODY (node); continue; default: @@ -11747,8 +11747,6 @@ java_complete_lhs (tree node) return node; case EXIT_BLOCK_EXPR: - /* We don't complete operand 1, because it's the return value of - the EXIT_BLOCK_EXPR which doesn't exist it Java */ return patch_bc_statement (node); case CASE_EXPR: @@ -15269,8 +15267,7 @@ build_bc_statement (int location, int is_break, tree name) } /* Unlabeled break/continue will be handled during the break/continue patch operation */ - break_continue = build2 (EXIT_BLOCK_EXPR, NULL_TREE, - label_block_expr, NULL_TREE); + break_continue = build1 (EXIT_BLOCK_EXPR, NULL_TREE, label_block_expr); IS_BREAK_STMT_P (break_continue) = is_break; TREE_SIDE_EFFECTS (break_continue) = 1; |