aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/parse.y
diff options
context:
space:
mode:
authorPer Bothner <bothner@gcc.gnu.org>1999-05-05 14:10:07 -0700
committerPer Bothner <bothner@gcc.gnu.org>1999-05-05 14:10:07 -0700
commitcd9643f75b2f7bc41642bd988532a03ba923c3f4 (patch)
tree6125e0290d9b6e83ae6f4e2dd48bdf11dfdaa937 /gcc/java/parse.y
parentc14cff58e5c6d6052e940cb1adf03733154ec9b6 (diff)
downloadgcc-cd9643f75b2f7bc41642bd988532a03ba923c3f4.zip
gcc-cd9643f75b2f7bc41642bd988532a03ba923c3f4.tar.gz
gcc-cd9643f75b2f7bc41642bd988532a03ba923c3f4.tar.bz2
class.c (make_field_value): DECL_INITIAL may be a string literal...
d * class.c (make_field_value): DECL_INITIAL may be a string literal; temporarily zero it while calling rest_of_decl_compilation. * java-tree.h (string_ptr_type_node): Add declaration. * decl.c: Define and initialize string_ptr_type_node. * parse.y (patch_string_cst): Use string_ptr_type_node. * parse.h (LOOP_HAS_LABEL_P, LOOP_HAS_LABEL_SKIP_P): Removed. * parse.y (for_statement): Now unconditionally exit_block. (finish_labeled_statement): No longer exit_block if for-loop. (patch_loop_statement): Check harder if the loop is already labeled. * parse.y (patch_initialized_static_field): Removed function. (maybe_generate_clinit): Removed special handling for interfaces. (java_complete_expand_methods): Do a preliminary java_complete_tree on <clinit> to determine if it can be removed. (java_complete_expand_method): Remove special handling for <clinit>. (java_complete_lhs): For BLOCK and EXPR_WITH_FILE_LOCATION optimize if we get back empty_stmt_node. For MODIFY_EXPR, re-do checking of static initializers. (fold_constant_for_init): Don't return immediate if VAR_DECL. For VAR_DECL, pass correct context. From-SVN: r26790
Diffstat (limited to 'gcc/java/parse.y')
-rw-r--r--gcc/java/parse.y176
1 files changed, 88 insertions, 88 deletions
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index deaa3e8..82598de 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -237,7 +237,6 @@ static tree patch_new_array_init PROTO ((tree, tree));
static tree maybe_build_array_element_wfl PROTO ((tree));
static int array_constructor_check_entry PROTO ((tree, tree));
static char *purify_type_name PROTO ((char *));
-static tree patch_initialized_static_field PROTO ((tree));
static tree fold_constant_for_init PROTO ((tree, tree));
static tree strip_out_static_field_access_decl PROTO ((tree));
static jdeplist *reverse_jdep_list PROTO ((struct parser_ctxt *));
@@ -1220,13 +1219,7 @@ statement:
| if_then_else_statement
| while_statement
| for_statement
- {
- /* If the for loop is unlabeled, we must return the
- block it was defined it. It our last chance to
- get a hold on it. */
- if (!LOOP_HAS_LABEL_P ($$))
- $$ = exit_block ();
- }
+ { $$ = exit_block (); }
;
statement_nsi:
@@ -3264,19 +3257,11 @@ static void
maybe_generate_clinit ()
{
tree mdecl, c;
- int is_interface = CLASS_INTERFACE (ctxp->current_parsed_class);
int has_non_primitive_fields = 0;
if (!ctxp->static_initialized || java_error_count)
return;
- if (is_interface)
- for (c = TYPE_FIELDS (TREE_TYPE (ctxp->current_parsed_class));
- c; c = TREE_CHAIN (c))
- has_non_primitive_fields |= !JPRIMITIVE_TYPE_P (TREE_TYPE (c));
- if (!has_non_primitive_fields && is_interface)
- return;
-
mdecl = create_artificial_method (TREE_TYPE (ctxp->current_parsed_class),
ACC_STATIC, void_type_node,
clinit_identifier_node, end_params_node);
@@ -5728,18 +5713,41 @@ java_complete_expand_methods ()
decl = tree_last (TYPE_METHODS (class_type));
if (IS_CLINIT (decl))
{
- tree list = nreverse (TYPE_METHODS (class_type));
- list = TREE_CHAIN (list);
- TREE_CHAIN (decl) = NULL_TREE;
- TYPE_METHODS (class_type) = chainon (decl, nreverse (list));
+ tree fbody = DECL_FUNCTION_BODY (decl);
+ tree list;
+ if (fbody != NULL_TREE)
+ {
+ /* First check if we can ignore empty <clinit> */
+ tree block_body = BLOCK_EXPR_BODY (fbody);
+
+ current_this = NULL_TREE;
+ current_function_decl = decl;
+ if (block_body != NULL_TREE)
+ {
+ /* Prevent the use of `this' inside <clinit> */
+ ctxp->explicit_constructor_p = 1;
+
+ block_body = java_complete_tree (block_body);
+ ctxp->explicit_constructor_p = 0;
+ BLOCK_EXPR_BODY (fbody) = block_body;
+ if (block_body != NULL_TREE
+ && TREE_CODE (block_body) == BLOCK
+ && BLOCK_EXPR_BODY (block_body) == empty_stmt_node)
+ decl = NULL_TREE;
+ }
+ }
+ list = nreverse (TREE_CHAIN (nreverse (TYPE_METHODS (class_type))));
+ if (decl != NULL_TREE)
+ {
+ TREE_CHAIN (decl) = list;
+ TYPE_METHODS (class_type) = decl;
+ }
+ else
+ TYPE_METHODS (class_type) = list;
}
for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl))
{
- /* Process only <clinit> method bodies in interfaces. */
- if (is_interface && decl != TYPE_METHODS (class_type))
- break;
-
current_function_decl = decl;
/* Don't generate debug info on line zero when expanding a
generated constructor. */
@@ -5816,10 +5824,6 @@ java_complete_expand_method (mdecl)
if (block_body != NULL_TREE)
{
- /* Prevent the use of `this' inside <clinit> */
- if (IS_CLINIT (current_function_decl))
- ctxp->explicit_constructor_p = 1;
-
block_body = java_complete_tree (block_body);
check_for_initialization (block_body);
ctxp->explicit_constructor_p = 0;
@@ -7755,6 +7759,13 @@ java_complete_lhs (node)
tree cur = java_complete_tree (TREE_OPERAND (*ptr, 0));
tree *next = &TREE_OPERAND (*ptr, 1);
TREE_OPERAND (*ptr, 0) = cur;
+ if (cur == empty_stmt_node)
+ {
+ /* Optimization; makes it easier to detect empty bodies.
+ Most useful for <clinit> with all-constant initializer. */
+ *ptr = *next;
+ continue;
+ }
if (TREE_CODE (cur) == ERROR_MARK)
error_seen++;
else if (! CAN_COMPLETE_NORMALLY (cur))
@@ -8022,6 +8033,11 @@ java_complete_lhs (node)
EXPR_WFL_NODE (node) = body;
TREE_SIDE_EFFECTS (node) = TREE_SIDE_EFFECTS (body);
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (body);
+ if (body == empty_stmt_node)
+ {
+ /* Optimization; makes it easier to detect empty bodies. */
+ return body;
+ }
if (body == error_mark_node)
{
/* Its important for the evaluation of assignment that
@@ -8091,8 +8107,22 @@ java_complete_lhs (node)
case MODIFY_EXPR:
/* Save potential wfls */
wfl_op1 = TREE_OPERAND (node, 0);
+ TREE_OPERAND (node, 0) = nn = java_complete_lhs (wfl_op1);
+ if (MODIFY_EXPR_FROM_INITIALIZATION_P (node)
+ && TREE_CODE (nn) == VAR_DECL && TREE_STATIC (nn)
+ && DECL_INITIAL (nn) != NULL_TREE)
+ {
+ tree value = fold_constant_for_init (nn, nn);
+ if (value != NULL_TREE)
+ {
+ tree type = TREE_TYPE (value);
+ if (JPRIMITIVE_TYPE_P (type) || type == string_ptr_type_node)
+ return empty_stmt_node;
+ }
+ DECL_INITIAL (nn) = NULL_TREE;
+ }
wfl_op2 = TREE_OPERAND (node, 1);
- TREE_OPERAND (node, 0) = java_complete_lhs (wfl_op1);
+
if (TREE_OPERAND (node, 0) == error_mark_node)
return error_mark_node;
@@ -8138,17 +8168,6 @@ java_complete_lhs (node)
TREE_OPERAND (node, 1) = nn;
node = patch_assignment (node, wfl_op1, wfl_op2);
CAN_COMPLETE_NORMALLY (node) = 1;
-
- /* Before returning the node, in the context of a static field
- assignment in <clinit>, we may want to carray further
- optimizations. (VAR_DECL means it's a static field. See
- add_field. */
- if (IS_CLINIT (current_function_decl)
- && MODIFY_EXPR_FROM_INITIALIZATION_P (node)
- && TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL
- && !flag_emit_xref)
- node = patch_initialized_static_field (node);
-
return node;
case MULT_EXPR:
@@ -8800,35 +8819,6 @@ patch_assignment (node, wfl_op1, wfl_op2)
return node;
}
-/* Optimize static (final) field initialized upon declaration.
- - If the field is static final and is assigned to a primitive
- constant type, then set its DECL_INITIAL to the value.
- - More to come. */
-
-static tree
-patch_initialized_static_field (node)
- tree node;
-{
- tree field = TREE_OPERAND (node, 0);
- tree value = TREE_OPERAND (node, 1);
-
- if (DECL_INITIAL (field) != NULL_TREE)
- {
- tree type = TREE_TYPE (value);
- if (FIELD_FINAL (field) && TREE_CONSTANT (value)
- && (JPRIMITIVE_TYPE_P (type)
- || (flag_emit_class_files
- && TREE_CODE (type) == POINTER_TYPE
- && TREE_TYPE (type) == string_type_node)))
- {
- DECL_INITIAL (field) = value;
- return empty_stmt_node;
- }
- DECL_INITIAL (field) = NULL_TREE;
- }
- return node;
-}
-
/* Check that type SOURCE can be cast into type DEST. If the cast
can't occur at all, return 0 otherwise 1. This function is used to
produce accurate error messages on the reasons why an assignment
@@ -9733,7 +9723,7 @@ patch_string_cst (node)
location = alloc_name_constant (CONSTANT_String, node);
node = build_ref_from_constant_pool (location);
}
- TREE_TYPE (node) = promote_type (string_type_node);
+ TREE_TYPE (node) = string_ptr_type_node;
TREE_CONSTANT (node) = 1;
return node;
}
@@ -10632,15 +10622,6 @@ finish_labeled_statement (lbe, statement)
{
/* In anyways, tie the loop to its statement */
LABELED_BLOCK_BODY (lbe) = statement;
-
- /* Ok, if statement is a for loop, we have to attach the labeled
- statement to the block the for loop belongs to and return the
- block instead */
- if (TREE_CODE (statement) == LOOP_EXPR && IS_FOR_LOOP_P (statement))
- {
- java_method_add_stmt (current_function_decl, lbe);
- lbe = exit_block ();
- }
pop_labeled_block ();
POP_LABELED_BLOCK ();
return lbe;
@@ -10752,14 +10733,33 @@ static tree
patch_loop_statement (loop)
tree loop;
{
- if (! LOOP_HAS_LABEL_P (loop))
+ tree loop_label;
+ tree block = ctxp->current_labeled_block;
+ TREE_TYPE (loop) = void_type_node;
+ if (block != NULL_TREE)
{
- tree loop_label = build_labeled_block (0, NULL_TREE);
- LABELED_BLOCK_BODY (loop_label) = loop;
- PUSH_LABELED_BLOCK (loop_label);
- loop = loop_label;
+ 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;
+ }
}
- TREE_TYPE (loop) = void_type_node;
+ loop_label = build_labeled_block (0, NULL_TREE);
+ LABELED_BLOCK_BODY (loop_label) = loop;
+ PUSH_LABELED_BLOCK (loop_label);
+ loop = loop_label;
return loop;
}
@@ -11431,7 +11431,7 @@ fold_constant_for_init (node, context)
if (code == INTEGER_CST || code == REAL_CST || code == STRING_CST)
return node;
- if (TREE_TYPE (node) != NULL_TREE)
+ if (TREE_TYPE (node) != NULL_TREE && code != VAR_DECL)
return NULL_TREE;
switch (code)
@@ -11503,7 +11503,7 @@ fold_constant_for_init (node, context)
val = DECL_INITIAL (node);
/* Guard against infinite recursion. */
DECL_INITIAL (node) = NULL_TREE;
- val = fold_constant_for_init (val, DECL_CONTEXT (node));
+ val = fold_constant_for_init (val, node);
DECL_INITIAL (node) = val;
return val;
@@ -11519,7 +11519,7 @@ fold_constant_for_init (node, context)
else if (! QUALIFIED_P (name))
{
decl = lookup_field_wrapper (DECL_CONTEXT (context), name);
- if (! FIELD_STATIC (decl))
+ if (decl == NULL_TREE || ! FIELD_STATIC (decl))
return NULL_TREE;
return fold_constant_for_init (decl, decl);
}