java-tree.h (end_params_node): Declare global.
d * java-tree.h (end_params_node): Declare global. * decl.c (end_params_node): New global. (init_decl_processing, start_java_method): Use end_params_node for end of list of parameter types. Follows correct gcc conventions. * expr.c (pop_argument_types, pop_arguments): Likewise. * lang.c (put_decl_node): Likewise. * typeck.c (various places): Likewise. * class.y (various places): Likewise. * parse.y (various places): Likewise. * parse.y (java_complete_tree): Move CAN_COMPLETE_NORMALLY. (build_jump_to_finally): Add missing CAN_COMPLETE_NORMALLY. * class.c: Add #include flags.h, remove no-longer needed declaration. * class.c (layout_class_method): Remove commented-out code, re-format. Don't add vtable entry (or index) for private methods. * expr.c (expand_invoke): A private method is implicitly final. * class.c (make_class_data): If inlining or optimizing, skip private methods. * class.c (finish_class): New function. Calls existing methods, but alls emits deferred inline functions. * jcf-parse.c (parse_class_file): Call finish_class. * parse.y (java_complete_expand_methods): Likewise. * expr.c (build_java_binop): Explicit default, to silence -Wall. From-SVN: r23869
This commit is contained in:
parent
df8940cf1b
commit
75d01ad77d
210
gcc/java/class.c
210
gcc/java/class.c
|
@ -28,6 +28,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
#include "system.h"
|
||||
#include "tree.h"
|
||||
#include "rtl.h"
|
||||
#include "flags.h"
|
||||
#include "java-tree.h"
|
||||
#include "jcf.h"
|
||||
#include "obstack.h"
|
||||
|
@ -994,7 +995,11 @@ make_class_data (type)
|
|||
for (method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (type));
|
||||
method != NULL_TREE; method = TREE_CHAIN (method))
|
||||
{
|
||||
tree init = make_method_value (method, this_class_addr);
|
||||
tree init;
|
||||
if (METHOD_PRIVATE (method)
|
||||
&& (flag_inline_functions || optimize))
|
||||
continue;
|
||||
init = make_method_value (method, this_class_addr);
|
||||
method_count++;
|
||||
methods = tree_cons (NULL_TREE, init, methods);
|
||||
}
|
||||
|
@ -1083,8 +1088,13 @@ make_class_data (type)
|
|||
START_RECORD_CONSTRUCTOR (cons, class_type_node);
|
||||
PUSH_SUPER_VALUE (cons, temp);
|
||||
PUSH_FIELD_VALUE (cons, "next", null_pointer_node);
|
||||
#if 0
|
||||
/* Need to fix _Jv_FindClassFromSignature. */
|
||||
PUSH_FIELD_VALUE (cons, "name", build_utf8_ref (DECL_NAME (type_decl)));
|
||||
#else
|
||||
PUSH_FIELD_VALUE (cons, "name",
|
||||
build_utf8_ref (build_internal_class_name (type)));
|
||||
#endif
|
||||
PUSH_FIELD_VALUE (cons, "accflags",
|
||||
build_int_2 (get_access_flags_from_decl (type_decl), 0));
|
||||
|
||||
|
@ -1101,7 +1111,6 @@ make_class_data (type)
|
|||
PUSH_FIELD_VALUE (cons, "field_count", build_int_2 (field_count, 0));
|
||||
PUSH_FIELD_VALUE (cons, "static_field_count",
|
||||
build_int_2 (static_field_count, 0));
|
||||
/* For now, we let Kaffe fill in the dtable. */
|
||||
PUSH_FIELD_VALUE (cons, "dtable",
|
||||
dtable_decl == NULL_TREE ? null_pointer_node
|
||||
: build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl));
|
||||
|
@ -1118,6 +1127,35 @@ make_class_data (type)
|
|||
rest_of_decl_compilation (decl, (char*) 0, 1, 0);
|
||||
}
|
||||
|
||||
void
|
||||
finish_class (cl)
|
||||
tree cl;
|
||||
{
|
||||
tree method;
|
||||
|
||||
/* Emit deferred inline methods. */
|
||||
for ( method = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (current_class));
|
||||
method != NULL_TREE; method = TREE_CHAIN (method))
|
||||
{
|
||||
if (! TREE_ASM_WRITTEN (method) && DECL_SAVED_INSNS (method) != 0)
|
||||
{
|
||||
/* It's a deferred inline method. Decide if we need to emit it. */
|
||||
if (flag_keep_inline_functions
|
||||
|| TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (method))
|
||||
|| ! METHOD_PRIVATE (method))
|
||||
{
|
||||
temporary_allocation ();
|
||||
output_inline_function (method);
|
||||
permanent_allocation (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
make_class_data (current_class);
|
||||
register_class ();
|
||||
rest_of_decl_compilation (TYPE_NAME (current_class), (char*) 0, 1, 0);
|
||||
}
|
||||
|
||||
/* Return 2 if CLASS is compiled by this compilation job;
|
||||
return 1 if CLASS can otherwise be assumed to be compiled;
|
||||
return 0 if we cannot assume that CLASS is compiled.
|
||||
|
@ -1435,113 +1473,91 @@ layout_class_method (this_class, super_class, method_decl, dtable_count)
|
|||
char *ptr;
|
||||
char buf[8];
|
||||
char *asm_name;
|
||||
tree arg, arglist, t;
|
||||
int method_name_needs_escapes = 0;
|
||||
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))
|
||||
|
||||
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));
|
||||
}
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
obstack_grow (&temporary_obstack,
|
||||
IDENTIFIER_POINTER (method_name),
|
||||
IDENTIFIER_LENGTH (method_name));
|
||||
}
|
||||
}
|
||||
|
||||
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; )
|
||||
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 != end_params_node; )
|
||||
{
|
||||
tree a = arglist;
|
||||
tree argtype = TREE_VALUE (arg);
|
||||
int tindex = 1;
|
||||
if (TREE_CODE (argtype) == POINTER_TYPE)
|
||||
{
|
||||
tree a = arglist;
|
||||
tree argtype = TREE_VALUE (arg);
|
||||
int tindex = 1;
|
||||
if (TREE_CODE (argtype) == POINTER_TYPE)
|
||||
/* 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++;
|
||||
}
|
||||
else
|
||||
a = arg;
|
||||
if (a != arg)
|
||||
{
|
||||
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 != end_params_node && 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, '_');
|
||||
}
|
||||
else
|
||||
{
|
||||
append_gpp_mangled_type (&temporary_obstack, argtype);
|
||||
arg = TREE_CHAIN (arg);
|
||||
}
|
||||
if (method_name_needs_escapes)
|
||||
obstack_1grow (&temporary_obstack, 'U');
|
||||
}
|
||||
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);
|
||||
|
@ -1576,17 +1592,18 @@ layout_class_method (this_class, super_class, method_decl, dtable_count)
|
|||
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)
|
||||
&& ! METHOD_PRIVATE (method_decl)
|
||||
&& ! CLASS_FINAL (TYPE_NAME (this_class))
|
||||
&& dtable_count)
|
||||
{
|
||||
|
@ -1625,7 +1642,7 @@ emit_register_classes ()
|
|||
|
||||
extern tree get_file_function_name PROTO((int));
|
||||
tree init_name = get_file_function_name ('I');
|
||||
tree init_type = build_function_type (void_type_node, NULL_TREE);
|
||||
tree init_type = build_function_type (void_type_node, end_params_node);
|
||||
tree init_decl;
|
||||
tree t;
|
||||
|
||||
|
@ -1650,7 +1667,6 @@ emit_register_classes ()
|
|||
poplevel (1, 0, 1);
|
||||
{
|
||||
/* Force generation, even with -O3 or deeper. Gross hack. FIXME */
|
||||
extern int flag_inline_functions;
|
||||
int saved_flag = flag_inline_functions;
|
||||
flag_inline_functions = 0;
|
||||
rest_of_compilation (init_decl);
|
||||
|
|
Loading…
Reference in New Issue