diff options
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/ChangeLog | 26 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 183 | ||||
-rw-r--r-- | libiberty/cplus-dem.c | 20 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 20 |
4 files changed, 225 insertions, 24 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 2cdcddc6d41..6c8c8f11499 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,29 @@ +2001-01-31 Bryce McKinlay <bryce@albatross.co.nz> + + Add support for Java demangling under the v3 ABI: + * 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 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. + * testsuite/demangle.expected: Add some Java test cases. + +2001-01-29 Phil Edwards <pme@sources.redhat.com> + + * COPYING.LIB: Update to LGPL 2.1 from the FSF. + 2000-12-29 DJ Delorie <dj@redhat.com> * fnmatch.c: Make the note about the origins of this file more diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 1cc4847d4e7..db34b58b1c5 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -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 @@ struct demangling_def /* 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 void template_arg_list_print 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 @@ current_template_arg_list (dm) 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 @@ demangling_new (name) dyn_string_delete (dm->last_source_name); return NULL; } + dm->style = style; return dm; } @@ -918,7 +926,7 @@ static status_t demangle_local_name 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 @@ demangle_prefix (dm, encode_return_type) { /* 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 @@ demangle_type_ptr (dm, insert_pos, substitution_start) 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 @@ static const char *const builtin_type_names[26] = "..." /* 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 @@ demangle_builtin_type (dm) } 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 @@ demangle_discriminator (dm, suppress_first) 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 @@ __cxa_demangle (mangled_name, output_buffer, length, status) 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 @@ cplus_demangle_v3 (mangled) /* 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 @@ cplus_demangle_v3 (mangled) } } +/* 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 @@ main (argc, argv) } /* 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 @@ main (argc, argv) 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 @@ main (argc, argv) /* 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. */ diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index a42f45e6426..d49ec7c7e1d 100644 --- a/libiberty/cplus-dem.c +++ b/libiberty/cplus-dem.c @@ -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 @@ cplus_demangle (mangled, options) 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 @@ static struct option long_options[] = { {"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 @@ main (argc, argv) 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 @@ main (argc, argv) 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 @@ main (argc, argv) skip_first = i; mbuffer[i] = 0; - + flags |= style; result = cplus_demangle (mbuffer + skip_first, flags); if (result) { diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index a5d72fab0fe..4953c7d1103 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -2566,3 +2566,23 @@ _27_GLOBAL_.N.__12burst_app_ct.app_instance --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) |