+2000-10-05 Tom Tromey <tromey@cygnus.com>
+
+ * jvspec.c (jvgenmain_spec): Added `-fdollars-in-identifiers'.
+ * jvgenmain.c (class_mangling_prefix): Removed.
+ (class_mangling_suffix): New global.
+ (main): Use it.
+ * gjavah.c (cxx_keyword_subst): Mangle C++ keywords by appending
+ `$'.
+ (print_method_info): Handle overrides for static and final
+ methods.
+ (process_file): Generate declaration for class object field.
+ * class.c (cxx_keywords): New array.
+ (utf8_cmp): New function.
+ (cxx_keyword_p): New function.
+ (layout_class_method): Mangle C++ keywords by appending `$'.
+ (mangle_field): New function.
+ (mangle_class_field): Use mangle_field. Mangle class name as
+ `class$'.
+ (mangle_static_field): Use mangle_field.
+
Tue Oct 3 13:44:37 2000 Alexandre Petit-Bianco <apbianco@cygnus.com>
* decl.c (find_local_variable): Removed uncessary type check and
(argument_types_convertible): Likewise.
(patch_cast): Rename wfl_op parameter to avoid macro conflicts.
+>>>>>>> 1.531
2000-09-14 Tom Tromey <tromey@cygnus.com>
* lex.h: Use HAVE_ICONV_H, not HAVE_ICONV.
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;
}
}
-/* Build the mangled name of the `class' field. */
-
-static tree
-mangle_class_field (class)
- tree class;
-{
- tree name;
- obstack_grow (&temporary_obstack, "_CL_", 4);
- append_gpp_mangled_type (&temporary_obstack, class);
- 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 (assembly-level) name of the static field FIELD. */
+/* Build the mangled name of a field, given the class name and the
+ field name. */
static tree
-mangle_static_field (field)
- tree field;
+mangle_field (class, name)
+ tree class, name;
{
- tree class = DECL_CONTEXT (field);
- tree name = DECL_NAME (field);
int encoded_len;
#if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL)
obstack_1grow (&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
}
else
dtable_count = integer_zero_node;
-
+
TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type));
for (method_decl = TYPE_METHODS (handle_type);
pop_obstacks ();
}
+/* 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 r = utf8_cmp (name, length, cxx_keywords[mid]);
+
+ if (r == 0)
+ return 1;
+ else if (r < 0)
+ last = mid;
+ else
+ first = mid;
+ }
+ return 0;
+}
+
/* Lay METHOD_DECL out, returning a possibly new value of
DTABLE_COUNT. */
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);
if (r == 0)
{
- char *str = xmalloc (9 + strlen (cxx_keywords[mid]));
- strcpy (str, "__dummy_");
- strcat (str, cxx_keywords[mid]);
+ char *str = xmalloc (2 + strlen (cxx_keywords[mid]));
+ strcpy (str, cxx_keywords[mid]);
+ strcat (str, "$");
return str;
}
else if (r < 0)
(not only for calls to this function for for other functions
after it in the vtbl). So we give it a dummy name instead. */
override = cxx_keyword_subst (str, length);
- if (override)
- {
- /* If the method is static or final, we can safely skip it.
- If we don't skip it then we'll have problems since the
- mangling will be wrong. FIXME. */
- if (METHOD_IS_FINAL (jcf->access_flags, flags)
- || (flags & ACC_STATIC))
- {
- free (override);
- return;
- }
- }
}
if (! stubs && ! flag_jni)
{
if (flag_jni)
{
- fprintf (out, "\n#ifdef __cplusplus\n");
- fprintf (out, "}\n");
- fprintf (out, "#endif\n");
+ fprintf (out, "\n#ifdef __cplusplus\n");
+ fprintf (out, "}\n");
+ fprintf (out, "#endif\n");
}
else
{
for (i = 0; i < add_count; ++i)
fprintf (out, " %s\n", add_specs[i]);
- if (! stubs)
- fputs ("};\n", out);
+ /* Generate an entry for the class object. */
+ generate_access (out, ACC_PUBLIC);
+ fprintf (out, "\n static ::java::lang::Class class$;\n");
+
+ fputs ("};\n", out);
if (append_count > 0)
fputc ('\n', out);
const char main_method_prefix[] = "main__";
const char main_method_suffix[] = "Pt6JArray1ZPQ34java4lang6String";
-const char class_mangling_prefix[] = "_CL_";
+const char class_mangling_suffix[] = ".class$";
struct obstack name_obstack;
}
fprintf (stream, " 0\n};\n\n");
- fprintf (stream, "extern struct Class %s%s;\n",
- class_mangling_prefix, mangled_classname);
+ fprintf (stream, "extern int class __attribute__ ((alias (\"_%s%s\")));\n",
+ mangled_classname, class_mangling_suffix);
fprintf (stream, "int main (int argc, const char **argv)\n");
fprintf (stream, "{\n");
fprintf (stream, " _Jv_Compiler_Properties = props;\n");
- fprintf (stream, " JvRunMain (&%s%s, argc, argv);\n",
- class_mangling_prefix, mangled_classname);
+ fprintf (stream, " JvRunMain (&class, argc, argv);\n");
fprintf (stream, "}\n");
if (stream != stdout && fclose (stream) != 0)
{