diff options
author | 2003-11-25 21:06:18 +0000 | |
---|---|---|
committer | 2003-11-25 21:06:18 +0000 | |
commit | 37c533223a617425b64bf716c3068c3739b7224b (patch) | |
tree | a212572d65681c0339e1897015d21c35c6fb0af3 /gnu/lib/libiberty/src/cplus-dem.c | |
parent | Synch with gcc-3.3.2 version (diff) | |
download | wireguard-openbsd-37c533223a617425b64bf716c3068c3739b7224b.tar.xz wireguard-openbsd-37c533223a617425b64bf716c3068c3739b7224b.zip |
fix stupid cvs conflicts.
I think that cvs is a poor lonesome, depressive program.
The only way it has found of getting your attention is to throw
senseless conflicts that shouldn't exist in your way.
Diffstat (limited to 'gnu/lib/libiberty/src/cplus-dem.c')
-rw-r--r-- | gnu/lib/libiberty/src/cplus-dem.c | 1213 |
1 files changed, 704 insertions, 509 deletions
diff --git a/gnu/lib/libiberty/src/cplus-dem.c b/gnu/lib/libiberty/src/cplus-dem.c index ff6625244df..199f767736d 100644 --- a/gnu/lib/libiberty/src/cplus-dem.c +++ b/gnu/lib/libiberty/src/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, 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 @@ -10,6 +11,15 @@ modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. +In addition to the permissions in the GNU Library General Public +License, the Free Software Foundation gives you unlimited permission +to link the compiled version of this file into combinations with other +programs, and to distribute those combinations without any restriction +coming from the use of this file. (The Library Public License +restrictions do apply in other respects; for example, they cover +modification of the file, and distribution when not linked into a +combined executable.) + Libiberty is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU @@ -33,7 +43,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,26 +62,15 @@ char * realloc (); #include "libiberty.h" +static char *ada_demangle PARAMS ((const char *, int)); + #define min(X,Y) (((X) < (Y)) ? (X) : (Y)) -static const char *mystrstr PARAMS ((const char *, const char *)); +/* A value at least one greater than the maximum number of characters + that will be output when using the `%d' format with `printf'. */ +#define INTBUF_SIZE 32 -static const char * -mystrstr (s1, s2) - const char *s1, *s2; -{ - register const char *p = s1; - register int len = strlen (s2); - - for (; (p = strchr (p, *s2)) != 0; p++) - { - if (strncmp (p, s2, len) == 0) - { - return (p); - } - } - return (0); -} +extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN; /* In order to allow a single demangler executable to demangle strings using various common values of CPLUS_MARKER, as well as any specific @@ -92,7 +92,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' }; @@ -147,9 +147,9 @@ struct work_stuff static const struct optable { - const char *in; - const char *out; - int flags; + const char *const in; + const char *const out; + const int flags; } optable[] = { {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */ {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */ @@ -246,9 +246,15 @@ typedef enum type_kind_t tk_real } type_kind_t; -struct demangler_engine libiberty_demanglers[] = +const struct demangler_engine libiberty_demanglers[] = { { + NO_DEMANGLING_STYLE_STRING, + no_demangling, + "Demangling disabled" + } + , + { AUTO_DEMANGLING_STYLE_STRING, auto_demangling, "Automatic selection based on executable" @@ -285,13 +291,29 @@ struct demangler_engine libiberty_demanglers[] = } , { + 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" + } + , + { NULL, unknown_demangling, NULL } }; #define STRING_EMPTY(str) ((str) -> b == (str) -> p) -#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ - string_prepend(str, " ");} #define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ string_append(str, " ");} #define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b)) @@ -305,12 +327,21 @@ struct demangler_engine libiberty_demanglers[] = /* Prototypes for local functions */ +static void +delete_work_stuff PARAMS ((struct work_stuff *)); + +static void +delete_non_B_K_work_stuff PARAMS ((struct work_stuff *)); + static char * mop_up PARAMS ((struct work_stuff *, string *, int)); static void squangle_mop_up PARAMS ((struct work_stuff *)); +static void +work_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *)); + #if 0 static int demangle_method_args PARAMS ((struct work_stuff *, const char **, string *)); @@ -388,6 +419,9 @@ string_prepend PARAMS ((string *, const char *)); static void string_prependn PARAMS ((string *, const char *, int)); +static void +string_append_template_idx PARAMS ((string *, int)); + static int get_count PARAMS ((const char **, int *)); @@ -413,6 +447,10 @@ static void demangle_function_name PARAMS ((struct work_stuff *, const char **, string *, const char *)); +static int +iterate_demangle_function PARAMS ((struct work_stuff *, + const char **, string *, const char *)); + static void remember_type PARAMS ((struct work_stuff *, const char *, int)); @@ -465,6 +503,28 @@ qualifier_string PARAMS ((int)); static const char* demangle_qualifier PARAMS ((int)); +static int +demangle_expression PARAMS ((struct work_stuff *, const char **, string *, + type_kind_t)); + +static int +demangle_integral_value PARAMS ((struct work_stuff *, const char **, + string *)); + +static int +demangle_real_value PARAMS ((struct work_stuff *, const char **, string *)); + +static void +demangle_arm_hp_template PARAMS ((struct work_stuff *, const char **, int, + string *)); + +static void +recursively_demangle PARAMS ((struct work_stuff *, const char **, string *, + int)); + +static void +grow_vect PARAMS ((char **, size_t *, size_t, int)); + /* Translate count to integer, consuming tokens in the process. Conversion terminates on the first non-digit character. @@ -479,10 +539,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; @@ -493,7 +553,7 @@ consume_count (type) ten. */ if ((count % 10) != 0) { - while (isdigit ((unsigned char) **type)) + while (ISDIGIT ((unsigned char) **type)) (*type)++; return -1; } @@ -502,6 +562,9 @@ consume_count (type) (*type)++; } + if (count < 0) + count = -1; + return (count); } @@ -519,7 +582,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); @@ -651,14 +714,14 @@ cplus_demangle_opname (opname, result, options) } } else if (opname[0] == '_' && opname[1] == '_' - && opname[2] >= 'a' && opname[2] <= 'z' - && opname[3] >= 'a' && opname[3] <= 'z') + && 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) @@ -676,7 +739,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) @@ -700,7 +763,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 @@ -717,7 +780,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 @@ -748,6 +811,7 @@ cplus_demangle_opname (opname, result, options) return ret; } + /* Takes operator name as e.g. "++" and returns mangled operator name (e.g. "postincrement_expr"), or NULL if not found. @@ -763,7 +827,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) @@ -780,7 +844,7 @@ enum demangling_styles cplus_demangle_set_style (style) enum demangling_styles style; { - struct demangler_engine *demangler = libiberty_demanglers; + const struct demangler_engine *demangler = libiberty_demanglers; for (; demangler->demangling_style != unknown_demangling; ++demangler) if (style == demangler->demangling_style) @@ -798,7 +862,7 @@ enum demangling_styles cplus_demangle_name_to_style (name) const char *name; { - struct demangler_engine *demangler = libiberty_demanglers; + const struct demangler_engine *demangler = libiberty_demanglers; for (; demangler->demangling_style != unknown_demangling; ++demangler) if (strcmp (name, demangler->demangling_style_name) == 0) @@ -810,7 +874,7 @@ cplus_demangle_name_to_style (name) /* char *cplus_demangle (const char *mangled, int options) If MANGLED is a mangled function name produced by GNU C++, then - a pointer to a malloced string giving a C++ representation + a pointer to a @code{malloc}ed string giving a C++ representation of the name will be returned; otherwise NULL will be returned. It is the caller's responsibility to free the string which is returned. @@ -842,10 +906,32 @@ cplus_demangle (mangled, options) { char *ret; struct work_stuff work[1]; + + if (current_demangling_style == no_demangling) + return xstrdup (mangled); + 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, work->options); + if (ret || GNU_V3_DEMANGLING) + return ret; + } + + if (JAVA_DEMANGLING) + { + ret = java_demangle_v3 (mangled); + if (ret) + return ret; + } + + if (GNAT_DEMANGLING) + return ada_demangle(mangled,options); ret = internal_cplus_demangle (work, mangled); squangle_mop_up (work); @@ -853,6 +939,137 @@ 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) + char **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 = (void *) 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; + size_t demangled_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 (&demangled, + &demangled_size, 2 * len0 + 1, + sizeof (char)); + + 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 (&demangled, + &demangled_size, strlen (mangled) + 3, + sizeof (char)); + + 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 @@ -868,7 +1085,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; @@ -921,7 +1138,7 @@ internal_cplus_demangle (work, mangled) work->destructor = s2; work->static_type = s3; work->type_quals = s4; - return (demangled); + return demangled; } @@ -942,16 +1159,85 @@ squangle_mop_up (work) } } -/* Clear out any mangled storage */ -static char * -mop_up (work, declp, success) - struct work_stuff *work; - string *declp; - int success; +/* Copy the work state and storage. */ + +static void +work_stuff_copy_to_from (to, from) + struct work_stuff *to; + struct work_stuff *from; { - char *demangled = NULL; + int i; + + delete_work_stuff (to); + + /* Shallow-copy scalars. */ + memcpy (to, from, sizeof (*to)); + + /* Deep-copy dynamic storage. */ + if (from->typevec_size) + to->typevec + = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0])); + + for (i = 0; i < from->ntypes; i++) + { + int len = strlen (from->typevec[i]) + 1; + + to->typevec[i] = xmalloc (len); + memcpy (to->typevec[i], from->typevec[i], len); + } + + if (from->ksize) + to->ktypevec + = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0])); + + for (i = 0; i < from->numk; i++) + { + int len = strlen (from->ktypevec[i]) + 1; + + to->ktypevec[i] = xmalloc (len); + memcpy (to->ktypevec[i], from->ktypevec[i], len); + } + if (from->bsize) + to->btypevec + = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0])); + + for (i = 0; i < from->numb; i++) + { + int len = strlen (from->btypevec[i]) + 1; + + to->btypevec[i] = xmalloc (len); + memcpy (to->btypevec[i], from->btypevec[i], len); + } + + if (from->ntmpl_args) + to->tmpl_argvec + = (char **) xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0])); + + for (i = 0; i < from->ntmpl_args; i++) + { + int len = strlen (from->tmpl_argvec[i]) + 1; + + to->tmpl_argvec[i] = xmalloc (len); + memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len); + } + + if (from->previous_argument) + { + to->previous_argument = (string*) xmalloc (sizeof (string)); + string_init (to->previous_argument); + string_appends (to->previous_argument, from->previous_argument); + } +} + + +/* Delete dynamic stuff in work_stuff that is not to be re-used. */ + +static void +delete_non_B_K_work_stuff (work) + struct work_stuff *work; +{ /* Discard the remembered types, if any. */ forget_types (work); @@ -978,6 +1264,30 @@ mop_up (work, declp, success) free ((char*) work->previous_argument); work->previous_argument = NULL; } +} + + +/* Delete all dynamic storage in work_stuff. */ +static void +delete_work_stuff (work) + struct work_stuff *work; +{ + delete_non_B_K_work_stuff (work); + squangle_mop_up (work); +} + + +/* Clear out any mangled storage */ + +static char * +mop_up (work, declp, success) + struct work_stuff *work; + string *declp; + int success; +{ + char *demangled = NULL; + + delete_non_B_K_work_stuff (work); /* If demangling was successful, ensure that the demangled string is null terminated and return it. Otherwise, free the demangling decl. */ @@ -989,7 +1299,7 @@ mop_up (work, declp, success) else { string_appendn (declp, "", 1); - demangled = declp -> b; + demangled = declp->b; } return (demangled); } @@ -1203,7 +1513,7 @@ demangle_signature (work, mangled, declp) break; case '_': - if (GNU_DEMANGLING && expect_return_type) + if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type) { /* Read the return type. */ string return_type; @@ -1229,7 +1539,7 @@ demangle_signature (work, mangled, declp) if (HP_DEMANGLING) { (*mangled)++; - while (**mangled && isdigit ((unsigned char)**mangled)) + while (**mangled && ISDIGIT ((unsigned char)**mangled)) (*mangled)++; } else @@ -1237,7 +1547,7 @@ demangle_signature (work, mangled, declp) break; case 'H': - if (GNU_DEMANGLING) + if (AUTO_DEMANGLING || GNU_DEMANGLING) { /* A G++ template function. Read the template arguments. */ success = demangle_template (work, mangled, declp, 0, 0, @@ -1405,82 +1715,151 @@ demangle_template_template_parm (work, mangled, tname) } static int -demangle_integral_value (work, mangled, s) +demangle_expression (work, mangled, s, tk) struct work_stuff *work; const char** mangled; string* s; + type_kind_t tk; { + int need_operator = 0; int success; - if (**mangled == 'E') + success = 1; + string_appendn (s, "(", 1); + (*mangled)++; + while (success && **mangled != 'W' && **mangled != '\0') { - int need_operator = 0; - - success = 1; - string_appendn (s, "(", 1); - (*mangled)++; - while (success && **mangled != 'W' && **mangled != '\0') + if (need_operator) { - if (need_operator) - { - size_t i; - size_t len; + size_t i; + size_t len; - success = 0; + success = 0; - len = strlen (*mangled); + len = strlen (*mangled); - for (i = 0; - i < sizeof (optable) / sizeof (optable [0]); - ++i) - { - size_t l = strlen (optable[i].in); + for (i = 0; i < ARRAY_SIZE (optable); ++i) + { + size_t l = strlen (optable[i].in); - if (l <= len - && memcmp (optable[i].in, *mangled, l) == 0) - { - string_appendn (s, " ", 1); - string_append (s, optable[i].out); - string_appendn (s, " ", 1); - success = 1; - (*mangled) += l; - break; - } + if (l <= len + && memcmp (optable[i].in, *mangled, l) == 0) + { + string_appendn (s, " ", 1); + string_append (s, optable[i].out); + string_appendn (s, " ", 1); + success = 1; + (*mangled) += l; + break; } - - if (!success) - break; } - else - need_operator = 1; - success = demangle_template_value_parm (work, mangled, s, - tk_integral); + if (!success) + break; } - - if (**mangled != 'W') - success = 0; else - { - string_appendn (s, ")", 1); - (*mangled)++; - } + need_operator = 1; + + success = demangle_template_value_parm (work, mangled, s, tk); + } + + if (**mangled != 'W') + success = 0; + else + { + string_appendn (s, ")", 1); + (*mangled)++; } + + return success; +} + +static int +demangle_integral_value (work, mangled, s) + struct work_stuff *work; + const char** mangled; + string* s; +{ + int success; + + if (**mangled == 'E') + success = demangle_expression (work, mangled, s, tk_integral); else if (**mangled == 'Q' || **mangled == 'K') success = demangle_qualified (work, mangled, s, 0, 1); else { + int value; + + /* By default, we let the number decide whether we shall consume an + underscore. */ + int multidigit_without_leading_underscore = 0; + int leave_following_underscore = 0; + success = 0; + /* Negative numbers are indicated with a leading `m'. */ if (**mangled == 'm') { string_appendn (s, "-", 1); (*mangled)++; } - while (isdigit ((unsigned char)**mangled)) + else if (mangled[0][0] == '_' && mangled[0][1] == 'm') { - string_appendn (s, *mangled, 1); - (*mangled)++; + /* Since consume_count_with_underscores does not handle the + `m'-prefix we must do it here, using consume_count and + adjusting underscores: we have to consume the underscore + matching the prepended one. */ + multidigit_without_leading_underscore = 1; + string_appendn (s, "-", 1); + (*mangled) += 2; + } + else if (**mangled == '_') + { + /* Do not consume a following underscore; + multidigit_without_leading_underscore will consume what should be + consumed. */ + leave_following_underscore = 1; + } + else + { + /* Since consume_count_with_underscores does not handle + multi-digit numbers that do not start with an underscore, + and this number can be an integer template parameter, + we have to call consume_count. */ + multidigit_without_leading_underscore = 1; + /* These multi-digit numbers never end on an underscore, + so if there is one then don't eat it. */ + leave_following_underscore = 1; + } + + /* We must call consume_count if we expect to remove a trailing + underscore, since consume_count_with_underscores expects + the leading underscore (that we consumed) if it is to handle + multi-digit numbers. */ + if (multidigit_without_leading_underscore) + value = consume_count (mangled); + else + value = consume_count_with_underscores (mangled); + + if (value != -1) + { + char buf[INTBUF_SIZE]; + sprintf (buf, "%d", value); + string_append (s, buf); + + /* Numbers not otherwise delimited, might have an underscore + appended as a delimeter, which we should skip. + + ??? This used to always remove a following underscore, which + is wrong. If other (arbitrary) cases are followed by an + underscore, we need to do something more radical. */ + + if ((value > 9 || multidigit_without_leading_underscore) + && ! leave_following_underscore + && **mangled == '_') + (*mangled)++; + + /* All is well. */ success = 1; } } @@ -1488,6 +1867,51 @@ demangle_integral_value (work, mangled, s) return success; } +/* Demangle the real value in MANGLED. */ + +static int +demangle_real_value (work, mangled, s) + struct work_stuff *work; + const char **mangled; + string* s; +{ + if (**mangled == 'E') + return demangle_expression (work, mangled, s, tk_real); + + if (**mangled == 'm') + { + string_appendn (s, "-", 1); + (*mangled)++; + } + while (ISDIGIT ((unsigned char)**mangled)) + { + string_appendn (s, *mangled, 1); + (*mangled)++; + } + if (**mangled == '.') /* fraction */ + { + string_appendn (s, ".", 1); + (*mangled)++; + while (ISDIGIT ((unsigned char)**mangled)) + { + string_appendn (s, *mangled, 1); + (*mangled)++; + } + } + if (**mangled == 'e') /* exponent */ + { + string_appendn (s, "e", 1); + (*mangled)++; + while (ISDIGIT ((unsigned char)**mangled)) + { + string_appendn (s, *mangled, 1); + (*mangled)++; + } + } + + return 1; +} + static int demangle_template_value_parm (work, mangled, s, tk) struct work_stuff *work; @@ -1511,11 +1935,7 @@ demangle_template_value_parm (work, mangled, s, tk) if (work->tmpl_argvec) string_append (s, work->tmpl_argvec[idx]); else - { - char buf[10]; - sprintf(buf, "T%d", idx); - string_append (s, buf); - } + string_append_template_idx (s, idx); } else if (tk == tk_integral) success = demangle_integral_value (work, mangled, s); @@ -1551,38 +1971,7 @@ demangle_template_value_parm (work, mangled, s, tk) success = 0; } else if (tk == tk_real) - { - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - while (isdigit ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - if (**mangled == '.') /* fraction */ - { - string_appendn (s, ".", 1); - (*mangled)++; - while (isdigit ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - } - if (**mangled == 'e') /* exponent */ - { - string_appendn (s, "e", 1); - (*mangled)++; - while (isdigit ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - } - } + success = demangle_real_value (work, mangled, s); else if (tk == tk_pointer || tk == tk_reference) { if (**mangled == 'Q') @@ -1632,7 +2021,7 @@ demangle_template_value_parm (work, mangled, s, tk) template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is non-NULL. If IS_TYPE is nonzero, this template is a type template, not a function template. If both IS_TYPE and REMEMBER are nonzero, - the tmeplate is remembered in the list of back-referenceable + the template is remembered in the list of back-referenceable types. */ static int @@ -1680,11 +2069,9 @@ demangle_template (work, mangled, tname, trawname, is_type, remember) } else { - char buf[10]; - sprintf(buf, "T%d", idx); - string_append (tname, buf); + string_append_template_idx (tname, idx); if (trawname) - string_append (trawname, buf); + string_append_template_idx (trawname, idx); } } else @@ -1863,7 +2250,7 @@ arm_pt (work, mangled, n, anchor, args) { /* Check if ARM template with "__pt__" in it ("parameterized type") */ /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */ - if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__"))) + if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = strstr (mangled, "__pt__"))) { int len; *args = *anchor + 6; @@ -1878,9 +2265,9 @@ arm_pt (work, mangled, n, anchor, args) } if (AUTO_DEMANGLING || EDG_DEMANGLING) { - if ((*anchor = mystrstr (mangled, "__tm__")) - || (*anchor = mystrstr (mangled, "__ps__")) - || (*anchor = mystrstr (mangled, "__pt__"))) + if ((*anchor = strstr (mangled, "__tm__")) + || (*anchor = strstr (mangled, "__ps__")) + || (*anchor = strstr (mangled, "__pt__"))) { int len; *args = *anchor + 6; @@ -1893,7 +2280,7 @@ arm_pt (work, mangled, n, anchor, args) return 1; } } - else if ((*anchor = mystrstr (mangled, "__S"))) + else if ((*anchor = strstr (mangled, "__S"))) { int len; *args = *anchor + 3; @@ -2032,8 +2419,15 @@ demangle_arm_hp_template (work, mangled, n, declp) break; default: /* Not handling other HP cfront stuff */ - if (!do_type (work, &args, &arg)) - goto cfront_template_args_done; + { + const char* old_args = args; + if (!do_type (work, &args, &arg)) + goto cfront_template_args_done; + + /* Fail if we didn't make any progress: prevent infinite loop. */ + if (args == old_args) + return; + } } string_appends (declp, &arg); string_append (declp, ","); @@ -2166,6 +2560,86 @@ demangle_class (work, mangled, declp) return (success); } + +/* Called when there's a "__" in the mangled name, with `scan' pointing to + the rightmost guess. + + Find the correct "__"-sequence where the function name ends and the + signature starts, which is ambiguous with GNU mangling. + Call demangle_signature here, so we can make sure we found the right + one; *mangled will be consumed so caller will not make further calls to + demangle_signature. */ + +static int +iterate_demangle_function (work, mangled, declp, scan) + struct work_stuff *work; + const char **mangled; + string *declp; + const char *scan; +{ + const char *mangle_init = *mangled; + int success = 0; + string decl_init; + struct work_stuff work_init; + + if (*(scan + 2) == '\0') + return 0; + + /* Do not iterate for some demangling modes, or if there's only one + "__"-sequence. This is the normal case. */ + if (ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING + || strstr (scan + 2, "__") == NULL) + { + demangle_function_name (work, mangled, declp, scan); + return 1; + } + + /* Save state so we can restart if the guess at the correct "__" was + wrong. */ + string_init (&decl_init); + string_appends (&decl_init, declp); + memset (&work_init, 0, sizeof work_init); + work_stuff_copy_to_from (&work_init, work); + + /* Iterate over occurrences of __, allowing names and types to have a + "__" sequence in them. We must start with the first (not the last) + occurrence, since "__" most often occur between independent mangled + parts, hence starting at the last occurence inside a signature + might get us a "successful" demangling of the signature. */ + + while (scan[2]) + { + demangle_function_name (work, mangled, declp, scan); + success = demangle_signature (work, mangled, declp); + if (success) + break; + + /* Reset demangle state for the next round. */ + *mangled = mangle_init; + string_clear (declp); + string_appends (declp, &decl_init); + work_stuff_copy_to_from (work, &work_init); + + /* Leave this underscore-sequence. */ + scan += 2; + + /* Scan for the next "__" sequence. */ + while (*scan && (scan[0] != '_' || scan[1] != '_')) + scan++; + + /* Move to last "__" in this sequence. */ + while (*scan && *scan == '_') + scan++; + scan -= 2; + } + + /* Delete saved state. */ + delete_work_stuff (&work_init); + string_delete (&decl_init); + + return success; +} + /* LOCAL FUNCTION @@ -2181,6 +2655,8 @@ SYNOPSIS DESCRIPTION Consume and demangle the prefix of the mangled name. + While processing the function name root, arrange to call + demangle_signature if the root is ambiguous. DECLP points to the string buffer into which demangled output is placed. On entry, the buffer is empty. On exit it contains @@ -2255,7 +2731,7 @@ demangle_prefix (work, mangled, declp) /* This block of code is a reduction in strength time optimization of: - scan = mystrstr (*mangled, "__"); */ + scan = strstr (*mangled, "__"); */ { scan = *mangled; @@ -2284,20 +2760,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); @@ -2334,7 +2810,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, @@ -2347,36 +2823,23 @@ demangle_prefix (work, mangled, declp) { scan++; } - if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) + if ((scan = strstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) { /* No separator (I.E. "__not_mangled"), or empty signature (I.E. "__not_mangled_either__") */ success = 0; } else - { - const char *tmp; - - /* Look for the LAST occurrence of __, allowing names to - have the '__' sequence embedded in them. */ - if (!(ARM_DEMANGLING || HP_DEMANGLING)) - { - while ((tmp = mystrstr (scan + 2, "__")) != NULL) - scan = tmp; - } - if (*(scan + 2) == '\0') - success = 0; - else - demangle_function_name (work, mangled, declp, scan); - } + return iterate_demangle_function (work, mangled, declp, scan); } } else if (*(scan + 2) != '\0') { /* Mangled name does not start with "__" but does have one somewhere in there with non empty stuff after it. Looks like a global - function name. */ - demangle_function_name (work, mangled, declp, scan); + function name. Iterate over all "__":s until the right + one is found. */ + return iterate_demangle_function (work, mangled, declp, scan); } else { @@ -2469,7 +2932,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 @@ -2525,11 +2988,30 @@ gnu_special (work, mangled, declp) break; default: n = consume_count (mangled); - if (n < 0 || n > strlen (*mangled)) + if (n < 0 || n > (long) strlen (*mangled)) { success = 0; break; } + + if (n > 10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 + && (*mangled)[9] == 'N' + && (*mangled)[8] == (*mangled)[10] + && strchr (cplus_markers, (*mangled)[8])) + { + /* A member of the anonymous namespace. There's information + about what identifier or filename it was keyed to, but + it's just there to make the mangled name unique; we just + step over it. */ + string_append (declp, "{anonymous}"); + (*mangled) += n; + + /* Now p points to the marker before the N, so we need to + update it to the first marker after what we consumed. */ + p = strpbrk (*mangled, cplus_markers); + break; + } + string_appendn (declp, *mangled, n); (*mangled) += n; } @@ -2591,7 +3073,7 @@ gnu_special (work, mangled, declp) success = demangle_template (work, mangled, declp, 0, 1, 1); break; default: - success = demangle_fund_type (work, mangled, declp); + success = do_type (work, mangled, declp); break; } if (success && **mangled != '\0') @@ -2692,7 +3174,7 @@ arm_special (mangled, declp) { n = consume_count (mangled); if (n == -1 - || n > strlen (*mangled)) + || n > (long) strlen (*mangled)) return 0; string_prependn (declp, *mangled, n); (*mangled) += n; @@ -2753,7 +3235,6 @@ demangle_qualified (work, mangled, result, isfuncname, append) { int qualifiers = 0; int success = 1; - const char *p; char num[2]; string temp; string last_name; @@ -2785,19 +3266,10 @@ demangle_qualified (work, mangled, result, isfuncname, append) /* GNU mangled name with more than 9 classes. The count is preceded by an underscore (to distinguish it from the <= 9 case) and followed by an underscore. */ - p = *mangled + 2; - qualifiers = atoi (p); - if (!isdigit ((unsigned char)*p) || *p == '0') - success = 0; - - /* Skip the digits. */ - while (isdigit ((unsigned char)*p)) - ++p; - - if (*p != '_') + (*mangled)++; + qualifiers = consume_count_with_underscores (mangled); + if (qualifiers == -1) success = 0; - - *mangled = p + 1; break; case '1': @@ -2987,15 +3459,13 @@ get_count (type, count) const char *p; int n; - if (!isdigit ((unsigned char)**type)) - { - return (0); - } + 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; @@ -3005,7 +3475,7 @@ get_count (type, count) n += *p - '0'; p++; } - while (isdigit ((unsigned char)*p)); + while (ISDIGIT ((unsigned char)*p)); if (*p == '_') { *type = p + 1; @@ -3129,8 +3599,13 @@ do_type (work, mangled, result) (*mangled)++; string_append (&decl, ")"); - string_prepend (&decl, SCOPE_STRING (work)); - if (isdigit ((unsigned char)**mangled)) + + /* We don't need to prepend `::' for a qualified name; + demangle_qualified will do that for us. */ + if (**mangled != 'Q') + string_prepend (&decl, SCOPE_STRING (work)); + + if (ISDIGIT ((unsigned char)**mangled)) { n = consume_count (mangled); if (n == -1 @@ -3162,6 +3637,14 @@ do_type (work, mangled, result) else break; } + else if (**mangled == 'Q') + { + success = demangle_qualified (work, mangled, &decl, + /*isfuncnam=*/0, + /*append=*/0); + if (!success) + break; + } else { success = 0; @@ -3274,11 +3757,7 @@ do_type (work, mangled, result) if (work->tmpl_argvec) string_append (result, work->tmpl_argvec[idx]); else - { - char buf[10]; - sprintf(buf, "T%d", idx); - string_append (result, buf); - } + string_append_template_idx (result, idx); success = 1; } @@ -3332,7 +3811,7 @@ demangle_fund_type (work, mangled, result) int done = 0; int success = 1; char buf[10]; - int dec = 0; + unsigned int dec = 0; string btype; type_kind_t tk = tk_integral; @@ -3446,7 +3925,7 @@ demangle_fund_type (work, mangled, result) break; case 'G': (*mangled)++; - if (!isdigit ((unsigned char)**mangled)) + if (!ISDIGIT ((unsigned char)**mangled)) { success = 0; break; @@ -3458,7 +3937,7 @@ demangle_fund_type (work, mangled, result) int i; (*mangled)++; for (i = 0; - i < sizeof (buf) - 1 && **mangled && **mangled != '_'; + i < (long) sizeof (buf) - 1 && **mangled && **mangled != '_'; (*mangled)++, i++) buf[i] = **mangled; if (**mangled != '_') @@ -3476,7 +3955,7 @@ demangle_fund_type (work, mangled, result) *mangled += min (strlen (*mangled), 2); } sscanf (buf, "%x", &dec); - sprintf (buf, "int%i_t", dec); + sprintf (buf, "int%u_t", dec); APPEND_BLANK (result); string_append (result, buf); break; @@ -3527,7 +4006,7 @@ demangle_fund_type (work, mangled, result) static int do_hpacc_template_const_value (work, mangled, result) - struct work_stuff *work; + struct work_stuff *work ATTRIBUTE_UNUSED; const char **mangled; string *result; { @@ -3558,12 +4037,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); @@ -3642,10 +4121,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); @@ -4151,7 +4630,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 @@ -4167,7 +4646,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 @@ -4209,13 +4688,13 @@ demangle_function_name (work, mangled, declp, scan) } } else if (declp->b[0] == '_' && declp->b[1] == '_' - && declp->b[2] >= 'a' && declp->b[2] <= 'z' - && declp->b[3] >= 'a' && declp->b[3] <= 'z') + && 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) @@ -4232,7 +4711,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) @@ -4397,296 +4876,12 @@ string_prependn (p, s, n) } } -/* To generate a standalone demangler program for testing purposes, - just compile and link this file with -DMAIN and libiberty.a. When - run, it demangles each command line arg, or each stdin string, and - prints the result on stdout. */ - -#ifdef MAIN - -#include "getopt.h" - -static char *program_name; -static char *program_version = VERSION; -static int flags = DMGL_PARAMS | DMGL_ANSI; - -static void demangle_it PARAMS ((char *)); -static void usage PARAMS ((FILE *, int)); -static void fatal PARAMS ((char *)); - -static void -demangle_it (mangled_name) - char *mangled_name; -{ - char *result; - - result = cplus_demangle (mangled_name, flags); - if (result == NULL) - { - printf ("%s\n", mangled_name); - } - else - { - printf ("%s\n", result); - free (result); - } -} - static void -usage (stream, status) - FILE *stream; - int status; -{ - fprintf (stream, "\ -Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\ - [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\ - [--help] [--version] [arg...]\n", - program_name); - exit (status); -} - -#define MBUF_SIZE 32767 -char mbuffer[MBUF_SIZE]; - -/* Defined in the automatically-generated underscore.c. */ -extern int prepends_underscore; - -int strip_underscore = 0; - -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} -}; - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ - -void -fancy_abort () -{ - fatal ("Internal gcc abort."); -} - - -/* Return the string of non-alnum characters that may occur - as a valid symbol component, in the standard assembler symbol - syntax. */ - -static const char * -standard_symbol_characters () -{ - return "_$."; -} - - -/* Return the string of non-alnum characters that may occur - as a valid symbol name component in an HP object file. - - Note that, since HP's compiler generates object code straight from - C++ source, without going through an assembler, its mangled - identifiers can use all sorts of characters that no assembler would - tolerate, so the alphabet this function creates is a little odd. - Here are some sample mangled identifiers offered by HP: - - typeid*__XT24AddressIndExpClassMember_ - [Vftptr]key:__dt__32OrdinaryCompareIndExpClassMemberFv - __ct__Q2_9Elf64_Dyn18{unnamed.union.#1}Fv - - This still seems really weird to me, since nowhere else in this - file is there anything to recognize curly brackets, parens, etc. - I've talked with Srikanth <srikanth@cup.hp.com>, and he assures me - this is right, but I still strongly suspect that there's a - misunderstanding here. - - If we decide it's better for c++filt to use HP's assembler syntax - to scrape identifiers out of its input, here's the definition of - the symbol name syntax from the HP assembler manual: - - Symbols are composed of uppercase and lowercase letters, decimal - digits, dollar symbol, period (.), ampersand (&), pound sign(#) and - underscore (_). A symbol can begin with a letter, digit underscore or - dollar sign. If a symbol begins with a digit, it must contain a - non-digit character. - - So have fun. */ -static const char * -hp_symbol_characters () -{ - return "_$.<>#,*&[]:(){}"; -} - - -int -main (argc, argv) - int argc; - char **argv; -{ - char *result; - int c; - char *valid_symbols; - - program_name = argv[0]; - - strip_underscore = prepends_underscore; - - while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF) - { - switch (c) - { - case '?': - usage (stderr, 1); - break; - case 'h': - usage (stdout, 0); - case 'n': - strip_underscore = 0; - break; - case 'v': - printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version); - exit (0); - case '_': - strip_underscore = 1; - break; - case 'j': - flags |= DMGL_JAVA; - break; - case 's': - if (strcmp (optarg, "gnu") == 0) - { - current_demangling_style = gnu_demangling; - } - else if (strcmp (optarg, "lucid") == 0) - { - current_demangling_style = lucid_demangling; - } - else if (strcmp (optarg, "arm") == 0) - { - current_demangling_style = arm_demangling; - } - else if (strcmp (optarg, "hp") == 0) - { - current_demangling_style = hp_demangling; - } - else if (strcmp (optarg, "edg") == 0) - { - current_demangling_style = edg_demangling; - } - else - { - fprintf (stderr, "%s: unknown demangling style `%s'\n", - program_name, optarg); - exit (1); - } - break; - } - } - - if (optind < argc) - { - for ( ; optind < argc; optind++) - { - demangle_it (argv[optind]); - } - } - else - { - switch (current_demangling_style) - { - case gnu_demangling: - case lucid_demangling: - case arm_demangling: - case edg_demangling: - valid_symbols = standard_symbol_characters (); - break; - case hp_demangling: - valid_symbols = hp_symbol_characters (); - break; - default: - /* Folks should explicitly indicate the appropriate alphabet for - each demangling. Providing a default would allow the - question to go unconsidered. */ - abort (); - } - - for (;;) - { - int i = 0; - c = getchar (); - /* Try to read a label. */ - while (c != EOF && (isalnum (c) || strchr (valid_symbols, c))) - { - if (i >= MBUF_SIZE-1) - break; - mbuffer[i++] = c; - c = getchar (); - } - if (i > 0) - { - int skip_first = 0; - - if (mbuffer[0] == '.') - ++skip_first; - if (strip_underscore && mbuffer[skip_first] == '_') - ++skip_first; - - if (skip_first > i) - skip_first = i; - - mbuffer[i] = 0; - - result = cplus_demangle (mbuffer + skip_first, flags); - if (result) - { - if (mbuffer[0] == '.') - putc ('.', stdout); - fputs (result, stdout); - free (result); - } - else - fputs (mbuffer, stdout); - - fflush (stdout); - } - if (c == EOF) - break; - putchar (c); - } - } - - exit (0); -} - -static void -fatal (str) - char *str; -{ - fprintf (stderr, "%s: %s\n", program_name, str); - exit (1); -} - -PTR -xmalloc (size) - size_t size; -{ - register PTR value = (PTR) malloc (size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} - -PTR -xrealloc (ptr, size) - PTR ptr; - size_t size; +string_append_template_idx (s, idx) + string *s; + int idx; { - register PTR value = (PTR) realloc (ptr, size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; + char buf[INTBUF_SIZE + 1 /* 'T' */]; + sprintf(buf, "T%d", idx); + string_append (s, buf); } -#endif /* main */ |