diff options
author | Alexandre Petit-Bianco <apbianco@cygnus.com> | 1999-04-26 19:09:37 +0000 |
---|---|---|
committer | Alexandre Petit-Bianco <apbianco@gcc.gnu.org> | 1999-04-26 12:09:37 -0700 |
commit | 7f1d48663e8aa1d749c88ffd17365bf2aa80f21a (patch) | |
tree | 38ae2203c1adb1c12229db14df3792c799011465 /gcc/java/parse.y | |
parent | ccd63d90d14a15e87224d8fba54870ab78167a25 (diff) | |
download | gcc-7f1d48663e8aa1d749c88ffd17365bf2aa80f21a.zip gcc-7f1d48663e8aa1d749c88ffd17365bf2aa80f21a.tar.gz gcc-7f1d48663e8aa1d749c88ffd17365bf2aa80f21a.tar.bz2 |
class.c (layout_class_method): Generate <clinit>'s rtl for interfaces.
Sat Apr 24 16:50:19 1999 Alexandre Petit-Bianco <apbianco@cygnus.com>
* class.c (layout_class_method): Generate <clinit>'s rtl for
interfaces.
* decl.c (complete_start_java_method): Don't call _Jv_InitClass
for interfaces' <clinit>.
* expr.c (lookup_field): Search for fields in interfaces.
(expand_invoke): Fixed indentation.
(expand_java_field_op): Likewise. Use IS_CLINIT.
* parse.h (JPRIMITIVE_TYPE_OR_VOID_P): Macro removed.
(IS_CLINIT): New macro.
* parse.y (type_declaration:): Call maybe_generate_clinit after an
interface was parsed.
(maybe_generate_clinit): Don't generate if the current class is an
interface with only fields of primitive types.
(reset_method_name): Use IS_CLINIT.
(java_complete_expand_method): Expand <clinit> when it exists for
interfaces. Use IS_CLINIT.
(resolve_expression_name): Use DECL_CONTEXT instead of
current_class to build static field references.
(java_complete_lhs): Use IS__CLINIT. Don't use SAVE_EXPR on
ARRAY_REF when doing xreferencing.
(check_final_assignment): Fixed typo in leading comment. Use
IS_CLINIT.
(patch_array_ref): Don't fully expand array references when
xreferencing.
(patch_return): Use IS_CLINIT.
(patch_throw_statement): Likewise.
From-SVN: r26661
Diffstat (limited to 'gcc/java/parse.y')
-rw-r--r-- | gcc/java/parse.y | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/gcc/java/parse.y b/gcc/java/parse.y index 4652ff2..f8c21c7 100644 --- a/gcc/java/parse.y +++ b/gcc/java/parse.y @@ -632,6 +632,10 @@ type_declaration: $$ = $1; } | interface_declaration + { + maybe_generate_clinit (); + $$ = $1; + } | SC_TK { $$ = NULL; } | error @@ -3231,10 +3235,19 @@ 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); @@ -4404,8 +4417,7 @@ static int reset_method_name (method) tree method; { - if (DECL_NAME (method) != clinit_identifier_node - && DECL_NAME (method) != finit_identifier_node) + if (!IS_CLINIT (method) && DECL_NAME (method) != finit_identifier_node) { /* NAME is just the plain name when Object is being defined */ if (DECL_CONTEXT (method) != object_type_node) @@ -5662,51 +5674,55 @@ java_complete_expand_methods () for (current = ctxp->class_list; current; current = TREE_CHAIN (current)) { + int is_interface; tree class_type = CLASS_TO_HANDLE_TYPE (TREE_TYPE (current)); tree decl; current_class = TREE_TYPE (current); + is_interface = CLASS_INTERFACE (TYPE_NAME (current_class)); /* Initialize a new constant pool */ init_outgoing_cpool (); /* We want <clinit> (if any) to be processed first. */ decl = tree_last (TYPE_METHODS (class_type)); - if (decl && DECL_NAME (decl) == clinit_identifier_node) + 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)); } + + 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; - /* Don't process function bodies in interfaces */ - if (!CLASS_INTERFACE (TYPE_NAME (current_class))) - for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl)) - { - current_function_decl = decl; - /* Don't generate debug info on line zero when expanding a - generated constructor. */ - if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl)) - { - /* If we found errors, it's too dangerous to try to generate - and expand a constructor */ - if (!java_error_count) - { - restore_line_number_status (1); - java_complete_expand_method (decl); - restore_line_number_status (0); + current_function_decl = decl; + /* Don't generate debug info on line zero when expanding a + generated constructor. */ + if (DECL_CONSTRUCTOR_P (decl) && !DECL_FUNCTION_BODY (decl)) + { + /* If we found errors, it's too dangerous to try to + generate and expand a constructor */ + if (!java_error_count) + { + restore_line_number_status (1); + java_complete_expand_method (decl); + restore_line_number_status (0); } - } - else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl)) - continue; - else - java_complete_expand_method (decl); - } + } + else if (METHOD_ABSTRACT (decl) || METHOD_NATIVE (decl)) + continue; + else + java_complete_expand_method (decl); + } /* Now verify constructor circularity (stop after the first one we find) */ - if (!CLASS_INTERFACE (TYPE_NAME (current_class))) + if (!is_interface) for (decl = TYPE_METHODS (class_type); decl; decl = TREE_CHAIN (decl)) if (DECL_CONSTRUCTOR_P (decl) && verify_constructor_circularity (decl, decl)) @@ -5761,7 +5777,7 @@ java_complete_expand_method (mdecl) if (block_body != NULL_TREE) { /* Prevent the use of `this' inside <clinit> */ - if (DECL_NAME (current_function_decl) == clinit_identifier_node) + if (IS_CLINIT (current_function_decl)) ctxp->explicit_constructor_p = 1; block_body = java_complete_tree (block_body); @@ -6097,9 +6113,9 @@ resolve_expression_name (id, orig) /* Otherwise build what it takes to access the field */ decl = build_field_ref ((fs ? NULL_TREE : current_this), - current_class, name); + DECL_CONTEXT (decl), name); if (fs && !flag_emit_class_files && !flag_emit_xref) - decl = build_class_init (current_class, decl); + decl = build_class_init (DECL_CONTEXT (decl), decl); /* We may be asked to save the real field access node */ if (orig) *orig = decl; @@ -8074,7 +8090,7 @@ java_complete_lhs (node) assignment in <clinit>, we may want to carray further optimizations. (VAR_DECL means it's a static field. See add_field. */ - if (DECL_NAME (current_function_decl) == clinit_identifier_node + if (IS_CLINIT (current_function_decl) && MODIFY_EXPR_FROM_INITIALIZATION_P (node) && TREE_CODE (TREE_OPERAND (node, 0)) == VAR_DECL) node = patch_initialized_static_field (node); @@ -8159,14 +8175,14 @@ java_complete_lhs (node) TREE_OPERAND (node, 0) = java_complete_tree (wfl_op1); if (TREE_OPERAND (node, 0) == error_mark_node) return error_mark_node; - if (!flag_emit_class_files) + if (!flag_emit_class_files && !flag_emit_xref) TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0)); /* The same applies to wfl_op2 */ wfl_op2 = TREE_OPERAND (node, 1); TREE_OPERAND (node, 1) = java_complete_tree (wfl_op2); if (TREE_OPERAND (node, 1) == error_mark_node) return error_mark_node; - if (!flag_emit_class_files) + if (!flag_emit_class_files && !flag_emit_xref) TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1)); return patch_array_ref (node); @@ -8507,14 +8523,15 @@ print_int_node (node) return buffer; } -/* Return 1 if you an assignment of a FINAL is attempted */ +/* Return 1 if an assignment to a FINAL is attempted in a non suitable + context. */ static int check_final_assignment (lvalue, wfl) tree lvalue, wfl; { - if (JDECL_P (lvalue) && FIELD_FINAL (lvalue) && - DECL_NAME (current_function_decl) != clinit_identifier_node) + if (JDECL_P (lvalue) + && FIELD_FINAL (lvalue) && !IS_CLINIT (current_function_decl)) { parse_error_context (wfl, "Can't assign a value to the final variable `%s'", @@ -10070,7 +10087,7 @@ patch_array_ref (node) array_type = TYPE_ARRAY_ELEMENT (array_type); - if (flag_emit_class_files) + if (flag_emit_class_files || flag_emit_xref) { TREE_OPERAND (node, 0) = array; TREE_OPERAND (node, 1) = index; @@ -10396,7 +10413,7 @@ patch_return (node) error_found = 1; /* It's invalid to use a return statement in a static block */ - if (DECL_NAME (current_function_decl) == clinit_identifier_node) + if (IS_CLINIT (current_function_decl)) error_found = 1; /* It's invalid to have a no return value within a function that @@ -10406,7 +10423,7 @@ patch_return (node) if (error_found) { - if (DECL_NAME (current_function_decl) == clinit_identifier_node) + if (IS_CLINIT (current_function_decl)) parse_error_context (wfl_operator, "`return' inside static initializer."); @@ -11134,7 +11151,7 @@ patch_throw_statement (node, wfl_op1) else if (!EXCEPTIONS_P (currently_caught_type_list) && !tryblock_throws_ok) { - if (DECL_NAME (current_function_decl) == clinit_identifier_node) + if (IS_CLINIT (current_function_decl)) parse_error_context (wfl_operator, "Checked exception `%s' can't " "be thrown in initializer", lang_printable_name (type, 0)); |