diff options
author | Alexandre Petit-Bianco <apbianco@cygnus.com> | 1999-08-19 00:53:20 +0000 |
---|---|---|
committer | Alexandre Petit-Bianco <apbianco@gcc.gnu.org> | 1999-08-18 17:53:20 -0700 |
commit | 5cbdba642487ff5d1502727b039a1bcccca7d196 (patch) | |
tree | a799200db51a3bcae06c0d28c4ddc0ade0f053ad /gcc/java/parse.y | |
parent | 0aa487d53420557a37388ac275a5855fcc5ae089 (diff) | |
download | gcc-5cbdba642487ff5d1502727b039a1bcccca7d196.zip gcc-5cbdba642487ff5d1502727b039a1bcccca7d196.tar.gz gcc-5cbdba642487ff5d1502727b039a1bcccca7d196.tar.bz2 |
[multiple changes]
Wed Aug 18 13:17:15 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
* class.c (emit_register_class): Removed unnecessary call to
start_sequence.
* parse.y (labeled_block_contains_loop_p): Removed unused local
variable.
Tue Aug 17 22:51:44 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
* parse.y (java_refold): Added prototype.
Tue Aug 17 21:48:41 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
* parse.y (BINOP_COMPOUND_CANDIDATES): New macro.
(java_stabilize_reference): Removed unnecessary `else'.
(java_complete_lhs): Set flag to remember boolean. Call
java_refold. Added comments.
(java_decl_equiv): New function.
(binop_compound_p): Likewise.
(java_refold): Likewise.
(patch_unaryop): Striped static field access assigned to decl and
op. Changed promotion scheme for ++/-- operators.
(search_loop): New function.
(labeled_block_contains_loop_p): Likewise.
(patch_loop_statement): Call labeled_block_contains_loop_p. Added
comment.
(patch_bc_statement): Call search_loop. Fixed comment.
Mostly bug fixes in some forms of compound expressions and
break/continue target lookup.
From-SVN: r28758
Diffstat (limited to 'gcc/java/parse.y')
-rw-r--r-- | gcc/java/parse.y | 207 |
1 files changed, 170 insertions, 37 deletions
diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 98e8e60..1c63bfd 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -257,6 +257,7 @@ static tree do_unary_numeric_promotion PROTO ((tree)); static char * operator_string PROTO ((tree)); static tree do_merge_string_cste PROTO ((tree, const char *, int, int)); static tree merge_string_cste PROTO ((tree, tree, int)); +static tree java_refold PROTO ((tree)); /* Number of error found so far. */ int java_error_count; @@ -288,6 +289,10 @@ static enum tree_code binop_lookup[19] = binop_lookup [((VALUE) - PLUS_TK)% \ (sizeof (binop_lookup) / sizeof (binop_lookup[0]))] +/* This is the end index for binary operators that can also be used + in compound assignements. */ +#define BINOP_COMPOUND_CANDIDATES 11 + /* Fake WFL used to report error message. It is initialized once if needed and reused with it's location information is overriden. */ tree wfl_operator = NULL_TREE; @@ -7879,8 +7884,7 @@ java_stabilize_reference (node) TREE_OPERAND (node, 1) = java_stabilize_reference (op1); return node; } - else - return stabilize_reference (node); + return stabilize_reference (node); } /* Patch tree nodes in a function body. When a BLOCK is found, push @@ -8330,14 +8334,17 @@ java_complete_lhs (node) if (TREE_OPERAND (node, 0) == error_mark_node) return error_mark_node; - if (COMPOUND_ASSIGN_P (wfl_op2)) + flag = COMPOUND_ASSIGN_P (wfl_op2); + if (flag) { tree lvalue = java_stabilize_reference (TREE_OPERAND (node, 0)); /* Hand stablize the lhs on both places */ TREE_OPERAND (node, 0) = lvalue; - TREE_OPERAND (TREE_OPERAND (node, 1), 0) = lvalue; + TREE_OPERAND (TREE_OPERAND (node, 1), 0) = + (flag_emit_class_files ? lvalue : save_expr (lvalue)); + /* 15.25.2.a: Left hand is not an array access. FIXME */ /* Now complete the RHS. We write it back later on. */ nn = java_complete_tree (TREE_OPERAND (node, 1)); @@ -8348,6 +8355,8 @@ java_complete_lhs (node) E1 = (T)(E1 op E2), with T being the type of E1. */ nn = java_complete_tree (build_cast (EXPR_WFL_LINECOL (wfl_op2), TREE_TYPE (lvalue), nn)); + + /* 15.25.2.b: Left hand is an array access. FIXME */ } /* If we're about to patch a NEW_ARRAY_INIT, we call a special @@ -8371,6 +8380,10 @@ java_complete_lhs (node) if ((nn = patch_string (TREE_OPERAND (node, 1)))) TREE_OPERAND (node, 1) = nn; node = patch_assignment (node, wfl_op1, wfl_op2); + /* Reorganize the tree if necessary. */ + if (flag && (!JREFERENCE_TYPE_P (TREE_TYPE (node)) + || JSTRING_P (TREE_TYPE (node)))) + node = java_refold (node); CAN_COMPLETE_NORMALLY (node) = 1; return node; @@ -9379,6 +9392,81 @@ operator_string (node) #undef BUILD_OPERATOR_STRING } +/* Return 1 if VAR_ACCESS1 is equivalent to VAR_ACCESS2. */ + +static int +java_decl_equiv (var_acc1, var_acc2) + tree var_acc1, var_acc2; +{ + if (JDECL_P (var_acc1)) + return (var_acc1 == var_acc2); + + return (TREE_CODE (var_acc1) == COMPONENT_REF + && TREE_CODE (var_acc2) == COMPONENT_REF + && TREE_OPERAND (TREE_OPERAND (var_acc1, 0), 0) + == TREE_OPERAND (TREE_OPERAND (var_acc2, 0), 0) + && TREE_OPERAND (var_acc1, 1) == TREE_OPERAND (var_acc2, 1)); +} + +/* Return a non zero value if CODE is one of the operators that can be + used in conjunction with the `=' operator in a compound assignment. */ + +static int +binop_compound_p (code) + enum tree_code code; +{ + int i; + for (i = 0; i < BINOP_COMPOUND_CANDIDATES; i++) + if (binop_lookup [i] == code) + break; + + return i < BINOP_COMPOUND_CANDIDATES; +} + +/* Reorganize after a fold to get SAVE_EXPR to generate what we want. */ + +static tree +java_refold (t) + tree t; +{ + tree c, b, ns, decl; + + if (TREE_CODE (t) != MODIFY_EXPR) + return t; + + c = TREE_OPERAND (t, 1); + if (! (c && TREE_CODE (c) == COMPOUND_EXPR + && TREE_CODE (TREE_OPERAND (c, 0)) == MODIFY_EXPR + && binop_compound_p (TREE_CODE (TREE_OPERAND (c, 1))))) + return t; + + /* Now the left branch of the binary operator. */ + b = TREE_OPERAND (TREE_OPERAND (c, 1), 0); + if (! (b && TREE_CODE (b) == NOP_EXPR + && TREE_CODE (TREE_OPERAND (b, 0)) == SAVE_EXPR)) + return t; + + ns = TREE_OPERAND (TREE_OPERAND (b, 0), 0); + if (! (ns && TREE_CODE (ns) == NOP_EXPR + && TREE_CODE (TREE_OPERAND (ns, 0)) == SAVE_EXPR)) + return t; + + decl = TREE_OPERAND (TREE_OPERAND (ns, 0), 0); + if ((JDECL_P (decl) || TREE_CODE (decl) == COMPONENT_REF) + /* It's got to be the an equivalent decl */ + && java_decl_equiv (decl, TREE_OPERAND (TREE_OPERAND (c, 0), 0))) + { + /* Shorten the NOP_EXPR/SAVE_EXPR path. */ + TREE_OPERAND (TREE_OPERAND (c, 1), 0) = TREE_OPERAND (ns, 0); + /* Substitute the COMPOUND_EXPR by the BINOP_EXPR */ + TREE_OPERAND (t, 1) = TREE_OPERAND (c, 1); + /* Change the right part of the BINOP_EXPR */ + TREE_OPERAND (TREE_OPERAND (t, 1), 1) = TREE_OPERAND (c, 0); + } + + return t; +} + /* Binary operators (15.16 up to 15.18). We return error_mark_node on errors but we modify NODE so that it contains the type computed according to the expression, when it's fixed. Otherwise, we write @@ -10043,7 +10131,7 @@ patch_unaryop (node, wfl_op) case PREINCREMENT_EXPR: /* 15.14.2 Prefix Decrement Operator -- */ case PREDECREMENT_EXPR: - decl = strip_out_static_field_access_decl (op); + op = decl = strip_out_static_field_access_decl (op); /* We really should have a JAVA_ARRAY_EXPR to avoid this */ if (!JDECL_P (decl) && TREE_CODE (decl) != COMPONENT_REF @@ -10082,15 +10170,28 @@ patch_unaryop (node, wfl_op) else { /* Before the addition, binary numeric promotion is performed on - both operands */ - value = build_int_2 (1, 0); - TREE_TYPE (node) = - binary_numeric_promotion (op_type, TREE_TYPE (value), &op, &value); - /* And write the promoted incremented and increment */ + both operands, if really necessary */ + if (JINTEGRAL_TYPE_P (op_type)) + { + value = build_int_2 (1, 0); + TREE_TYPE (value) = TREE_TYPE (node) = op_type; + } + else + { + value = build_int_2 (1, 0); + TREE_TYPE (node) = + binary_numeric_promotion (op_type, + TREE_TYPE (value), &op, &value); + } + /* And write back into the node. */ TREE_OPERAND (node, 0) = op; TREE_OPERAND (node, 1) = value; - /* Convert the overall back into its original type. */ - return fold (convert (op_type, node)); + /* Convert the overall back into its original type, if + necessary, and return */ + if (JINTEGRAL_TYPE_P (op_type)) + return fold (node); + else + return fold (convert (op_type, node)); } break; @@ -10948,6 +11049,54 @@ finish_for_loop (location, condition, update, body) return loop; } +/* Try to find the loop a block might be related to. This comprises + the case where the LOOP_EXPR is found as the second operand of a + COMPOUND_EXPR, because the loop happens to have an initialization + part, then expressed as the first operand of the COMPOUND_EXPR. If + the search finds something, 1 is returned. Otherwise, 0 is + returned. The search is assumed to start from a + LABELED_BLOCK_EXPR's block. */ + +static tree +search_loop (statement) + tree statement; +{ + if (TREE_CODE (statement) == LOOP_EXPR) + return statement; + + if (TREE_CODE (statement) == BLOCK) + statement = BLOCK_SUBBLOCKS (statement); + else + return NULL_TREE; + + if (statement && TREE_CODE (statement) == COMPOUND_EXPR) + while (statement && TREE_CODE (statement) == COMPOUND_EXPR) + statement = TREE_OPERAND (statement, 1); + + return (TREE_CODE (statement) == LOOP_EXPR + && IS_FOR_LOOP_P (statement) ? statement : NULL_TREE); +} + +/* Return 1 if LOOP can be found in the labeled block BLOCK. 0 is + returned otherwise. */ + +static int +labeled_block_contains_loop_p (block, loop) + tree block, loop; +{ + if (!block) + return 0; + + if (LABELED_BLOCK_BODY (block) == loop) + return 1; + + if (IS_FOR_LOOP_P (loop) + && search_loop (LABELED_BLOCK_BODY (block)) == loop) + return 1; + + return 0; +} + /* If the loop isn't surrounded by a labeled statement, create one and insert LOOP as its body. */ @@ -10956,33 +11105,17 @@ patch_loop_statement (loop) tree loop; { tree loop_label; - tree block = ctxp->current_labeled_block; + TREE_TYPE (loop) = void_type_node; - if (block != NULL_TREE) - { - tree block_body = LABELED_BLOCK_BODY (block); - if (IS_FOR_LOOP_P (loop)) - { - if (TREE_CODE (block_body) == BLOCK) - { - block_body = BLOCK_EXPR_BODY (block_body); - if (block_body == loop - || (TREE_CODE (block_body) == COMPOUND_EXPR - && TREE_OPERAND (block_body, 1) == loop)) - return loop; - } - } - else - { - if (block_body == loop) - return loop; - } - } + if (labeled_block_contains_loop_p (ctxp->current_labeled_block, loop)) + return loop; + loop_label = build_labeled_block (0, NULL_TREE); + /* LOOP is an EXPR node, so it should have a valid EXPR_WFL_LINECOL + that LOOP_LABEL could enquire about, for a better accuracy. FIXME */ LABELED_BLOCK_BODY (loop_label) = loop; PUSH_LABELED_BLOCK (loop_label); - loop = loop_label; - return loop; + return loop_label; } /* 14.13, 14.14: break and continue Statements */ @@ -11074,7 +11207,7 @@ patch_bc_statement (node) } target_stmt = LABELED_BLOCK_BODY (labeled_block); if (TREE_CODE (target_stmt) == SWITCH_EXPR - || TREE_CODE (target_stmt) == LOOP_EXPR) + || search_loop (target_stmt)) { bc_label = labeled_block; break; @@ -11088,7 +11221,7 @@ patch_bc_statement (node) /* Our break/continue don't return values. */ TREE_TYPE (node) = void_type_node; /* Encapsulate the break within a compound statement so that it's - expanded all the times by expand_expr (and not clobered + expanded all the times by expand_expr (and not clobbered sometimes, like after a if statement) */ node = add_stmt_to_compound (NULL_TREE, void_type_node, node); TREE_SIDE_EFFECTS (node) = 1; |