diff options
author | obrien <obrien@FreeBSD.org> | 2001-05-28 05:21:37 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2001-05-28 05:21:37 +0000 |
commit | 328e45595b12375b6d16a846069507d25086abdb (patch) | |
tree | ae2a6f4f4987889b7bd2af7bdf0b86fa580df011 /contrib/binutils/libiberty/cplus-dem.c | |
parent | 7fbb72605a1c3bcb81f8b6bb6297ffef30f84335 (diff) | |
download | FreeBSD-src-328e45595b12375b6d16a846069507d25086abdb.zip FreeBSD-src-328e45595b12375b6d16a846069507d25086abdb.tar.gz |
Import of GNU Binutils version 2.11.0.
Believe it or not, this is heavily stripped down.
Diffstat (limited to 'contrib/binutils/libiberty/cplus-dem.c')
-rw-r--r-- | contrib/binutils/libiberty/cplus-dem.c | 280 |
1 files changed, 220 insertions, 60 deletions
diff --git a/contrib/binutils/libiberty/cplus-dem.c b/contrib/binutils/libiberty/cplus-dem.c index 8a672c6..a42f45e 100644 --- a/contrib/binutils/libiberty/cplus-dem.c +++ b/contrib/binutils/libiberty/cplus-dem.c @@ -1,5 +1,6 @@ /* Demangler for GNU C++ - Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. + Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, + 2000 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 @@ -33,7 +34,8 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #endif -#include <ctype.h> +#include "safe-ctype.h" + #include <sys/types.h> #include <string.h> #include <stdio.h> @@ -51,6 +53,8 @@ char * realloc (); #include "libiberty.h" +static char *ada_demangle PARAMS ((const char *, int)); + #define min(X,Y) (((X) < (Y)) ? (X) : (Y)) /* A value at least one greater than the maximum number of characters @@ -98,7 +102,7 @@ mystrstr (s1, s2) #define CPLUS_MARKER '$' #endif -enum demangling_styles current_demangling_style = gnu_demangling; +enum demangling_styles current_demangling_style = auto_demangling; static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; @@ -291,9 +295,21 @@ struct demangler_engine libiberty_demanglers[] = } , { - GNU_NEW_ABI_DEMANGLING_STYLE_STRING, - gnu_new_abi_demangling, - "GNU (g++) new-ABI-style demangling" + GNU_V3_DEMANGLING_STYLE_STRING, + gnu_v3_demangling, + "GNU (g++) V3 ABI-style demangling" + } + , + { + JAVA_DEMANGLING_STYLE_STRING, + java_demangling, + "Java style demangling" + } + , + { + GNAT_DEMANGLING_STYLE_STRING, + gnat_demangling, + "GNAT style demangling" } , { @@ -512,6 +528,9 @@ static void recursively_demangle PARAMS ((struct work_stuff *, const char **, string *, int)); +static void +grow_vect PARAMS ((void **, size_t *, size_t, int)); + /* Translate count to integer, consuming tokens in the process. Conversion terminates on the first non-digit character. @@ -526,10 +545,10 @@ consume_count (type) { int count = 0; - if (! isdigit ((unsigned char)**type)) + if (! ISDIGIT ((unsigned char)**type)) return -1; - while (isdigit ((unsigned char)**type)) + while (ISDIGIT ((unsigned char)**type)) { count *= 10; @@ -540,7 +559,7 @@ consume_count (type) ten. */ if ((count % 10) != 0) { - while (isdigit ((unsigned char) **type)) + while (ISDIGIT ((unsigned char) **type)) (*type)++; return -1; } @@ -566,7 +585,7 @@ consume_count_with_underscores (mangled) if (**mangled == '_') { (*mangled)++; - if (!isdigit ((unsigned char)**mangled)) + if (!ISDIGIT ((unsigned char)**mangled)) return -1; idx = consume_count (mangled); @@ -698,14 +717,14 @@ cplus_demangle_opname (opname, result, options) } } else if (opname[0] == '_' && opname[1] == '_' - && islower((unsigned char)opname[2]) - && islower((unsigned char)opname[3])) + && ISLOWER((unsigned char)opname[2]) + && ISLOWER((unsigned char)opname[3])) { if (opname[4] == '\0') { /* Operator. */ size_t i; - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { if (strlen (optable[i].in) == 2 && memcmp (optable[i].in, opname + 2, 2) == 0) @@ -723,7 +742,7 @@ cplus_demangle_opname (opname, result, options) { /* Assignment. */ size_t i; - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { if (strlen (optable[i].in) == 3 && memcmp (optable[i].in, opname + 2, 3) == 0) @@ -747,7 +766,7 @@ cplus_demangle_opname (opname, result, options) && memcmp (opname + 3, "assign_", 7) == 0) { size_t i; - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { len1 = len - 10; if ((int) strlen (optable[i].in) == len1 @@ -764,7 +783,7 @@ cplus_demangle_opname (opname, result, options) else { size_t i; - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { len1 = len - 3; if ((int) strlen (optable[i].in) == len1 @@ -811,7 +830,7 @@ cplus_mangle_opname (opname, options) int len; len = strlen (opname); - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { if ((int) strlen (optable[i].out) == len && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) @@ -891,13 +910,20 @@ cplus_demangle (mangled, options) char *ret; struct work_stuff work[1]; memset ((char *) work, 0, sizeof (work)); - work -> options = options; - if ((work -> options & DMGL_STYLE_MASK) == 0) - work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK; + work->options = options; + if ((work->options & DMGL_STYLE_MASK) == 0) + work->options |= (int) current_demangling_style & DMGL_STYLE_MASK; + + /* The V3 ABI demangling is implemented elsewhere. */ + if (GNU_V3_DEMANGLING || AUTO_DEMANGLING) + { + ret = cplus_demangle_v3 (mangled); + if (ret || GNU_V3_DEMANGLING) + return ret; + } - /* The new-ABI demangling is implemented elsewhere. */ - if (GNU_NEW_ABI_DEMANGLING) - return cplus_demangle_new_abi (mangled); + if (GNAT_DEMANGLING) + return ada_demangle(mangled,options); ret = internal_cplus_demangle (work, mangled); squangle_mop_up (work); @@ -905,6 +931,139 @@ cplus_demangle (mangled, options) } +/* Assuming *OLD_VECT points to an array of *SIZE objects of size + ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects, + updating *OLD_VECT and *SIZE as necessary. */ + +static void +grow_vect (old_vect, size, min_size, element_size) + void **old_vect; + size_t *size; + size_t min_size; + int element_size; +{ + if (*size < min_size) + { + *size *= 2; + if (*size < min_size) + *size = min_size; + *old_vect = xrealloc (*old_vect, *size * element_size); + } +} + +/* Demangle ada names: + 1. Discard final __{DIGIT}+ or ${DIGIT}+ + 2. Convert other instances of embedded "__" to `.'. + 3. Discard leading _ada_. + 4. Remove everything after first ___ if it is followed by 'X'. + 5. Put symbols that should be suppressed in <...> brackets. + The resulting string is valid until the next call of ada_demangle. */ + +static char * +ada_demangle (mangled, option) + const char *mangled; + int option ATTRIBUTE_UNUSED; +{ + int i, j; + int len0; + const char* p; + char *demangled = NULL; + int at_start_name; + int changed; + char *demangling_buffer = NULL; + size_t demangling_buffer_size = 0; + + changed = 0; + + if (strncmp (mangled, "_ada_", 5) == 0) + { + mangled += 5; + changed = 1; + } + + if (mangled[0] == '_' || mangled[0] == '<') + goto Suppress; + + p = strstr (mangled, "___"); + if (p == NULL) + len0 = strlen (mangled); + else + { + if (p[3] == 'X') + { + len0 = p - mangled; + changed = 1; + } + else + goto Suppress; + } + + /* Make demangled big enough for possible expansion by operator name. */ + grow_vect ((void **) &(demangling_buffer), + &demangling_buffer_size, 2 * len0 + 1, + sizeof (char)); + demangled = demangling_buffer; + + if (ISDIGIT ((unsigned char) mangled[len0 - 1])) { + for (i = len0 - 2; i >= 0 && ISDIGIT ((unsigned char) mangled[i]); i -= 1) + ; + if (i > 1 && mangled[i] == '_' && mangled[i - 1] == '_') + { + len0 = i - 1; + changed = 1; + } + else if (mangled[i] == '$') + { + len0 = i; + changed = 1; + } + } + + for (i = 0, j = 0; i < len0 && ! ISALPHA ((unsigned char)mangled[i]); + i += 1, j += 1) + demangled[j] = mangled[i]; + + at_start_name = 1; + while (i < len0) + { + at_start_name = 0; + + if (i < len0 - 2 && mangled[i] == '_' && mangled[i + 1] == '_') + { + demangled[j] = '.'; + changed = at_start_name = 1; + i += 2; j += 1; + } + else + { + demangled[j] = mangled[i]; + i += 1; j += 1; + } + } + demangled[j] = '\000'; + + for (i = 0; demangled[i] != '\0'; i += 1) + if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ') + goto Suppress; + + if (! changed) + return NULL; + else + return demangled; + + Suppress: + grow_vect ((void **) &(demangling_buffer), + &demangling_buffer_size, strlen (mangled) + 3, + sizeof (char)); + demangled = demangling_buffer; + if (mangled[0] == '<') + strcpy (demangled, mangled); + else + sprintf (demangled, "<%s>", mangled); + + return demangled; +} + /* This function performs most of what cplus_demangle use to do, but to be able to demangle a name with a B, K or n code, we need to have a longer term memory of what types have been seen. The original @@ -920,7 +1079,7 @@ internal_cplus_demangle (work, mangled) string decl; int success = 0; char *demangled = NULL; - int s1,s2,s3,s4; + int s1, s2, s3, s4; s1 = work->constructor; s2 = work->destructor; s3 = work->static_type; @@ -973,7 +1132,7 @@ internal_cplus_demangle (work, mangled) work->destructor = s2; work->static_type = s3; work->type_quals = s4; - return (demangled); + return demangled; } @@ -1134,7 +1293,7 @@ mop_up (work, declp, success) else { string_appendn (declp, "", 1); - demangled = declp -> b; + demangled = declp->b; } return (demangled); } @@ -1374,7 +1533,7 @@ demangle_signature (work, mangled, declp) if (HP_DEMANGLING) { (*mangled)++; - while (**mangled && isdigit ((unsigned char)**mangled)) + while (**mangled && ISDIGIT ((unsigned char)**mangled)) (*mangled)++; } else @@ -1573,9 +1732,7 @@ demangle_expression (work, mangled, s, tk) len = strlen (*mangled); - for (i = 0; - i < sizeof (optable) / sizeof (optable [0]); - ++i) + for (i = 0; i < ARRAY_SIZE (optable); ++i) { size_t l = strlen (optable[i].in); @@ -1709,7 +1866,7 @@ demangle_real_value (work, mangled, s) string_appendn (s, "-", 1); (*mangled)++; } - while (isdigit ((unsigned char)**mangled)) + while (ISDIGIT ((unsigned char)**mangled)) { string_appendn (s, *mangled, 1); (*mangled)++; @@ -1718,7 +1875,7 @@ demangle_real_value (work, mangled, s) { string_appendn (s, ".", 1); (*mangled)++; - while (isdigit ((unsigned char)**mangled)) + while (ISDIGIT ((unsigned char)**mangled)) { string_appendn (s, *mangled, 1); (*mangled)++; @@ -1728,7 +1885,7 @@ demangle_real_value (work, mangled, s) { string_appendn (s, "e", 1); (*mangled)++; - while (isdigit ((unsigned char)**mangled)) + while (ISDIGIT ((unsigned char)**mangled)) { string_appendn (s, *mangled, 1); (*mangled)++; @@ -2579,20 +2736,20 @@ demangle_prefix (work, mangled, declp) } else if (work -> static_type) { - if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't')) + if (!ISDIGIT ((unsigned char)scan[0]) && (scan[0] != 't')) { success = 0; } } else if ((scan == *mangled) - && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q') + && (ISDIGIT ((unsigned char)scan[2]) || (scan[2] == 'Q') || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H'))) { /* The ARM says nothing about the mangling of local variables. But cfront mangles local variables by prepending __<nesting_level> to them. As an extension to ARM demangling we handle this case. */ if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING) - && isdigit ((unsigned char)scan[2])) + && ISDIGIT ((unsigned char)scan[2])) { *mangled = scan + 2; consume_count (mangled); @@ -2629,7 +2786,7 @@ demangle_prefix (work, mangled, declp) /* EDG template? */ demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); } - else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2]) + else if ((scan == *mangled) && !ISDIGIT ((unsigned char)scan[2]) && (scan[2] != 't')) { /* Mangled name starts with "__". Skip over any leading '_' characters, @@ -2751,7 +2908,7 @@ gnu_special (work, mangled, declp) 1); break; default: - if (isdigit((unsigned char)*mangled[0])) + if (ISDIGIT((unsigned char)*mangled[0])) { n = consume_count(mangled); /* We may be seeing a too-large size, or else a @@ -3278,13 +3435,13 @@ get_count (type, count) const char *p; int n; - if (!isdigit ((unsigned char)**type)) + if (!ISDIGIT ((unsigned char)**type)) return (0); else { *count = **type - '0'; (*type)++; - if (isdigit ((unsigned char)**type)) + if (ISDIGIT ((unsigned char)**type)) { p = *type; n = *count; @@ -3294,7 +3451,7 @@ get_count (type, count) n += *p - '0'; p++; } - while (isdigit ((unsigned char)*p)); + while (ISDIGIT ((unsigned char)*p)); if (*p == '_') { *type = p + 1; @@ -3424,7 +3581,7 @@ do_type (work, mangled, result) if (**mangled != 'Q') string_prepend (&decl, SCOPE_STRING (work)); - if (isdigit ((unsigned char)**mangled)) + if (ISDIGIT ((unsigned char)**mangled)) { n = consume_count (mangled); if (n == -1 @@ -3744,7 +3901,7 @@ demangle_fund_type (work, mangled, result) break; case 'G': (*mangled)++; - if (!isdigit ((unsigned char)**mangled)) + if (!ISDIGIT ((unsigned char)**mangled)) { success = 0; break; @@ -3856,12 +4013,12 @@ do_hpacc_template_const_value (work, mangled, result) } /* We have to be looking at an integer now */ - if (!(isdigit ((unsigned char)**mangled))) + if (!(ISDIGIT ((unsigned char)**mangled))) return 0; /* We only deal with integral values for template parameters -- so it's OK to look only for digits */ - while (isdigit ((unsigned char)**mangled)) + while (ISDIGIT ((unsigned char)**mangled)) { char_str[0] = **mangled; string_append (result, char_str); @@ -3940,10 +4097,10 @@ snarf_numeric_literal (args, arg) else if (**args == '+') (*args)++; - if (!isdigit ((unsigned char)**args)) + if (!ISDIGIT ((unsigned char)**args)) return 0; - while (isdigit ((unsigned char)**args)) + while (ISDIGIT ((unsigned char)**args)) { char_str[0] = **args; string_append (arg, char_str); @@ -4449,7 +4606,7 @@ demangle_function_name (work, mangled, declp, scan) if (declp->p - declp->b >= 10 /* op$assign_ */ && memcmp (declp->b + 3, "assign_", 7) == 0) { - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { int len = declp->p - declp->b - 10; if ((int) strlen (optable[i].in) == len @@ -4465,7 +4622,7 @@ demangle_function_name (work, mangled, declp, scan) } else { - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { int len = declp->p - declp->b - 3; if ((int) strlen (optable[i].in) == len @@ -4507,13 +4664,13 @@ demangle_function_name (work, mangled, declp, scan) } } else if (declp->b[0] == '_' && declp->b[1] == '_' - && islower((unsigned char)declp->b[2]) - && islower((unsigned char)declp->b[3])) + && ISLOWER((unsigned char)declp->b[2]) + && ISLOWER((unsigned char)declp->b[3])) { if (declp->b[4] == '\0') { /* Operator. */ - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { if (strlen (optable[i].in) == 2 && memcmp (optable[i].in, declp->b + 2, 2) == 0) @@ -4530,7 +4687,7 @@ demangle_function_name (work, mangled, declp, scan) if (declp->b[2] == 'a' && declp->b[5] == '\0') { /* Assignment. */ - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) + for (i = 0; i < ARRAY_SIZE (optable); i++) { if (strlen (optable[i].in) == 3 && memcmp (optable[i].in, declp->b + 2, 3) == 0) @@ -4816,7 +4973,7 @@ static const char * hp_symbol_characters PARAMS ((void)); static const char * -gnu_new_abi_symbol_characters PARAMS ((void)); +gnu_v3_symbol_characters PARAMS ((void)); /* Return the string of non-alnum characters that may occur as a valid symbol component, in the standard assembler symbol @@ -4867,13 +5024,13 @@ hp_symbol_characters () /* Return the string of non-alnum characters that may occur - as a valid symbol component in the GNU standard C++ ABI mangling + as a valid symbol component in the GNU C++ V3 ABI mangling scheme. */ static const char * -gnu_new_abi_symbol_characters () +gnu_v3_symbol_characters () { - return "_"; + return "_$."; } @@ -4945,14 +5102,17 @@ main (argc, argv) case gnu_demangling: case lucid_demangling: case arm_demangling: + case java_demangling: case edg_demangling: + case gnat_demangling: + case auto_demangling: valid_symbols = standard_symbol_characters (); break; case hp_demangling: valid_symbols = hp_symbol_characters (); break; - case gnu_new_abi_demangling: - valid_symbols = gnu_new_abi_symbol_characters (); + case gnu_v3_demangling: + valid_symbols = gnu_v3_symbol_characters (); break; default: /* Folks should explicitly indicate the appropriate alphabet for @@ -4966,7 +5126,7 @@ main (argc, argv) int i = 0; c = getchar (); /* Try to read a label. */ - while (c != EOF && (isalnum (c) || strchr (valid_symbols, c))) + while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c))) { if (i >= MBUF_SIZE-1) break; |