This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Re: V3 ABI Java symbol demangling
Mark Mitchell wrote:
> >>>>> "Bryce" == Bryce McKinlay <bryce@albatross.co.nz> writes:
>
> Bryce> Where can I find tests for v3 demangling? The testsuite
> Bryce> only seems to contain non-V3 cases. I can easily add a few
> Bryce> simple Java ones though.
>
> Sadly, our customer still hasn't gotten its lawyers together to let us
> release the tests. We are trying!
>
> Alex, would you run Bryce's modified demangler against our tests?
> He's adding support for the special Java demanglings.
Thanks. Here's an updated version of the patch. This one handles Java
primitive type names, and adds a few Java test cases.
[ bryce ]
2001-01-31 Bryce McKinlay <bryce@albatross.co.nz>
* cp-demangle.c (NAMESPACE_SEPARATOR): New define.
(struct demangling_def): Add `style' field.
(demangling_new): New parameter `style'. Set it in demangling_t.
(demangle_prefix): Use NAMESPACE_SEPARATOR.
(demangle_type_ptr): Don't emit pointer symbol if doing Java output.
(cp_demangle): New parameter `style'. Pass it to demangling_new().
(main): Call cp_demangle with extra parameter.
(java_demangle_v3): New function.
(java_builtin_type_names): New. Table of primitive type names used
for Java demangling.
(demangle_builtin_type): Look up in java_builtin_type_names if doing
Java-style output.
* cplus-dem.c (cplus_demangle): Use java_demangle_v3 to do Java
demangling.
(long_options): Remove obsolete `java' option.
(main): Remove explicit handling of `java' option. Instead, pass style
parameter in cplus_demangle flags as gdb does.
Index: include/demangle.h
===================================================================
RCS file: /cvs/gcc/egcs/include/demangle.h,v
retrieving revision 1.12
diff -u -r1.12 demangle.h
--- demangle.h 2000/12/05 13:28:46 1.12
+++ demangle.h 2001/01/31 00:50:05
@@ -120,8 +120,11 @@
extern enum demangling_styles
cplus_demangle_name_to_style PARAMS ((const char *name));
-/* V3 ABI demangling entry point, defined in cp-demangle.c. */
+/* V3 ABI demangling entry points, defined in cp-demangle.c. */
extern char*
cplus_demangle_v3 PARAMS ((const char* mangled));
+
+extern char*
+java_demangle_v3 PARAMS ((const char* mangled));
#endif /* DEMANGLE_H */
Index: libiberty/cplus-dem.c
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/cplus-dem.c,v
retrieving revision 1.71
diff -u -r1.71 cplus-dem.c
--- cplus-dem.c 2000/12/08 03:00:26 1.71
+++ cplus-dem.c 2001/01/31 00:50:08
@@ -1,6 +1,6 @@
/* Demangler for GNU C++
Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000 Free Software Foundation, Inc.
+ 2000, 2001 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
@@ -922,6 +922,13 @@
return ret;
}
+ if (JAVA_DEMANGLING)
+ {
+ ret = java_demangle_v3 (mangled);
+ if (ret)
+ return ret;
+ }
+
if (GNAT_DEMANGLING)
return ada_demangle(mangled,options);
@@ -4950,7 +4957,6 @@
{"strip-underscores", no_argument, 0, '_'},
{"format", required_argument, 0, 's'},
{"help", no_argument, 0, 'h'},
- {"java", no_argument, 0, 'j'},
{"no-strip-underscores", no_argument, 0, 'n'},
{"version", no_argument, 0, 'v'},
{0, no_argument, 0, 0}
@@ -5044,12 +5050,13 @@
char *result;
int c;
const char *valid_symbols;
+ enum demangling_styles style;
program_name = argv[0];
strip_underscore = prepends_underscore;
- while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF)
+ while ((c = getopt_long (argc, argv, "_ns:", long_options, (int *) 0)) != EOF)
{
switch (c)
{
@@ -5067,13 +5074,8 @@
case '_':
strip_underscore = 1;
break;
- case 'j':
- flags |= DMGL_JAVA;
- break;
case 's':
{
- enum demangling_styles style;
-
style = cplus_demangle_name_to_style (optarg);
if (style == unknown_demangling)
{
@@ -5146,7 +5148,7 @@
skip_first = i;
mbuffer[i] = 0;
-
+ flags |= style;
result = cplus_demangle (mbuffer + skip_first, flags);
if (result)
{
Index: libiberty/cp-demangle.c
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/cp-demangle.c,v
retrieving revision 1.26
diff -u -r1.26 cp-demangle.c
--- cp-demangle.c 2000/12/05 17:29:12 1.26
+++ cp-demangle.c 2001/01/31 00:50:10
@@ -1,5 +1,5 @@
/* Demangler for IA64 / g++ V3 ABI.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001 Free Software Foundation, Inc.
Written by Alex Samuel <samuel@codesourcery.com>.
This file is part of GNU CC.
@@ -68,6 +68,9 @@
anonymous namespace. */
#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_"
+/* Character(s) to use for namespace separation in demangled output */
+#define NAMESPACE_SEPARATOR (dm->style == DMGL_JAVA ? "." : "::")
+
/* If flag_verbose is zero, some simplifications will be made to the
output to make it easier to read and supress details that are
generally not of interest to the average C++ programmer.
@@ -166,6 +169,9 @@
/* The most recently demangled source-name. */
dyn_string_t last_source_name;
+
+ /* Language style to use for demangled output. */
+ int style;
};
typedef struct demangling_def *demangling_t;
@@ -240,7 +246,7 @@
static template_arg_list_t current_template_arg_list
PARAMS ((demangling_t));
static demangling_t demangling_new
- PARAMS ((const char *));
+ PARAMS ((const char *, int));
static void demangling_delete
PARAMS ((demangling_t));
@@ -783,8 +789,9 @@
Returns NULL if allocation fails. */
static demangling_t
-demangling_new (name)
+demangling_new (name, style)
const char *name;
+ int style;
{
demangling_t dm;
dm = (demangling_t) malloc (sizeof (struct demangling_def));
@@ -807,6 +814,7 @@
dyn_string_delete (dm->last_source_name);
return NULL;
}
+ dm->style = style;
return dm;
}
@@ -918,7 +926,7 @@
static status_t demangle_discriminator
PARAMS ((demangling_t, int));
static status_t cp_demangle
- PARAMS ((const char *, dyn_string_t));
+ PARAMS ((const char *, dyn_string_t, int));
#ifdef IN_LIBGCC2
static status_t cp_demangle_type
PARAMS ((const char*, dyn_string_t));
@@ -1222,7 +1230,7 @@
{
/* We have another level of scope qualification. */
if (nested)
- RETURN_IF_ERROR (result_add (dm, "::"));
+ RETURN_IF_ERROR (result_add (dm, NAMESPACE_SEPARATOR));
else
nested = 1;
@@ -2093,8 +2101,10 @@
RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos,
substitution_start));
/* Insert an asterisk where we're told to; it doesn't
- necessarily go at the end. */
- RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*'));
+ necessarily go at the end. If we're doing Java style output,
+ there is no pointer symbol. */
+ if (dm->style != DMGL_JAVA)
+ RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*'));
/* The next (outermost) pointer or reference character should go
after this one. */
++(*insert_pos);
@@ -2469,6 +2479,39 @@
"..." /* z */
};
+/* Java source names of builtin types. Types that arn't valid in Java
+ are also included here - we don't fail if someone attempts to demangle a
+ C++ symbol in Java style. */
+static const char *const java_builtin_type_names[26] =
+{
+ "signed char", /* a */
+ "boolean", /* C++ "bool" */ /* b */
+ "byte", /* C++ "char" */ /* c */
+ "double", /* d */
+ "long double", /* e */
+ "float", /* f */
+ "__float128", /* g */
+ "unsigned char", /* h */
+ "int", /* i */
+ "unsigned", /* j */
+ NULL, /* k */
+ "long", /* l */
+ "unsigned long", /* m */
+ "__int128", /* n */
+ "unsigned __int128", /* o */
+ NULL, /* p */
+ NULL, /* q */
+ NULL, /* r */
+ "short", /* s */
+ "unsigned short", /* t */
+ NULL, /* u */
+ "void", /* v */
+ "char", /* C++ "wchar_t" */ /* w */
+ "long", /* C++ "long long" */ /* x */
+ "unsigned long long", /* y */
+ "..." /* z */
+};
+
/* Demangles and emits a <builtin-type>.
<builtin-type> ::= v # void
@@ -2511,7 +2554,12 @@
}
else if (code >= 'a' && code <= 'z')
{
- const char *type_name = builtin_type_names[code - 'a'];
+ const char *type_name;
+ /* Java uses different names for some built-in types. */
+ if (dm->style == DMGL_JAVA)
+ type_name = java_builtin_type_names[code - 'a'];
+ else
+ type_name = builtin_type_names[code - 'a'];
if (type_name == NULL)
return "Unrecognized <builtin-type> code.";
@@ -3395,16 +3443,17 @@
an error message, and the contents of RESULT are unchanged. */
static status_t
-cp_demangle (name, result)
+cp_demangle (name, result, style)
const char *name;
dyn_string_t result;
+ int style;
{
status_t status;
int length = strlen (name);
if (length > 2 && name[0] == '_' && name[1] == 'Z')
{
- demangling_t dm = demangling_new (name);
+ demangling_t dm = demangling_new (name, style);
if (dm == NULL)
return STATUS_ALLOCATION_FAILED;
@@ -3551,7 +3600,7 @@
if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
/* MANGLED_NAME apprears to be a function or variable name.
Demangle it accordingly. */
- result = cp_demangle (mangled_name, &demangled_name);
+ result = cp_demangle (mangled_name, &demangled_name, 0);
else
/* Try to demangled MANGLED_NAME as the name of a type. */
result = cp_demangle_type (mangled_name, &demangled_name);
@@ -3610,7 +3659,7 @@
/* Create a dyn_string to hold the demangled name. */
demangled = dyn_string_new (0);
/* Attempt the demangling. */
- status = cp_demangle ((char *) mangled, demangled);
+ status = cp_demangle ((char *) mangled, demangled, 0);
if (STATUS_NO_ERROR (status))
/* Demangling succeeded. */
@@ -3634,6 +3683,110 @@
}
}
+/* Demangle a Java symbol. Java uses a subset of the V3 ABI C++ mangling
+ conventions, but the output formatting is a little different.
+ This instructs the C++ demangler not to emit pointer characters ("*"), and
+ to use Java's namespace separator symbol ("." instead of "::"). It then
+ does an additional pass over the demangled output to replace instances
+ of JArray<TYPE> with TYPE[]. */
+
+char *
+java_demangle_v3 (mangled)
+ const char* mangled;
+{
+ dyn_string_t demangled;
+ char *next;
+ char *end;
+ int len;
+ status_t status;
+ int nesting = 0;
+ char *cplus_demangled;
+ char *return_value;
+
+ /* Create a dyn_string to hold the demangled name. */
+ demangled = dyn_string_new (0);
+
+ /* Attempt the demangling. */
+ status = cp_demangle ((char *) mangled, demangled, DMGL_JAVA);
+
+ if (STATUS_NO_ERROR (status))
+ /* Demangling succeeded. */
+ {
+ /* Grab the demangled result from the dyn_string. */
+ cplus_demangled = dyn_string_release (demangled);
+ }
+ else if (status == STATUS_ALLOCATION_FAILED)
+ {
+ fprintf (stderr, "Memory allocation failed.\n");
+ abort ();
+ }
+ else
+ /* Demangling failed. */
+ {
+ dyn_string_delete (demangled);
+ return NULL;
+ }
+
+ len = strlen (cplus_demangled);
+ next = cplus_demangled;
+ end = next + len;
+ demangled = NULL;
+
+ /* Replace occurances of JArray<TYPE> with TYPE[]. */
+ while (next < end)
+ {
+ char *open_str = strstr (next, "JArray<");
+ char *close_str = NULL;
+ if (nesting > 0)
+ close_str = strchr (next, '>');
+
+ if (open_str != NULL && (close_str == NULL || close_str > open_str))
+ {
+ ++nesting;
+
+ if (!demangled)
+ demangled = dyn_string_new(len);
+
+ /* Copy prepending symbols, if any. */
+ if (open_str > next)
+ {
+ open_str[0] = 0;
+ dyn_string_append_cstr (demangled, next);
+ }
+ next = open_str + 7;
+ }
+ else if (close_str != NULL)
+ {
+ --nesting;
+
+ /* Copy prepending type symbol, if any. Squash any spurious
+ whitespace. */
+ if (close_str > next && next[0] != ' ')
+ {
+ close_str[0] = 0;
+ dyn_string_append_cstr (demangled, next);
+ }
+ dyn_string_append_cstr (demangled, "[]");
+ next = close_str + 1;
+ }
+ else
+ {
+ /* There are no more arrays. Copy the rest of the symbol, or
+ simply return the original symbol if no changes were made. */
+ if (next == cplus_demangled)
+ return cplus_demangled;
+
+ dyn_string_append_cstr (demangled, next);
+ next = end;
+ }
+ }
+
+ free (cplus_demangled);
+
+ return_value = dyn_string_release (demangled);
+ return return_value;
+}
+
#endif /* IN_LIBGCC2 */
#ifdef STANDALONE_DEMANGLER
@@ -3771,7 +3924,7 @@
}
/* Attempt to demangle the name. */
- status = cp_demangle (dyn_string_buf (mangled), demangled);
+ status = cp_demangle (dyn_string_buf (mangled), demangled, 0);
/* If the demangling succeeded, great! Print out the
demangled version. */
@@ -3810,7 +3963,7 @@
for (i = optind; i < argc; ++i)
{
/* Attempt to demangle. */
- status = cp_demangle (argv[i], result);
+ status = cp_demangle (argv[i], result, 0);
/* If it worked, print the demangled name. */
if (STATUS_NO_ERROR (status))
@@ -3818,7 +3971,7 @@
/* Abort on allocaiton failures. */
else if (status == STATUS_ALLOCATION_FAILED)
{
- fprintf (stderr, "Memory allocaiton failed.\n");
+ fprintf (stderr, "Memory allocation failed.\n");
abort ();
}
/* If not, print the error message to stderr instead. */
Index: libiberty/testsuite/demangle-expected
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/testsuite/demangle-expected,v
retrieving revision 1.7
diff -u -r1.7 demangle-expected
--- demangle-expected 2000/09/13 23:09:30 1.7
+++ demangle-expected 2001/01/31 00:50:10
@@ -2566,3 +2566,23 @@
--format=gnu
_26_GLOBAL_\$N\$_tmp_n.iilg4Gya\$app_instance
{anonymous}::app_instance
+#
+--format=java
+_ZN4java3awt10ScrollPane7addImplEPNS0_9ComponentEPNS_4lang6ObjectEi
+java.awt.ScrollPane.addImpl(java.awt.Component, java.lang.Object, int)
+#
+--format=java
+_ZN4java3awt4geom15AffineTransform9getMatrixEP6JArrayIdE
+java.awt.geom.AffineTransform.getMatrix(double[])
+#
+--format=java
+_ZN23Mangle$Inner$InnerInner3fooEP6JArrayIPS0_IiEEdPS0_IPS0_IPS0_IPS0_IPN4java4lang6StringEEEEEPS0_IPS0_IPN6MangleEEE
+Mangle$Inner$InnerInner.foo(int[][], double, java.lang.String[][][][], Mangle[][])
+#
+--format=java
+_ZN6JArray1tEP6JArrayIPS_E
+JArray.t(JArray[])
+#
+--format=java
+_ZN4Prim1iEibcdfwPN4java4lang6StringEsx
+Prim.i(int, boolean, byte, double, float, char, java.lang.String, short, long)