static int supers_all_compiled (tree type);
static void add_interface_do (tree, tree, int);
static tree maybe_layout_super_class (tree, tree);
+static void add_miranda_methods (tree, tree);
static int assume_compiled (const char *);
-static tree build_method_symbols_entry (tree);
+static tree build_symbol_entry (tree);
static GTY(()) rtx registerClass_libfunc;
-static GTY(()) rtx registerResource_libfunc;
struct obstack temporary_obstack;
{
int len;
assume_compiled_node *parent;
- assume_compiled_node *node =
- xmalloc (sizeof (assume_compiled_node));
+ assume_compiled_node *node = xmalloc (sizeof (assume_compiled_node));
node->ident = xstrdup (ident);
node->excludep = excludep;
{
tree type;
type = make_node (RECORD_TYPE);
- TYPE_BINFO (type) = make_tree_vec (6);
+ TYPE_BINFO (type) = make_tree_vec (BINFO_ELTS);
MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
return type;
push_class (tree class_type, tree class_name)
{
tree decl, signature;
- const char *save_input_filename = input_filename;
- int save_lineno = lineno;
+ location_t saved_loc = input_location;
tree source_name = identifier_subst (class_name, "", '.', '/', ".java");
CLASS_P (class_type) = 1;
input_filename = IDENTIFIER_POINTER (source_name);
- lineno = 0;
+ input_line = 0;
decl = build_decl (TYPE_DECL, class_name, class_type);
/* dbxout needs a DECL_SIZE if in gstabs mode */
DECL_SIZE (decl) = integer_zero_node;
- input_filename = save_input_filename;
- lineno = save_lineno;
+ input_location = saved_loc;
signature = identifier_subst (class_name, "L", '.', '/', ";");
IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);
TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers);
if (super_class)
{
- tree super_binfo = make_tree_vec (6);
+ tree super_binfo = make_tree_vec (BINFO_ELTS);
BINFO_TYPE (super_binfo) = super_class;
BINFO_OFFSET (super_binfo) = integer_zero_node;
- TREE_VIA_PUBLIC (super_binfo) = 1;
TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (this_class)), 0)
= super_binfo;
CLASS_HAS_SUPER (this_class) = 1;
static void
add_interface_do (tree basetype_vec, tree interface_class, int i)
{
- tree interface_binfo = make_tree_vec (6);
+ tree interface_binfo = make_tree_vec (BINFO_ELTS);
BINFO_TYPE (interface_binfo) = interface_class;
BINFO_OFFSET (interface_binfo) = integer_zero_node;
BINFO_VPTR_FIELD (interface_binfo) = integer_zero_node;
TREE_VIA_VIRTUAL (interface_binfo) = 1;
- TREE_VIA_PUBLIC (interface_binfo) = 1;
TREE_VEC_ELT (basetype_vec, i) = interface_binfo;
}
METHOD_FINAL (fndecl) = DECL_INLINE (fndecl) = 1;
if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
- if (access_flags & ACC_TRANSIENT) METHOD_TRANSIENT (fndecl) = 1;
if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
return fndecl;
}
return hash;
}
-/* Generate a byte array representing the contents of FILENAME. The
- array is assigned a unique local symbol. The array represents a
- compiled Java resource, which is accessed by the runtime using
- NAME. */
-void
-compile_resource_file (char *name, const char *filename)
-{
- struct stat stat_buf;
- int fd;
- char *buffer;
- char buf[60];
- tree rtype, field = NULL_TREE, data_type, rinit, data, decl;
- static int Jr_count = 0;
-
- fd = open (filename, O_RDONLY | O_BINARY);
- if (fd < 0)
- {
- perror ("Failed to read resource file");
- return;
- }
- if (fstat (fd, &stat_buf) != 0
- || ! S_ISREG (stat_buf.st_mode))
- {
- perror ("Could not figure length of resource file");
- return;
- }
- buffer = xmalloc (strlen (name) + stat_buf.st_size);
- strcpy (buffer, name);
- read (fd, buffer + strlen (name), stat_buf.st_size);
- close (fd);
- data_type = build_prim_array_type (unsigned_byte_type_node,
- strlen (name) + stat_buf.st_size);
- rtype = make_node (RECORD_TYPE);
- PUSH_FIELD (rtype, field, "name_length", unsigned_int_type_node);
- PUSH_FIELD (rtype, field, "resource_length", unsigned_int_type_node);
- PUSH_FIELD (rtype, field, "data", data_type);
- FINISH_RECORD (rtype);
- START_RECORD_CONSTRUCTOR (rinit, rtype);
- PUSH_FIELD_VALUE (rinit, "name_length",
- build_int_2 (strlen (name), 0));
- PUSH_FIELD_VALUE (rinit, "resource_length",
- build_int_2 (stat_buf.st_size, 0));
- data = build_string (strlen(name) + stat_buf.st_size, buffer);
- TREE_TYPE (data) = data_type;
- PUSH_FIELD_VALUE (rinit, "data", data);
- FINISH_RECORD_CONSTRUCTOR (rinit);
- TREE_CONSTANT (rinit) = 1;
-
- /* Generate a unique-enough identifier. */
- sprintf(buf, "_Jr%d", ++Jr_count);
-
- decl = build_decl (VAR_DECL, get_identifier (buf), rtype);
- TREE_STATIC (decl) = 1;
- DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
- TREE_READONLY (decl) = 1;
- TREE_THIS_VOLATILE (decl) = 0;
- DECL_INITIAL (decl) = rinit;
- layout_decl (decl, 0);
- pushdecl (decl);
- rest_of_decl_compilation (decl, (char*) 0, global_bindings_p (), 0);
- make_decl_rtl (decl, (char*) 0);
- assemble_variable (decl, 1, 0, 0);
-
- {
- tree init_name = get_file_function_name ('I');
- tree init_type = build_function_type (void_type_node, end_params_node);
- tree init_decl;
-
- init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
- SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
- TREE_STATIC (init_decl) = 1;
- current_function_decl = init_decl;
- DECL_RESULT (init_decl) = build_decl (RESULT_DECL,
- NULL_TREE, void_type_node);
-
- /* It can be a static function as long as collect2 does not have
- to scan the object file to find its ctor/dtor routine. */
- TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;
-
- pushlevel (0);
- make_decl_rtl (init_decl, NULL);
- init_function_start (init_decl, input_filename, 0);
- expand_function_start (init_decl, 0);
-
- emit_library_call (registerResource_libfunc, 0, VOIDmode, 1,
- gen_rtx (SYMBOL_REF, Pmode, buf),
- Pmode);
-
- expand_function_end (input_filename, 0, 0);
- poplevel (1, 0, 1);
- {
- /* Force generation, even with -O3 or deeper. Gross hack. FIXME */
- int saved_flag = flag_inline_functions;
- flag_inline_functions = 0;
- rest_of_compilation (init_decl);
- flag_inline_functions = saved_flag;
- }
- current_function_decl = NULL_TREE;
- (* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
- DEFAULT_INIT_PRIORITY);
- }
-}
-
-tree utf8_decl_list = NULL_TREE;
+static GTY(()) tree utf8_decl_list = NULL_TREE;
tree
build_utf8_ref (tree name)
TREE_READONLY (decl) = 1;
TREE_THIS_VOLATILE (decl) = 0;
DECL_INITIAL (decl) = cinit;
-#ifdef HAVE_GAS_SHF_MERGE
- {
- int decl_size;
- /* Ensure decl_size is a multiple of utf8const_type's alignment. */
- decl_size = (name_len + 5 + TYPE_ALIGN_UNIT (utf8const_type) - 1)
- & ~(TYPE_ALIGN_UNIT (utf8const_type) - 1);
- if (flag_merge_constants && decl_size < 256)
- {
- char buf[32];
- int flags = (SECTION_OVERRIDE
- | SECTION_MERGE | (SECTION_ENTSIZE & decl_size));
- sprintf (buf, ".rodata.jutf8.%d", decl_size);
- named_section_flags (buf, flags);
- DECL_SECTION_NAME (decl) = build_string (strlen (buf), buf);
- }
- }
-#endif
+
+ if (HAVE_GAS_SHF_MERGE)
+ {
+ int decl_size;
+ /* Ensure decl_size is a multiple of utf8const_type's alignment. */
+ decl_size = (name_len + 5 + TYPE_ALIGN_UNIT (utf8const_type) - 1)
+ & ~(TYPE_ALIGN_UNIT (utf8const_type) - 1);
+ if (flag_merge_constants && decl_size < 256)
+ {
+ char buf[32];
+ int flags = (SECTION_OVERRIDE
+ | SECTION_MERGE | (SECTION_ENTSIZE & decl_size));
+ sprintf (buf, ".rodata.jutf8.%d", decl_size);
+ named_section_flags (buf, flags);
+ DECL_SECTION_NAME (decl) = build_string (strlen (buf), buf);
+ }
+ }
+
TREE_CHAIN (decl) = utf8_decl_list;
layout_decl (decl, 0);
pushdecl (decl);
return ref;
}
+/* Like build_class_ref, but instead of a direct reference generate a
+ pointer into the constant pool. */
+
+static tree
+build_indirect_class_ref (tree type)
+{
+ int index;
+ tree cl;
+ index = alloc_class_constant (type);
+ cl = build_ref_from_constant_pool (index);
+ TREE_TYPE (cl) = promote_type (class_ptr_type);
+ return cl;
+}
+
/* Build a reference to the class TYPE.
Also handles primitive types and array types. */
tree ref, decl_name, decl;
if (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type);
+
+ if (flag_indirect_dispatch
+ && type != current_class
+ && TREE_CODE (type) == RECORD_TYPE)
+ return build_indirect_class_ref (type);
+
if (TREE_CODE (type) == RECORD_TYPE)
{
if (TYPE_SIZE (type) == error_mark_node)
return ref;
}
else
- {
- int index;
- tree cl;
- index = alloc_class_constant (type);
- cl = build_ref_from_constant_pool (index);
- TREE_TYPE (cl) = promote_type (class_ptr_type);
- return cl;
- }
+ return build_indirect_class_ref (type);
}
tree
tree fclass = DECL_CONTEXT (fdecl);
int is_compiled = is_compiled_class (fclass);
- /* Allow static final fields to fold to a constant. */
- if (is_compiled || FIELD_FINAL (fdecl))
+ /* Allow static final fields to fold to a constant. When using
+ -fno-assume-compiled, gcj will sometimes try to fold a field from
+ an uncompiled class. This is required when the field in question
+ meets the appropriate criteria for a compile-time constant.
+ However, currently sometimes gcj is too eager and will end up
+ returning the field itself, leading to an incorrect external
+ reference being generated. */
+ if ((is_compiled
+ && (! flag_indirect_dispatch || current_class == fclass))
+ || (FIELD_FINAL (fdecl) && DECL_INITIAL (fdecl) != NULL_TREE
+ && (JSTRING_TYPE_P (TREE_TYPE (fdecl))
+ || JNUMERIC_TYPE_P (TREE_TYPE (fdecl)))
+ && TREE_CONSTANT (DECL_INITIAL (fdecl))))
{
if (!DECL_RTL_SET_P (fdecl))
{
}
return fdecl;
}
- else
+
+ if (flag_indirect_dispatch)
+ {
+ tree table_index
+ = build_int_2 (get_symbol_table_index (fdecl, &atable_methods), 0);
+ tree field_address
+ = build (ARRAY_REF, build_pointer_type (TREE_TYPE (fdecl)),
+ atable_decl, table_index);
+ return fold (build1 (INDIRECT_REF, TREE_TYPE (fdecl),
+ field_address));
+ }
+ else
{
/* Compile as:
* *(FTYPE*)build_class_ref(FCLASS)->fields[INDEX].info.addr */
access_flags |= ACC_NATIVE;
if (METHOD_ABSTRACT (decl))
access_flags |= ACC_ABSTRACT;
- if (METHOD_TRANSIENT (decl))
- access_flags |= ACC_TRANSIENT;
if (METHOD_STRICTFP (decl))
access_flags |= ACC_STRICT;
+ if (METHOD_INVISIBLE (decl))
+ access_flags |= ACC_INVISIBLE;
return access_flags;
}
abort ();
tree finit;
int flags;
tree type = TREE_TYPE (fdecl);
- int resolved = is_compiled_class (type);
+ int resolved = is_compiled_class (type) && ! flag_indirect_dispatch;
START_RECORD_CONSTRUCTOR (finit, field_type_node);
PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
PUSH_FIELD_VALUE
(finit, "info",
- build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
+ build_constructor (field_info_union_node,
build_tree_list
((FIELD_STATIC (fdecl)
? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
table = tree_cons (NULL_TREE, utf8, table);
}
type = build_prim_array_type (ptr_type_node, length);
- table = build (CONSTRUCTOR, type, NULL_TREE, table);
+ table = build_constructor (type, table);
/* Compute something unique enough. */
sprintf (buf, "_methods%d", method_name_count++);
array = build_decl (VAR_DECL, get_identifier (buf), type);
if (METHOD_ABSTRACT (method))
{
if (! abstract_p)
- warning_with_decl (method,
- "abstract method in non-abstract class");
+ warning ("%Jabstract method in non-abstract class", method);
if (TARGET_VTABLE_USES_DESCRIPTORS)
for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
if (TARGET_VTABLE_USES_DESCRIPTORS)
arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
arraysize += 2;
- return build (CONSTRUCTOR,
- build_prim_array_type (nativecode_ptr_type_node, arraysize),
- NULL_TREE, list);
+ return build_constructor (build_prim_array_type (nativecode_ptr_type_node,
+ arraysize), list);
}
static int
field_array_type = build_prim_array_type (field_type_node, field_count);
fields_decl = build_decl (VAR_DECL, mangled_classname ("_FL_", type),
field_array_type);
- DECL_INITIAL (fields_decl) = build (CONSTRUCTOR, field_array_type,
- NULL_TREE, static_fields);
+ DECL_INITIAL (fields_decl) = build_constructor (field_array_type,
+ static_fields);
TREE_STATIC (fields_decl) = 1;
DECL_ARTIFICIAL (fields_decl) = 1;
DECL_IGNORED_P (fields_decl) = 1;
method_array_type = build_prim_array_type (method_type_node, method_count);
methods_decl = build_decl (VAR_DECL, mangled_classname ("_MT_", type),
method_array_type);
- DECL_INITIAL (methods_decl) = build (CONSTRUCTOR, method_array_type,
- NULL_TREE, nreverse (methods));
+ DECL_INITIAL (methods_decl) = build_constructor (method_array_type,
+ nreverse (methods));
TREE_STATIC (methods_decl) = 1;
DECL_ARTIFICIAL (methods_decl) = 1;
DECL_IGNORED_P (methods_decl) = 1;
super = CLASSTYPE_SUPER (type);
if (super == NULL_TREE)
super = null_pointer_node;
- else if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
+ else if (! flag_indirect_dispatch
+ && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
&& assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
super = build_class_ref (super);
else
}
init = tree_cons (NULL_TREE, index, init);
}
- DECL_INITIAL (idecl) = build (CONSTRUCTOR, interface_array_type,
- NULL_TREE, init);
+ DECL_INITIAL (idecl) = build_constructor (interface_array_type, init);
TREE_STATIC (idecl) = 1;
DECL_ARTIFICIAL (idecl) = 1;
DECL_IGNORED_P (idecl) = 1;
PUSH_FIELD_VALUE (cons, "method_count", build_int_2 (method_count, 0));
if (flag_indirect_dispatch)
- PUSH_FIELD_VALUE (cons, "vtable_method_count", integer_minus_one_node)
+ PUSH_FIELD_VALUE (cons, "vtable_method_count", integer_minus_one_node);
else
PUSH_FIELD_VALUE (cons, "vtable_method_count", TYPE_NVIRTUALS (type));
build_int_2 (static_field_count, 0));
if (flag_indirect_dispatch)
- PUSH_FIELD_VALUE (cons, "vtable", null_pointer_node)
+ PUSH_FIELD_VALUE (cons, "vtable", null_pointer_node);
else
PUSH_FIELD_VALUE (cons, "vtable",
dtable_decl == NULL_TREE ? null_pointer_node
: build (PLUS_EXPR, dtable_ptr_type,
build1 (ADDR_EXPR, dtable_ptr_type, dtable_decl),
dtable_start_offset));
-
if (otable_methods == NULL_TREE)
{
PUSH_FIELD_VALUE (cons, "otable", null_pointer_node);
PUSH_FIELD_VALUE (cons, "otable",
build1 (ADDR_EXPR, otable_ptr_type, otable_decl));
PUSH_FIELD_VALUE (cons, "otable_syms",
- build1 (ADDR_EXPR, method_symbols_array_ptr_type,
+ build1 (ADDR_EXPR, symbols_array_ptr_type,
otable_syms_decl));
+ TREE_CONSTANT (otable_decl) = 1;
}
+ if (atable_methods == NULL_TREE)
+ {
+ PUSH_FIELD_VALUE (cons, "atable", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "atable_syms", null_pointer_node);
+ }
+ else
+ {
+ PUSH_FIELD_VALUE (cons, "atable",
+ build1 (ADDR_EXPR, atable_ptr_type, atable_decl));
+ PUSH_FIELD_VALUE (cons, "atable_syms",
+ build1 (ADDR_EXPR, symbols_array_ptr_type,
+ atable_syms_decl));
+ TREE_CONSTANT (atable_decl) = 1;
+ }
+
+ PUSH_FIELD_VALUE (cons, "catch_classes",
+ build1 (ADDR_EXPR, ptr_type_node, ctable_decl));
PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
PUSH_FIELD_VALUE (cons, "arrayclass", null_pointer_node);
PUSH_FIELD_VALUE (cons, "protectionDomain", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "signers", null_pointer_node);
PUSH_FIELD_VALUE (cons, "chain", null_pointer_node);
FINISH_RECORD_CONSTRUCTOR (cons);
super_class = TREE_TYPE (super_class);
else
{
+ /* do_resolve_class expects an EXPR_WITH_FILE_LOCATION, so
+ we give it one. */
+ tree this_wrap = NULL_TREE;
+
+ if (this_class)
+ {
+ tree this_decl = TYPE_NAME (this_class);
+ this_wrap = build_expr_wfl (this_class,
+ DECL_SOURCE_FILE (this_decl),
+ DECL_SOURCE_LINE (this_decl), 0);
+ }
super_class = do_resolve_class (NULL_TREE, /* FIXME? */
- super_class, NULL_TREE, this_class);
+ super_class, NULL_TREE, this_wrap);
if (!super_class)
return NULL_TREE; /* FIXME, NULL_TREE not checked by caller. */
super_class = TREE_TYPE (super_class);
{
tree super_class = CLASSTYPE_SUPER (this_class);
tree field;
-
+
class_list = tree_cons (this_class, NULL_TREE, class_list);
if (CLASS_BEING_LAIDOUT (this_class))
{
char buffer [1024];
char *report;
tree current;
-
+
sprintf (buffer, " with `%s'",
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
obstack_grow (&temporary_obstack, buffer, strlen (buffer));
layout_type (this_class);
- /* Also recursively load/layout any superinterfaces, but only if class was
- loaded from bytecode. The source parser will take care of this itself. */
+ /* Also recursively load/layout any superinterfaces, but only if
+ class was loaded from bytecode. The source parser will take care
+ of this itself. */
if (!CLASS_FROM_SOURCE_P (this_class))
{
tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);
}
}
- /* Convert the size back to an SI integer value */
- TYPE_SIZE_UNIT (this_class) =
+ /* Convert the size back to an SI integer value. */
+ TYPE_SIZE_UNIT (this_class) =
fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
CLASS_BEING_LAIDOUT (this_class) = 0;
class_list = TREE_CHAIN (class_list);
}
+static void
+add_miranda_methods (tree base_class, tree search_class)
+{
+ tree basetype_vec = TYPE_BINFO_BASETYPES (search_class);
+ int i, n = TREE_VEC_LENGTH (basetype_vec);
+ for (i = 1; i < n; ++i)
+ {
+ tree method_decl;
+ tree elt = TREE_VEC_ELT (basetype_vec, i);
+ if (elt == NULL_TREE)
+ break;
+ elt = BINFO_TYPE (elt);
+
+ /* Ensure that interface methods are seen in declared order. */
+ layout_class_methods (elt);
+
+ /* All base classes will have been laid out at this point, so the order
+ will be correct. This code must match similar layout code in the
+ runtime. */
+ for (method_decl = TYPE_METHODS (elt);
+ method_decl; method_decl = TREE_CHAIN (method_decl))
+ {
+ tree sig, override;
+
+ /* An interface can have <clinit>. */
+ if (ID_CLINIT_P (DECL_NAME (method_decl)))
+ continue;
+
+ sig = build_java_argument_signature (TREE_TYPE (method_decl));
+ override = lookup_argument_method (base_class,
+ DECL_NAME (method_decl), sig);
+ if (override == NULL_TREE)
+ {
+ /* Found a Miranda method. Add it. */
+ tree new_method;
+ sig = build_java_signature (TREE_TYPE (method_decl));
+ new_method
+ = add_method (base_class,
+ get_access_flags_from_decl (method_decl),
+ DECL_NAME (method_decl), sig);
+ METHOD_INVISIBLE (new_method) = 1;
+ }
+ }
+
+ /* Try superinterfaces. */
+ add_miranda_methods (base_class, elt);
+ }
+}
+
void
layout_class_methods (tree this_class)
{
else
dtable_count = integer_zero_node;
+ if (CLASS_ABSTRACT (TYPE_NAME (this_class)))
+ {
+ /* An abstract class can have methods which are declared only in
+ an implemented interface. These are called "Miranda
+ methods". We make a dummy method entry for such methods
+ here. */
+ add_miranda_methods (this_class, this_class);
+ }
+
TYPE_METHODS (this_class) = nreverse (TYPE_METHODS (this_class));
for (method_decl = TYPE_METHODS (this_class);
method_decl; method_decl = TREE_CHAIN (method_decl))
- dtable_count = layout_class_method (this_class, super_class,
+ dtable_count = layout_class_method (this_class, super_class,
method_decl, dtable_count);
TYPE_NVIRTUALS (this_class) = dtable_count;
tree method_name = DECL_NAME (method_decl);
TREE_PUBLIC (method_decl) = 1;
+ /* Considered external until we know what classes are being
+ compiled into this object file. */
+ DECL_EXTERNAL (method_decl) = 1;
/* This is a good occasion to mangle the method's name */
SET_DECL_ASSEMBLER_NAME (method_decl,
DECL_VINDEX (method_decl) = DECL_VINDEX (super_method);
if (DECL_VINDEX (method_decl) == NULL_TREE
&& !CLASS_FROM_SOURCE_P (this_class))
- error_with_decl (method_decl,
- "non-static method '%s' overrides static method");
+ error ("%Jnon-static method '%D' overrides static method",
+ method_decl, method_decl);
}
else if (! METHOD_FINAL (method_decl)
&& ! METHOD_PRIVATE (method_decl)
tree init_type = build_function_type (void_type_node, end_params_node);
tree init_decl;
tree t;
+ location_t saved_loc = input_location;
init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
+ DECL_SOURCE_LINE (init_decl) = 0;
TREE_STATIC (init_decl) = 1;
current_function_decl = init_decl;
DECL_RESULT (init_decl) = build_decl (RESULT_DECL, NULL_TREE,
pushlevel (0);
make_decl_rtl (init_decl, NULL);
- init_function_start (init_decl, input_filename, 0);
+ init_function_start (init_decl);
expand_function_start (init_decl, 0);
/* Do not allow the function to be deferred. */
for ( t = registered_class; t; t = TREE_CHAIN (t))
emit_library_call (registerClass_libfunc, 0, VOIDmode, 1,
XEXP (DECL_RTL (t), 0), Pmode);
-
- expand_function_end (input_filename, 0, 0);
+ input_location = DECL_SOURCE_LOCATION (init_decl);
+ expand_function_end ();
poplevel (1, 0, 1);
rest_of_compilation (init_decl);
current_function_decl = NULL_TREE;
if (targetm.have_ctors_dtors)
(* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
DEFAULT_INIT_PRIORITY);
+ input_location = saved_loc;
}
}
-/* Make a method_symbol_type (_Jv_MethodSymbol) node for METHOD. */
+/* Make a symbol_type (_Jv_MethodSymbol) node for DECL. */
-tree
-build_method_symbols_entry (tree method)
+static tree
+build_symbol_entry (tree decl)
{
- tree clname, name, signature, method_symbol;
+ tree clname, name, signature, sym;
- clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (method))));
- name = build_utf8_ref (DECL_NAME (method));
- signature = build_java_signature (TREE_TYPE (method));
+ clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
+ name = build_utf8_ref (DECL_NAME (decl));
+ signature = build_java_signature (TREE_TYPE (decl));
signature = build_utf8_ref (unmangle_classname
(IDENTIFIER_POINTER (signature),
IDENTIFIER_LENGTH (signature)));
- START_RECORD_CONSTRUCTOR (method_symbol, method_symbol_type);
- PUSH_FIELD_VALUE (method_symbol, "clname", clname);
- PUSH_FIELD_VALUE (method_symbol, "name", name);
- PUSH_FIELD_VALUE (method_symbol, "signature", signature);
- FINISH_RECORD_CONSTRUCTOR (method_symbol);
- TREE_CONSTANT (method_symbol) = 1;
+ START_RECORD_CONSTRUCTOR (sym, symbol_type);
+ PUSH_FIELD_VALUE (sym, "clname", clname);
+ PUSH_FIELD_VALUE (sym, "name", name);
+ PUSH_FIELD_VALUE (sym, "signature", signature);
+ FINISH_RECORD_CONSTRUCTOR (sym);
+ TREE_CONSTANT (sym) = 1;
- return method_symbol;
+ return sym;
}
-/* Emit the offset symbols table for indirect virtual dispatch. */
+/* Emit a symbol table: used by -findirect-dispatch. */
-void
-emit_offset_symbol_table (void)
+tree
+emit_symbol_table (tree name, tree the_table, tree decl_list, tree the_syms_decl,
+ tree the_array_element_type)
{
tree method_list, method, table, list, null_symbol;
- tree otable_bound, otable_array_type;
+ tree table_size, the_array_type;
int index;
- /* Only emit an offset table if this translation unit actually made virtual
- calls. */
- if (otable_methods == NULL_TREE)
- return;
+ /* Only emit a table if this translation unit actually made any
+ references via it. */
+ if (decl_list == NULL_TREE)
+ return the_table;
/* Build a list of _Jv_MethodSymbols for each entry in otable_methods. */
index = 0;
- method_list = otable_methods;
+ method_list = decl_list;
list = NULL_TREE;
while (method_list != NULL_TREE)
{
method = TREE_VALUE (method_list);
- list = tree_cons (NULL_TREE, build_method_symbols_entry (method), list);
+ list = tree_cons (NULL_TREE, build_symbol_entry (method), list);
method_list = TREE_CHAIN (method_list);
index++;
}
/* Terminate the list with a "null" entry. */
- START_RECORD_CONSTRUCTOR (null_symbol, method_symbol_type);
+ START_RECORD_CONSTRUCTOR (null_symbol, symbol_type);
PUSH_FIELD_VALUE (null_symbol, "clname", null_pointer_node);
PUSH_FIELD_VALUE (null_symbol, "name", null_pointer_node);
PUSH_FIELD_VALUE (null_symbol, "signature", null_pointer_node);
/* Put the list in the right order and make it a constructor. */
list = nreverse (list);
- table = build (CONSTRUCTOR, method_symbols_array_type, NULL_TREE, list);
+ table = build_constructor (symbols_array_type, list);
/* Make it the initial value for otable_syms and emit the decl. */
- DECL_INITIAL (otable_syms_decl) = table;
- DECL_ARTIFICIAL (otable_syms_decl) = 1;
- DECL_IGNORED_P (otable_syms_decl) = 1;
- rest_of_decl_compilation (otable_syms_decl, NULL, 1, 0);
+ DECL_INITIAL (the_syms_decl) = table;
+ DECL_ARTIFICIAL (the_syms_decl) = 1;
+ DECL_IGNORED_P (the_syms_decl) = 1;
+ rest_of_decl_compilation (the_syms_decl, NULL, 1, 0);
- /* Now that its size is known, redefine otable as an uninitialized static
- array of INDEX + 1 integers. The extra entry is used by the runtime
- to track whether the otable has been initialized. */
- otable_bound = build_index_type (build_int_2 (index, 0));
- otable_array_type = build_array_type (integer_type_node, otable_bound);
- otable_decl = build_decl (VAR_DECL, get_identifier ("otable"),
- otable_array_type);
- TREE_STATIC (otable_decl) = 1;
- TREE_READONLY (otable_decl) = 1;
- rest_of_decl_compilation (otable_decl, NULL, 1, 0);
+ /* Now that its size is known, redefine the table as an
+ uninitialized static array of INDEX + 1 elements. The extra entry
+ is used by the runtime to track whether the table has been
+ initialized. */
+ table_size = build_index_type (build_int_2 (index, 0));
+ the_array_type = build_array_type (the_array_element_type, table_size);
+ the_table = build_decl (VAR_DECL, name, the_array_type);
+ TREE_STATIC (the_table) = 1;
+ TREE_READONLY (the_table) = 1;
+ rest_of_decl_compilation (the_table, NULL, 1, 0);
+
+ return the_table;
+}
+
+/* make an entry for the catch_classes list. */
+tree
+make_catch_class_record (tree catch_class, tree classname)
+{
+ tree entry;
+ tree type = TREE_TYPE (TREE_TYPE (ctable_decl));
+ START_RECORD_CONSTRUCTOR (entry, type);
+ PUSH_FIELD_VALUE (entry, "address", catch_class);
+ PUSH_FIELD_VALUE (entry, "classname", classname);
+ FINISH_RECORD_CONSTRUCTOR (entry);
+ return entry;
+}
+
+
+/* Generate the list of Throwable classes that are caught by exception
+ handlers in this compilation. */
+void
+emit_catch_table (void)
+{
+ tree table, table_size, array_type;
+ catch_classes
+ = tree_cons (NULL,
+ make_catch_class_record (null_pointer_node, null_pointer_node),
+ catch_classes);
+ catch_classes = nreverse (catch_classes);
+ catch_classes
+ = tree_cons (NULL,
+ make_catch_class_record (null_pointer_node, null_pointer_node),
+ catch_classes);
+ table_size = build_index_type (build_int_2 (list_length (catch_classes), 0));
+ array_type
+ = build_array_type (TREE_TYPE (TREE_TYPE (ctable_decl)), table_size);
+ table = build_decl (VAR_DECL, DECL_NAME (ctable_decl), array_type);
+ DECL_INITIAL (table) = build_constructor (array_type, catch_classes);
+ TREE_STATIC (table) = 1;
+ TREE_READONLY (table) = 1;
+ rest_of_decl_compilation (table, NULL, 1, 0);
+ ctable_decl = table;
}
+
void
init_class_processing (void)
{
registerClass_libfunc = gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterClass");
- registerResource_libfunc =
- gen_rtx_SYMBOL_REF (Pmode, "_Jv_RegisterResource");
fields_ident = get_identifier ("fields");
info_ident = get_identifier ("info");
gcc_obstack_init (&temporary_obstack);
{
struct treetreehash_entry *e;
hashval_t hv = JAVA_TREEHASHHASH_H (t);
- e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv);
+ e = htab_find_with_hash (ht, t, hv);
if (e == NULL)
return NULL;
else