Commit e0a0c416 by Tom Tromey

jvspec.c (jvgenmain_spec): Added `-fdollars-in-identifiers'.

	* 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.

From-SVN: r36738
parent d1a458c4
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> Tue Oct 3 13:44:37 2000 Alexandre Petit-Bianco <apbianco@cygnus.com>
* decl.c (find_local_variable): Removed uncessary type check and * decl.c (find_local_variable): Removed uncessary type check and
...@@ -127,6 +147,7 @@ Wed Sep 13 11:50:35 2000 Alexandre Petit-Bianco <apbianco@cygnus.com> ...@@ -127,6 +147,7 @@ Wed Sep 13 11:50:35 2000 Alexandre Petit-Bianco <apbianco@cygnus.com>
(argument_types_convertible): Likewise. (argument_types_convertible): Likewise.
(patch_cast): Rename wfl_op parameter to avoid macro conflicts. (patch_cast): Rename wfl_op parameter to avoid macro conflicts.
>>>>>>> 1.531
2000-09-14 Tom Tromey <tromey@cygnus.com> 2000-09-14 Tom Tromey <tromey@cygnus.com>
* lex.h: Use HAVE_ICONV_H, not HAVE_ICONV. * lex.h: Use HAVE_ICONV_H, not HAVE_ICONV.
......
...@@ -52,6 +52,9 @@ static int assume_compiled PARAMS ((const char *)); ...@@ -52,6 +52,9 @@ static int assume_compiled PARAMS ((const char *));
static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *, static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *,
struct hash_table *, struct hash_table *,
hash_table_key)); 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; static rtx registerClass_libfunc;
...@@ -1626,29 +1629,13 @@ append_gpp_mangled_type (obstack, type) ...@@ -1626,29 +1629,13 @@ append_gpp_mangled_type (obstack, type)
} }
} }
/* Build the mangled name of the `class' field. */ /* Build the mangled name of a field, given the class name and the
field name. */
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. */
static tree static tree
mangle_static_field (field) mangle_field (class, name)
tree field; tree class, name;
{ {
tree class = DECL_CONTEXT (field);
tree name = DECL_NAME (field);
int encoded_len; int encoded_len;
#if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL) #if ! defined (NO_DOLLAR_IN_LABEL) || ! defined (NO_DOT_IN_LABEL)
obstack_1grow (&temporary_obstack, '_'); obstack_1grow (&temporary_obstack, '_');
...@@ -1683,12 +1670,39 @@ mangle_static_field (field) ...@@ -1683,12 +1670,39 @@ mangle_static_field (field)
IDENTIFIER_POINTER (name), IDENTIFIER_POINTER (name),
IDENTIFIER_LENGTH (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'); obstack_1grow (&temporary_obstack, '\0');
name = get_identifier (obstack_base (&temporary_obstack)); name = get_identifier (obstack_base (&temporary_obstack));
obstack_free (&temporary_obstack, obstack_base (&temporary_obstack)); obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
return name; 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. */ /* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */
tree tree
...@@ -1880,7 +1894,7 @@ layout_class_methods (this_class) ...@@ -1880,7 +1894,7 @@ layout_class_methods (this_class)
} }
else else
dtable_count = integer_zero_node; dtable_count = integer_zero_node;
TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type)); TYPE_METHODS (handle_type) = nreverse (TYPE_METHODS (handle_type));
for (method_decl = TYPE_METHODS (handle_type); for (method_decl = TYPE_METHODS (handle_type);
...@@ -1896,6 +1910,93 @@ layout_class_methods (this_class) ...@@ -1896,6 +1910,93 @@ layout_class_methods (this_class)
pop_obstacks (); 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 /* Lay METHOD_DECL out, returning a possibly new value of
DTABLE_COUNT. */ DTABLE_COUNT. */
...@@ -1931,8 +2032,14 @@ layout_class_method (this_class, super_class, method_decl, dtable_count) ...@@ -1931,8 +2032,14 @@ layout_class_method (this_class, super_class, method_decl, dtable_count)
IDENTIFIER_POINTER (method_name), IDENTIFIER_POINTER (method_name),
IDENTIFIER_LENGTH (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); obstack_grow (&temporary_obstack, "__", 2);
if (ID_FINIT_P (method_name)) if (ID_FINIT_P (method_name))
obstack_grow (&temporary_obstack, "finit", 5); obstack_grow (&temporary_obstack, "finit", 5);
......
...@@ -440,9 +440,9 @@ cxx_keyword_subst (str, length) ...@@ -440,9 +440,9 @@ cxx_keyword_subst (str, length)
if (r == 0) if (r == 0)
{ {
char *str = xmalloc (9 + strlen (cxx_keywords[mid])); char *str = xmalloc (2 + strlen (cxx_keywords[mid]));
strcpy (str, "__dummy_"); strcpy (str, cxx_keywords[mid]);
strcat (str, cxx_keywords[mid]); strcat (str, "$");
return str; return str;
} }
else if (r < 0) else if (r < 0)
...@@ -759,18 +759,6 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags, synth), ...@@ -759,18 +759,6 @@ DEFUN(print_method_info, (stream, jcf, name_index, sig_index, flags, synth),
(not only for calls to this function for for other functions (not only for calls to this function for for other functions
after it in the vtbl). So we give it a dummy name instead. */ after it in the vtbl). So we give it a dummy name instead. */
override = cxx_keyword_subst (str, length); 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 (! stubs && ! flag_jni)
...@@ -1844,9 +1832,9 @@ DEFUN(process_file, (jcf, out), ...@@ -1844,9 +1832,9 @@ DEFUN(process_file, (jcf, out),
{ {
if (flag_jni) if (flag_jni)
{ {
fprintf (out, "\n#ifdef __cplusplus\n"); fprintf (out, "\n#ifdef __cplusplus\n");
fprintf (out, "}\n"); fprintf (out, "}\n");
fprintf (out, "#endif\n"); fprintf (out, "#endif\n");
} }
else else
{ {
...@@ -1860,8 +1848,11 @@ DEFUN(process_file, (jcf, out), ...@@ -1860,8 +1848,11 @@ DEFUN(process_file, (jcf, out),
for (i = 0; i < add_count; ++i) for (i = 0; i < add_count; ++i)
fprintf (out, " %s\n", add_specs[i]); fprintf (out, " %s\n", add_specs[i]);
if (! stubs) /* Generate an entry for the class object. */
fputs ("};\n", out); generate_access (out, ACC_PUBLIC);
fprintf (out, "\n static ::java::lang::Class class$;\n");
fputs ("};\n", out);
if (append_count > 0) if (append_count > 0)
fputc ('\n', out); fputc ('\n', out);
......
...@@ -34,7 +34,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -34,7 +34,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
const char main_method_prefix[] = "main__"; const char main_method_prefix[] = "main__";
const char main_method_suffix[] = "Pt6JArray1ZPQ34java4lang6String"; const char main_method_suffix[] = "Pt6JArray1ZPQ34java4lang6String";
const char class_mangling_prefix[] = "_CL_"; const char class_mangling_suffix[] = ".class$";
struct obstack name_obstack; struct obstack name_obstack;
...@@ -155,13 +155,12 @@ main (int argc, const char **argv) ...@@ -155,13 +155,12 @@ main (int argc, const char **argv)
} }
fprintf (stream, " 0\n};\n\n"); fprintf (stream, " 0\n};\n\n");
fprintf (stream, "extern struct Class %s%s;\n", fprintf (stream, "extern int class __attribute__ ((alias (\"_%s%s\")));\n",
class_mangling_prefix, mangled_classname); mangled_classname, class_mangling_suffix);
fprintf (stream, "int main (int argc, const char **argv)\n"); fprintf (stream, "int main (int argc, const char **argv)\n");
fprintf (stream, "{\n"); fprintf (stream, "{\n");
fprintf (stream, " _Jv_Compiler_Properties = props;\n"); fprintf (stream, " _Jv_Compiler_Properties = props;\n");
fprintf (stream, " JvRunMain (&%s%s, argc, argv);\n", fprintf (stream, " JvRunMain (&class, argc, argv);\n");
class_mangling_prefix, mangled_classname);
fprintf (stream, "}\n"); fprintf (stream, "}\n");
if (stream != stdout && fclose (stream) != 0) if (stream != stdout && fclose (stream) != 0)
{ {
......
...@@ -61,7 +61,7 @@ const char jvgenmain_spec[] = ...@@ -61,7 +61,7 @@ const char jvgenmain_spec[] =
%{<fuse-boehm-gc} %{<fhash-synchronization} %{<fjni}\ %{<fuse-boehm-gc} %{<fhash-synchronization} %{<fjni}\
%{<fclasspath*} %{<fCLASSPATH*} %{<foutput-class-dir}\ %{<fclasspath*} %{<fCLASSPATH*} %{<foutput-class-dir}\
%{<fuse-divide-subroutine} %{<fno-use-divide-subroutine}\ %{<fuse-divide-subroutine} %{<fno-use-divide-subroutine}\
%{f*}\ %{f*} -fdollars-in-identifiers\
%{aux-info*}\ %{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%Umain.s}} |\n\ %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%Umain.s}} |\n\
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment