aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/class.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/java/class.c')
-rw-r--r--gcc/java/class.c357
1 files changed, 12 insertions, 345 deletions
diff --git a/gcc/java/class.c b/gcc/java/class.c
index dbf3f4e..5e1e0b8 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -37,25 +37,18 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "parse.h"
#include "ggc.h"
-static tree mangle_class_field PARAMS ((tree class));
static tree make_method_value PARAMS ((tree));
static tree build_java_method_type PARAMS ((tree, tree, int));
static int32 hashUtf8String PARAMS ((const char *, int));
static tree make_field_value PARAMS ((tree));
static tree get_dispatch_vector PARAMS ((tree));
static tree get_dispatch_table PARAMS ((tree, tree));
-static void append_gpp_mangled_type PARAMS ((struct obstack *, tree));
-static tree mangle_static_field PARAMS ((tree));
static void add_interface_do PARAMS ((tree, tree, int));
static tree maybe_layout_super_class PARAMS ((tree, tree));
static int assume_compiled PARAMS ((const char *));
static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *,
struct hash_table *,
hash_table_key));
-static int utf8_cmp PARAMS ((const unsigned char *, int, const char *));
-static int cxx_keyword_p PARAMS ((const char *, int));
-static tree mangle_field PARAMS ((tree, tree));
-
static rtx registerClass_libfunc;
extern struct obstack permanent_obstack;
@@ -890,7 +883,8 @@ build_class_ref (type)
TREE_PUBLIC (decl) = 1;
DECL_IGNORED_P (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
- DECL_ASSEMBLER_NAME (decl) = mangle_class_field (type);
+ DECL_ASSEMBLER_NAME (decl) =
+ java_mangle_class_field (&temporary_obstack, type);
make_decl_rtl (decl, NULL);
pushdecl_top_level (decl);
if (is_compiled == 1)
@@ -1545,147 +1539,13 @@ is_compiled_class (class)
return 0;
}
-/* Append the mangled name of TYPE onto OBSTACK. */
-
-static void
-append_gpp_mangled_type (obstack, type)
- struct obstack *obstack;
- tree type;
-{
- switch (TREE_CODE (type))
- {
- char code;
- case BOOLEAN_TYPE: code = 'b'; goto primitive;
- case CHAR_TYPE: code = 'w'; goto primitive;
- case VOID_TYPE: code = 'v'; goto primitive;
- case INTEGER_TYPE:
- /* Get the original type instead of the arguments promoted type.
- Avoid symbol name clashes. Should call a function to do that.
- FIXME. */
- if (type == promoted_short_type_node)
- type = short_type_node;
- if (type == promoted_byte_type_node)
- type = byte_type_node;
- switch (TYPE_PRECISION (type))
- {
- case 8: code = 'c'; goto primitive;
- case 16: code = 's'; goto primitive;
- case 32: code = 'i'; goto primitive;
- case 64: code = 'x'; goto primitive;
- default: goto bad_type;
- }
- primitive:
- obstack_1grow (obstack, code);
- break;
- case REAL_TYPE:
- switch (TYPE_PRECISION (type))
- {
- case 32: code = 'f'; goto primitive;
- case 64: code = 'd'; goto primitive;
- default: goto bad_type;
- }
- case POINTER_TYPE:
- type = TREE_TYPE (type);
- obstack_1grow (obstack, 'P');
- case RECORD_TYPE:
- if (TYPE_ARRAY_P (type))
- {
- obstack_grow (obstack, "t6JArray1Z", sizeof("t6JArray1Z")-1);
- append_gpp_mangled_type (obstack, TYPE_ARRAY_ELEMENT (type));
- }
- else
- {
- const char *class_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
- append_gpp_mangled_classtype (obstack, class_name);
- }
- break;
- bad_type:
- default:
- fatal ("internal error - trying to mangle unknown type");
- }
-}
-
-/* Build the mangled name of a field, given the class name and the
- field name. */
-
-static tree
-mangle_field (class, name)
- tree class, name;
-{
- int encoded_len;
-#if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL)
- obstack_1grow (&temporary_obstack, '_');
-#else
- obstack_grow (&temporary_obstack, "__static_", 9);
-#endif
- append_gpp_mangled_type (&temporary_obstack, class);
- encoded_len = unicode_mangling_length (IDENTIFIER_POINTER (name),
- IDENTIFIER_LENGTH (name));
- if (encoded_len > 0)
- {
- obstack_1grow (&temporary_obstack, 'U');
- }
-#ifndef NO_DOLLAR_IN_LABEL
- obstack_1grow (&temporary_obstack, '$');
-#else /* NO_DOLLAR_IN_LABEL */
-#ifndef NO_DOT_IN_LABEL
- obstack_1grow (&temporary_obstack, '.');
-#else /* NO_DOT_IN_LABEL */
- obstack_1grow (&temporary_obstack, '_');
-#endif /* NO_DOT_IN_LABEL */
-#endif /* NO_DOLLAR_IN_LABEL */
- if (encoded_len > 0)
- {
- emit_unicode_mangled_name (&temporary_obstack,
- IDENTIFIER_POINTER (name),
- IDENTIFIER_LENGTH (name));
- }
- else
- {
- obstack_grow (&temporary_obstack,
- IDENTIFIER_POINTER (name),
- IDENTIFIER_LENGTH (name));
- }
-
- /* Mangle C++ keywords by appending a `$'. */
- /* FIXME: NO_DOLLAR_IN_LABEL */
- if (cxx_keyword_p (IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name)))
- obstack_grow (&temporary_obstack, "$", 1);
-
- obstack_1grow (&temporary_obstack, '\0');
- name = get_identifier (obstack_base (&temporary_obstack));
- obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
- return name;
-}
-
-/* Build the mangled name of the `class' field. */
-
-static tree
-mangle_class_field (class)
- tree class;
-{
- /* We know that we can use `class$' to mangle the class object,
- because `class' is a reserved word in Java and thus can't appear
- as a field or method name. */
- return mangle_field (class, get_identifier ("class$"));
-}
-
-/* Build the mangled (assembly-level) name of the static field FIELD. */
-
-static tree
-mangle_static_field (field)
- tree field;
-{
- return mangle_field (DECL_CONTEXT (field), DECL_NAME (field));
-}
-
/* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */
tree
build_dtable_decl (type)
tree type;
{
- tree name, dtype;
+ tree dtype;
/* We need to build a new dtable type so that its size is uniquely
computed when we're dealing with the class for real and not just
@@ -1706,12 +1566,8 @@ build_dtable_decl (type)
else
dtype = dtable_type;
- obstack_grow (&temporary_obstack, "__vt_", 5);
- append_gpp_mangled_type (&temporary_obstack, type);
- obstack_1grow (&temporary_obstack, '\0');
- name = get_identifier (obstack_base (&temporary_obstack));
- obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
- return build_decl (VAR_DECL, name, dtype);
+ return build_decl (VAR_DECL,
+ java_mangle_vtable (&temporary_obstack, type), dtype);
}
/* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
@@ -1836,7 +1692,8 @@ layout_class (this_class)
if (FIELD_STATIC (field))
{
/* Set DECL_ASSEMBLER_NAME to something suitably mangled. */
- DECL_ASSEMBLER_NAME (field) = mangle_static_field (field);
+ DECL_ASSEMBLER_NAME (field) =
+ java_mangle_decl (&temporary_obstack, field);
}
}
@@ -1916,218 +1773,38 @@ layout_class_methods (this_class)
#endif
}
-/* A sorted list of all C++ keywords. */
-
-static const char *cxx_keywords[] =
-{
- "asm",
- "auto",
- "bool",
- "const_cast",
- "delete",
- "dynamic_cast",
- "enum",
- "explicit",
- "extern",
- "friend",
- "inline",
- "mutable",
- "namespace",
- "overload",
- "register",
- "reinterpret_cast",
- "signed",
- "sizeof",
- "static_cast",
- "struct",
- "template",
- "typedef",
- "typeid",
- "typename",
- "typenameopt",
- "union",
- "unsigned",
- "using",
- "virtual",
- "volatile",
- "wchar_t"
-};
-
/* Return 0 if NAME is equal to STR, -1 if STR is "less" than NAME,
and 1 if STR is "greater" than NAME. */
-static int
-utf8_cmp (str, length, name)
- const unsigned char *str;
- int length;
- const char *name;
-{
- const unsigned char *limit = str + length;
- int i;
-
- for (i = 0; name[i]; ++i)
- {
- int ch = UTF8_GET (str, limit);
- if (ch != name[i])
- return ch - name[i];
- }
-
- return str == limit ? 0 : 1;
-}
-
-/* Return true if NAME is a C++ keyword. */
-
-static int
-cxx_keyword_p (name, length)
- const char *name;
- int length;
-{
- int last = ARRAY_SIZE (cxx_keywords);
- int first = 0;
- int mid = (last + first) / 2;
- int old = -1;
-
- for (mid = (last + first) / 2;
- mid != old;
- old = mid, mid = (last + first) / 2)
- {
- int kwl = strlen (cxx_keywords[mid]);
- int min_length = kwl > length ? length : kwl;
- int r = utf8_cmp (name, min_length, cxx_keywords[mid]);
-
- if (r == 0)
- {
- int i;
- /* We've found a match if all the remaining characters are
- `$'. */
- for (i = min_length; i < length && name[i] == '$'; ++i)
- ;
- if (i == length)
- return 1;
- r = 1;
- }
-
- if (r < 0)
- last = mid;
- else
- first = mid;
- }
- return 0;
-}
-
/* Lay METHOD_DECL out, returning a possibly new value of
- DTABLE_COUNT. */
+ DTABLE_COUNT. Also mangle the method's name. */
tree
layout_class_method (this_class, super_class, method_decl, dtable_count)
tree this_class, super_class, method_decl, dtable_count;
{
- const char *ptr;
- 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 (!ID_INIT_P (method_name) && !ID_FINIT_P (method_name))
- {
- 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));
- }
-
- /* Mangle C++ keywords by appending a `$'. */
- /* FIXME: NO_DOLLAR_IN_LABEL */
- if (cxx_keyword_p (IDENTIFIER_POINTER (method_name),
- IDENTIFIER_LENGTH (method_name)))
- obstack_grow (&temporary_obstack, "$", 1);
- }
-
- obstack_grow (&temporary_obstack, "__", 2);
- if (ID_FINIT_P (method_name))
- 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)
- {
- /* 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
- {
- arg = TREE_CHAIN (arg); nrepeats++;
- }
- while (arg != end_params_node && 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_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');
-
- obstack_1grow (&temporary_obstack, '\0');
- asm_name = obstack_finish (&temporary_obstack);
- DECL_ASSEMBLER_NAME (method_decl) = get_identifier (asm_name);
+ /* This is a good occasion to mangle the method's name */
+ DECL_ASSEMBLER_NAME (method_decl) =
+ java_mangle_decl (&temporary_obstack, method_decl);
/* We don't generate a RTL for the method if it's abstract, or if
it's an interface method that isn't clinit. */
if (! METHOD_ABSTRACT (method_decl)
|| (CLASS_INTERFACE (TYPE_NAME (this_class))
&& (DECL_CLINIT_P (method_decl))))
make_decl_rtl (method_decl, NULL);
- obstack_free (&temporary_obstack, asm_name);
if (ID_INIT_P (method_name))
{
const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
+ const char *ptr;
for (ptr = p; *ptr; )
{
if (*ptr++ == '.')
@@ -2153,16 +1830,6 @@ layout_class_method (this_class, super_class, method_decl, dtable_count)
&& !CLASS_FROM_SOURCE_P (this_class))
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");
- }
-#endif
}
else if (! METHOD_FINAL (method_decl)
&& ! METHOD_PRIVATE (method_decl)