diff options
author | Alexandre Petit-Bianco <apbianco@gcc.gnu.org> | 1998-11-24 09:57:41 -0800 |
---|---|---|
committer | Alexandre Petit-Bianco <apbianco@gcc.gnu.org> | 1998-11-24 09:57:41 -0800 |
commit | 23a79c61921246f3d84df2503555208f2683203e (patch) | |
tree | ddfaaed8a863a8721201f3dd3d76d282cc58791c /gcc/java/class.c | |
parent | 333a9f0aafc0d0e426d948e545daae6f6d277f19 (diff) | |
download | gcc-23a79c61921246f3d84df2503555208f2683203e.zip gcc-23a79c61921246f3d84df2503555208f2683203e.tar.gz gcc-23a79c61921246f3d84df2503555208f2683203e.tar.bz2 |
[multiple changes]
Tue Nov 24 17:06:38 1998 Per Bothner <bothner@cygnus.com>
* (generate_classfile): Always write class access flag with
ACC_SUPER set.
Tue Nov 24 16:34:33 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
* class.c (maybe_layout_super_class): New function.
(layout_class): Reorganized. Loop on class methods dispatched into
a new function. Call maybe_layout_super_class.
(layout_class_methods, layout_class_method): New functions.
* expr.c (expand_java_NEW): Call layout_class_methods on loaded
class.
(expand_invoke): Likewise.
* java-tree.h (all_class_list): New global variable declared.
(layout_class_methods, layout_class_method): New function
prototypes.
(LAYOUT_SEEN_CLASS_METHODS): New macro.
* jcf-parse.c (all_class_list): New global variable.
(load_class): Extended what class_or_name can be. Use parser
context mechanism to save globals before calling jcf_parse.
(jcf_parse_source): Don't parse twice if HAS_BEEN_ALREADY_PARSED_P
is set on the file name.
(jcf_parse): Layout class methods when Object is loaded, otherwise
record class in all_class_list for delayed method layout.
(parse_class_file): Use LAYOUT_SEEN_CLASS_METHODS.
* lang.c (put_decl_node): Decode <init> into the decl context
class name.
* lex.c (java_allocate_new_line): Use xmalloc.
* parse.h (INCOMPLETE_TYPE_P): Redefined to work with incomplete
pointers, not TREE_LIST elements.
(struct parser_ctxt): Fixed comment indentations, added comments
and reordered some fields.
(java_check_methods): Function prototype removed.
* parse.y (java_push_parser_context): Use xmalloc.
(java_parser_context_restore_global): Pop extra pushed ctxp only
when there's nothing next.
(maybe_create_class_interface_decl): Fixed comment, add new
created class decl to all_class_list.
(method_header): Use GET_REAL_TYPE on argument's types.
(method_declarator): Use GET_REAL_TYPE, change type to the real
type in TREE_LIST dependency node. Build argument list with the
real type.
(create_jdep_list): Use xmalloc. Removed allocation error message.
(obtain_incomplete_type): Fixed leading comment. Broadened
incoming argument meaning.
(register_incomplete_type): Use xmalloc. Removed allocation error
message.
(safe_layout_class): Fixed leading comment.
(jdep_resolve_class): Reversed if statement condition and switch
if and else bodies.
(resolve_and_layout): Fixed leading comment. Broadened incoming
argument meaning.
(complete_class_report_errors): New local variable name, for
clarity. purify_type_name used for all error cases.
(java_get_real_method_name): Stricter check on constructors.
(java_check_regular_methods): Reverse methods list only if not
already laid out. Layout artificial constructor.
(java_check_methods): Deleted.
(source_start_java_method): Obtain incomplete type for patchable
method arguments.
(java_layout_classes): Fixed leading comment. Use
LAYOUT_SEEN_CLASS_METHODS, use a loop to check methods. Added else
statement to layout operation, reuse LAYOUT_SEEN_CLASS_METHODS
before returning. Fixed comments.
(java_expand_classes): Check for errors up front.
(patch_method_invocation): Class to search is resolved and laid
out.
A step forward truly mixing .class and .java during package
compilation. Includes a Per's patch.
From-SVN: r23834
Diffstat (limited to 'gcc/java/class.c')
-rw-r--r-- | gcc/java/class.c | 373 |
1 files changed, 214 insertions, 159 deletions
diff --git a/gcc/java/class.c b/gcc/java/class.c index 0f8d488..e0ea241 100644 --- a/gcc/java/class.c +++ b/gcc/java/class.c @@ -1323,39 +1323,55 @@ push_super_field (this_class, super_class) DECL_SIZE (base_decl) = TYPE_SIZE (super_class); } +/* Handle the different manners we may have to lay out a super class. */ + +static tree +maybe_layout_super_class (super_class) + tree super_class; +{ + if (TREE_CODE (super_class) == RECORD_TYPE) + { + if (!CLASS_LOADED_P (super_class) + && CLASS_FROM_SOURCE_P (super_class)) + safe_layout_class (super_class); + if (!CLASS_LOADED_P (super_class)) + load_class (super_class, 1); + } + /* We might have to layout the class before its dependency on + the super class gets resolved by java_complete_class */ + else if (TREE_CODE (super_class) == TREE_LIST) + { + tree name = TYPE_NAME (TREE_PURPOSE (super_class)); + load_class (name, 1); + super_class = IDENTIFIER_CLASS_VALUE (name); + if (!super_class) + return; + super_class = TREE_TYPE (super_class); + } + if (!TYPE_SIZE (super_class)) + safe_layout_class (super_class); + + return super_class; +} + void layout_class (this_class) tree this_class; { tree super_class = CLASSTYPE_SUPER (this_class); - tree handle_type = CLASS_TO_HANDLE_TYPE (this_class); - tree method_decl, field; - tree dtable_count; - int i; + tree field; if (super_class) { - /* Class seen in source are now complete and can be layed out. - Once layed out, a class seen in the source has its - CLASS_LOADED_P flag set */ - if (CLASS_FROM_SOURCE_P (super_class) && !CLASS_LOADED_P (super_class)) - safe_layout_class (super_class); - if (! CLASS_LOADED_P (super_class)) - load_class (super_class, 1); + super_class = maybe_layout_super_class (super_class); if (TREE_CODE (TYPE_SIZE (super_class)) == ERROR_MARK) { TYPE_SIZE (this_class) = error_mark_node; return; } - dtable_count = TYPE_NVIRTUALS (super_class); - if (TYPE_SIZE (this_class) == NULL_TREE) push_super_field (this_class, super_class); } - else - { - dtable_count = integer_zero_node; - } for (field = TYPE_FIELDS (this_class); field != NULL_TREE; field = TREE_CHAIN (field)) @@ -1368,178 +1384,217 @@ layout_class (this_class) } layout_type (this_class); +} - TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type)); +void +layout_class_methods (this_class) + tree this_class; +{ + tree method_decl, dtable_count; + tree super_class, handle_type; + + if (TYPE_NVIRTUALS (this_class)) + return; + + push_obstacks (&permanent_obstack, &permanent_obstack); + super_class = CLASSTYPE_SUPER (this_class); + handle_type = CLASS_TO_HANDLE_TYPE (this_class); - for (method_decl = TYPE_METHODS (handle_type), i = 0; - method_decl; method_decl = TREE_CHAIN (method_decl), i++) + if (super_class) { - char *ptr; - char buf[8]; - char *asm_name; - tree method_name = DECL_NAME (method_decl); - int method_name_is_wfl = - (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION); - if (method_name_is_wfl) - method_name = java_get_real_method_name (method_decl); + super_class = maybe_layout_super_class (super_class); + if (!TYPE_NVIRTUALS (super_class)) + layout_class_methods (super_class); + dtable_count = TYPE_NVIRTUALS (super_class); + } + else + dtable_count = integer_zero_node; + + TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type)); + + for (method_decl = TYPE_METHODS (handle_type); + method_decl; method_decl = TREE_CHAIN (method_decl)) + dtable_count = layout_class_method (this_class, super_class, + method_decl, dtable_count); + + TYPE_NVIRTUALS (this_class) = dtable_count; + +#ifdef JAVA_USE_HANDLES + layout_type (handle_type); +#endif + pop_obstacks (); +} + +/* Lay METHOD_DECL out, returning a possibly new value of + DTABLE_COUNT. */ + +tree +layout_class_method (this_class, super_class, method_decl, dtable_count) + tree this_class, super_class, method_decl, dtable_count; +{ + char *ptr; + char buf[8]; + char *asm_name; + tree method_name = DECL_NAME (method_decl); + int method_name_is_wfl = + (TREE_CODE (method_name) == EXPR_WITH_FILE_LOCATION); + if (method_name_is_wfl) + method_name = java_get_real_method_name (method_decl); #if 1 - /* Remove this once we no longer need old (Kaffe / JDK 1.0) mangling. */ - if (! flag_assume_compiled && METHOD_NATIVE (method_decl)) + /* Remove this once we no longer need old (Kaffe / JDK 1.0) mangling. */ + if (! flag_assume_compiled && METHOD_NATIVE (method_decl)) + { + for (ptr = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))); + *ptr; ) + { + int ch = *ptr++; + if (ch == '.') + ch = '_'; + obstack_1grow (&temporary_obstack, (char) ch); + } + obstack_1grow (&temporary_obstack, (char) '_'); + if (method_name == init_identifier_node) + obstack_grow (&temporary_obstack, "INIT", 4); + else + obstack_grow (&temporary_obstack, + IDENTIFIER_POINTER (method_name), + IDENTIFIER_LENGTH (method_name)); + } + else +#endif + { + int len; tree arg, arglist, t; + int method_name_needs_escapes = 0; + if (method_name != init_identifier_node + && method_name != finit_identifier_node) { - for (ptr = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))); - *ptr; ) + int encoded_len + = unicode_mangling_length (IDENTIFIER_POINTER (method_name), + IDENTIFIER_LENGTH (method_name)); + if (encoded_len > 0) { - int ch = *ptr++; - if (ch == '.') - ch = '_'; - obstack_1grow (&temporary_obstack, (char) ch); + method_name_needs_escapes = 1; + emit_unicode_mangled_name (&temporary_obstack, + IDENTIFIER_POINTER (method_name), + IDENTIFIER_LENGTH (method_name)); } - obstack_1grow (&temporary_obstack, (char) '_'); - if (method_name == init_identifier_node) - obstack_grow (&temporary_obstack, "INIT", 4); else - obstack_grow (&temporary_obstack, - IDENTIFIER_POINTER (method_name), - IDENTIFIER_LENGTH (method_name)); + { + obstack_grow (&temporary_obstack, + IDENTIFIER_POINTER (method_name), + IDENTIFIER_LENGTH (method_name)); + } } - else -#endif + + obstack_grow (&temporary_obstack, "__", 2); + if (method_name == finit_identifier_node) + obstack_grow (&temporary_obstack, "finit", 5); + append_gpp_mangled_type (&temporary_obstack, this_class); + TREE_PUBLIC (method_decl) = 1; + + t = TREE_TYPE (method_decl); + arglist = TYPE_ARG_TYPES (t); + if (TREE_CODE (t) == METHOD_TYPE) + arglist = TREE_CHAIN (arglist); + for (arg = arglist; arg != NULL_TREE; ) { - int len; tree arg, arglist, t; - int method_name_needs_escapes = 0; - if (method_name != init_identifier_node - && method_name != finit_identifier_node) + tree a = arglist; + tree argtype = TREE_VALUE (arg); + int tindex = 1; + if (TREE_CODE (argtype) == POINTER_TYPE) { - int encoded_len - = unicode_mangling_length (IDENTIFIER_POINTER (method_name), - IDENTIFIER_LENGTH (method_name)); - if (encoded_len > 0) - { - method_name_needs_escapes = 1; - emit_unicode_mangled_name (&temporary_obstack, - IDENTIFIER_POINTER (method_name), - IDENTIFIER_LENGTH (method_name)); - } - else - { - obstack_grow (&temporary_obstack, - IDENTIFIER_POINTER (method_name), - IDENTIFIER_LENGTH (method_name)); - } + /* This is O(N**2). Do we care? Cfr gcc/cp/method.c. */ + while (a != arg && argtype != TREE_VALUE (a)) + a = TREE_CHAIN (a), tindex++; } - - obstack_grow (&temporary_obstack, "__", 2); - if (method_name == finit_identifier_node) - obstack_grow (&temporary_obstack, "finit", 5); - append_gpp_mangled_type (&temporary_obstack, this_class); - TREE_PUBLIC (method_decl) = 1; - - t = TREE_TYPE (method_decl); - arglist = TYPE_ARG_TYPES (t); - if (TREE_CODE (t) == METHOD_TYPE) - arglist = TREE_CHAIN (arglist); - for (arg = arglist; arg != NULL_TREE; ) + else + a = arg; + if (a != arg) { - tree a = arglist; - tree argtype = TREE_VALUE (arg); - int tindex = 1; - if (TREE_CODE (argtype) == POINTER_TYPE) + char buf[12]; + int nrepeats = 0; + do { - /* This is O(N**2). Do we care? Cfr gcc/cp/method.c. */ - while (a != arg && argtype != TREE_VALUE (a)) - a = TREE_CHAIN (a), tindex++; + arg = TREE_CHAIN (arg); nrepeats++; } - else - a = arg; - if (a != arg) + while (arg != NULL_TREE && argtype == TREE_VALUE (arg)); + if (nrepeats > 1) { - char buf[12]; - int nrepeats = 0; - do - { - arg = TREE_CHAIN (arg); nrepeats++; - } - while (arg != NULL_TREE && argtype == TREE_VALUE (arg)); - if (nrepeats > 1) - { - obstack_1grow (&temporary_obstack, 'N'); - sprintf (buf, "%d", nrepeats); - obstack_grow (&temporary_obstack, buf, strlen (buf)); - if (nrepeats > 9) - obstack_1grow (&temporary_obstack, '_'); - } - else - obstack_1grow (&temporary_obstack, 'T'); - sprintf (buf, "%d", tindex); + obstack_1grow (&temporary_obstack, 'N'); + sprintf (buf, "%d", nrepeats); obstack_grow (&temporary_obstack, buf, strlen (buf)); - if (tindex > 9) + if (nrepeats > 9) obstack_1grow (&temporary_obstack, '_'); } else - { - append_gpp_mangled_type (&temporary_obstack, argtype); - arg = TREE_CHAIN (arg); - } + obstack_1grow (&temporary_obstack, 'T'); + sprintf (buf, "%d", tindex); + obstack_grow (&temporary_obstack, buf, strlen (buf)); + if (tindex > 9) + obstack_1grow (&temporary_obstack, '_'); } - if (method_name_needs_escapes) - obstack_1grow (&temporary_obstack, 'U'); - } - obstack_1grow (&temporary_obstack, '\0'); - asm_name = obstack_finish (&temporary_obstack); - DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name); - if (! METHOD_ABSTRACT (method_decl)) - make_function_rtl (method_decl); - obstack_free (&temporary_obstack, asm_name); - - if (method_name == init_identifier_node) - { - char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))); - for (ptr = p; *ptr; ) + else { - if (*ptr++ == '.') - p = ptr; + append_gpp_mangled_type (&temporary_obstack, argtype); + arg = TREE_CHAIN (arg); } - if (method_name_is_wfl) - EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p); - else - DECL_NAME (method_decl) = get_identifier (p); - DECL_CONSTRUCTOR_P (method_decl) = 1; } - else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl)) + if (method_name_needs_escapes) + obstack_1grow (&temporary_obstack, 'U'); + } + obstack_1grow (&temporary_obstack, '\0'); + asm_name = obstack_finish (&temporary_obstack); + DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name); + if (! METHOD_ABSTRACT (method_decl)) + make_function_rtl (method_decl); + obstack_free (&temporary_obstack, asm_name); + + if (method_name == init_identifier_node) + { + char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))); + for (ptr = p; *ptr; ) { - tree method_sig = build_java_argument_signature (TREE_TYPE (method_decl)); - tree super_method = lookup_argument_method (super_class, method_name, + if (*ptr++ == '.') + p = ptr; + } + if (method_name_is_wfl) + EXPR_WFL_NODE (DECL_NAME (method_decl)) = get_identifier (p); + else + DECL_NAME (method_decl) = get_identifier (p); + DECL_CONSTRUCTOR_P (method_decl) = 1; + } + else if (! METHOD_STATIC (method_decl) && !DECL_ARTIFICIAL (method_decl)) + { + tree method_sig = + build_java_argument_signature (TREE_TYPE (method_decl)); + tree super_method = lookup_argument_method (super_class, method_name, method_sig); - if (super_method != NULL_TREE) - { - DECL_VINDEX (method_decl) = DECL_VINDEX (super_method); - if (DECL_VINDEX (method_decl) == NULL_TREE) - error_with_decl (method_decl, - "non-static method '%s' overrides static method"); + if (super_method != NULL_TREE) + { + DECL_VINDEX (method_decl) = DECL_VINDEX (super_method); + if (DECL_VINDEX (method_decl) == NULL_TREE) + error_with_decl (method_decl, + "non-static method '%s' overrides static method"); #if 0 - else if (TREE_TYPE (TREE_TYPE (method_decl)) - != TREE_TYPE (TREE_TYPE (super_method))) - { - error_with_decl (method_decl, - "Method `%s' redefined with different return type"); - error_with_decl (super_method, - "Overridden decl is here"); - } +else if (TREE_TYPE (TREE_TYPE (method_decl)) + != TREE_TYPE (TREE_TYPE (super_method))) + { + error_with_decl (method_decl, + "Method `%s' redefined with different return type"); + error_with_decl (super_method, + "Overridden decl is here"); + } #endif - } - else if (! METHOD_FINAL (method_decl) - && ! CLASS_FINAL (TYPE_NAME (this_class))) - { - DECL_VINDEX (method_decl) = dtable_count; - dtable_count = build_int_2 (1+TREE_INT_CST_LOW (dtable_count), 0); - } + } + else if (! METHOD_FINAL (method_decl) + && ! CLASS_FINAL (TYPE_NAME (this_class)) + && dtable_count) + { + DECL_VINDEX (method_decl) = dtable_count; + dtable_count = build_int_2 (1+TREE_INT_CST_LOW (dtable_count), 0); } } - TYPE_NVIRTUALS (this_class) = dtable_count; - -#ifdef JAVA_USE_HANDLES - layout_type (handle_type); -#endif + return dtable_count; } static tree registered_class = NULL_TREE; |