aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/class.c
diff options
context:
space:
mode:
authorAlexandre Petit-Bianco <apbianco@gcc.gnu.org>1998-11-24 09:57:41 -0800
committerAlexandre Petit-Bianco <apbianco@gcc.gnu.org>1998-11-24 09:57:41 -0800
commit23a79c61921246f3d84df2503555208f2683203e (patch)
treeddfaaed8a863a8721201f3dd3d76d282cc58791c /gcc/java/class.c
parent333a9f0aafc0d0e426d948e545daae6f6d277f19 (diff)
downloadgcc-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.c373
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;