X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=libiberty%2Fcplus-dem.c;h=a990e072975e2b7137817ec8b316201954c34a6e;hb=be6a24d8eabdbeef32a9d79e81307af4491fcf56;hp=f3c4464f184ad9973e59ffd28273e47a585f1ba7;hpb=820542c970da46f15f9b691e77e7404a5c6fd734;p=deliverable%2Fbinutils-gdb.git diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index f3c4464f18..a990e07297 100644 --- a/libiberty/cplus-dem.c +++ b/libiberty/cplus-dem.c @@ -1,6 +1,5 @@ /* Demangler for GNU C++ - Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1989-2017 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 @@ -27,8 +26,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +not, write to the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +Boston, MA 02110-1301, USA. */ /* This file exports two functions; cplus_mangle_opname and cplus_demangle. @@ -52,8 +51,15 @@ Boston, MA 02111-1307, USA. */ #ifdef HAVE_STDLIB_H #include #else -char * malloc (); -char * realloc (); +void * malloc (); +void * realloc (); +#endif + +#ifdef HAVE_LIMITS_H +#include +#endif +#ifndef INT_MAX +# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */ #endif #include @@ -62,15 +68,13 @@ 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 that will be output when using the `%d' format with `printf'. */ #define INTBUF_SIZE 32 -extern void fancy_abort PARAMS ((void)) ATTRIBUTE_NORETURN; +extern void fancy_abort (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 @@ -99,8 +103,7 @@ static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; static char char_str[2] = { '\000', '\000' }; void -set_cplus_marker_for_demangling (ch) - int ch; +set_cplus_marker_for_demangling (int ch) { cplus_markers[0] = ch; } @@ -140,6 +143,9 @@ struct work_stuff string* previous_argument; /* The last function argument demangled. */ int nrepeats; /* The number of times to repeat the previous argument. */ + int *proctypevec; /* Indices of currently processed remembered typevecs. */ + int proctypevec_size; + int nproctypes; }; #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) @@ -240,6 +246,7 @@ typedef enum type_kind_t tk_none, tk_pointer, tk_reference, + tk_rvalue_reference, tk_integral, tk_bool, tk_char, @@ -308,6 +315,18 @@ const struct demangler_engine libiberty_demanglers[] = "GNAT style demangling" } , + { + DLANG_DEMANGLING_STYLE_STRING, + dlang_demangling, + "DLANG style demangling" + } + , + { + RUST_DEMANGLING_STYLE_STRING, + rust_demangling, + "Rust style demangling" + } + , { NULL, unknown_demangling, NULL } @@ -327,163 +346,131 @@ const struct demangler_engine libiberty_demanglers[] = /* Prototypes for local functions */ -static void -delete_work_stuff PARAMS ((struct work_stuff *)); +static void delete_work_stuff (struct work_stuff *); -static void -delete_non_B_K_work_stuff PARAMS ((struct work_stuff *)); +static void delete_non_B_K_work_stuff (struct work_stuff *); -static char * -mop_up PARAMS ((struct work_stuff *, string *, int)); +static char *mop_up (struct work_stuff *, string *, int); -static void -squangle_mop_up PARAMS ((struct work_stuff *)); +static void squangle_mop_up (struct work_stuff *); -static void -work_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *)); +static void work_stuff_copy_to_from (struct work_stuff *, struct work_stuff *); #if 0 static int -demangle_method_args PARAMS ((struct work_stuff *, const char **, string *)); +demangle_method_args (struct work_stuff *, const char **, string *); #endif static char * -internal_cplus_demangle PARAMS ((struct work_stuff *, const char *)); +internal_cplus_demangle (struct work_stuff *, const char *); static int -demangle_template_template_parm PARAMS ((struct work_stuff *work, - const char **, string *)); +demangle_template_template_parm (struct work_stuff *work, + const char **, string *); static int -demangle_template PARAMS ((struct work_stuff *work, const char **, string *, - string *, int, int)); +demangle_template (struct work_stuff *work, const char **, string *, + string *, int, int); static int -arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **, - const char **)); +arm_pt (struct work_stuff *, const char *, int, const char **, + const char **); static int -demangle_class_name PARAMS ((struct work_stuff *, const char **, string *)); +demangle_class_name (struct work_stuff *, const char **, string *); static int -demangle_qualified PARAMS ((struct work_stuff *, const char **, string *, - int, int)); +demangle_qualified (struct work_stuff *, const char **, string *, + int, int); -static int -demangle_class PARAMS ((struct work_stuff *, const char **, string *)); +static int demangle_class (struct work_stuff *, const char **, string *); -static int -demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *)); +static int demangle_fund_type (struct work_stuff *, const char **, string *); -static int -demangle_signature PARAMS ((struct work_stuff *, const char **, string *)); +static int demangle_signature (struct work_stuff *, const char **, string *); -static int -demangle_prefix PARAMS ((struct work_stuff *, const char **, string *)); +static int demangle_prefix (struct work_stuff *, const char **, string *); -static int -gnu_special PARAMS ((struct work_stuff *, const char **, string *)); +static int gnu_special (struct work_stuff *, const char **, string *); -static int -arm_special PARAMS ((const char **, string *)); +static int arm_special (const char **, string *); -static void -string_need PARAMS ((string *, int)); +static void string_need (string *, int); -static void -string_delete PARAMS ((string *)); +static void string_delete (string *); static void -string_init PARAMS ((string *)); +string_init (string *); -static void -string_clear PARAMS ((string *)); +static void string_clear (string *); #if 0 -static int -string_empty PARAMS ((string *)); +static int string_empty (string *); #endif -static void -string_append PARAMS ((string *, const char *)); +static void string_append (string *, const char *); -static void -string_appends PARAMS ((string *, string *)); +static void string_appends (string *, string *); -static void -string_appendn PARAMS ((string *, const char *, int)); +static void string_appendn (string *, const char *, int); -static void -string_prepend PARAMS ((string *, const char *)); +static void string_prepend (string *, const char *); -static void -string_prependn PARAMS ((string *, const char *, int)); +static void string_prependn (string *, const char *, int); -static void -string_append_template_idx PARAMS ((string *, int)); +static void string_append_template_idx (string *, int); -static int -get_count PARAMS ((const char **, int *)); +static int get_count (const char **, int *); -static int -consume_count PARAMS ((const char **)); +static int consume_count (const char **); -static int -consume_count_with_underscores PARAMS ((const char**)); +static int consume_count_with_underscores (const char**); -static int -demangle_args PARAMS ((struct work_stuff *, const char **, string *)); +static int demangle_args (struct work_stuff *, const char **, string *); -static int -demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*)); +static int demangle_nested_args (struct work_stuff*, const char**, string*); + +static int do_type (struct work_stuff *, const char **, string *); + +static int do_arg (struct work_stuff *, const char **, string *); static int -do_type PARAMS ((struct work_stuff *, const char **, string *)); +demangle_function_name (struct work_stuff *, const char **, string *, + const char *); static int -do_arg PARAMS ((struct work_stuff *, const char **, string *)); +iterate_demangle_function (struct work_stuff *, + const char **, string *, const char *); -static void -demangle_function_name PARAMS ((struct work_stuff *, const char **, string *, - const char *)); +static void remember_type (struct work_stuff *, const char *, int); -static int -iterate_demangle_function PARAMS ((struct work_stuff *, - const char **, string *, const char *)); +static void push_processed_type (struct work_stuff *, int); -static void -remember_type PARAMS ((struct work_stuff *, const char *, int)); +static void pop_processed_type (struct work_stuff *); -static void -remember_Btype PARAMS ((struct work_stuff *, const char *, int, int)); +static void remember_Btype (struct work_stuff *, const char *, int, int); -static int -register_Btype PARAMS ((struct work_stuff *)); +static int register_Btype (struct work_stuff *); -static void -remember_Ktype PARAMS ((struct work_stuff *, const char *, int)); +static void remember_Ktype (struct work_stuff *, const char *, int); -static void -forget_types PARAMS ((struct work_stuff *)); +static void forget_types (struct work_stuff *); -static void -forget_B_and_K_types PARAMS ((struct work_stuff *)); +static void forget_B_and_K_types (struct work_stuff *); -static void -string_prepends PARAMS ((string *, string *)); +static void string_prepends (string *, string *); static int -demangle_template_value_parm PARAMS ((struct work_stuff*, const char**, - string*, type_kind_t)); +demangle_template_value_parm (struct work_stuff*, const char**, + string*, type_kind_t); static int -do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *)); +do_hpacc_template_const_value (struct work_stuff *, const char **, string *); static int -do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *)); +do_hpacc_template_literal (struct work_stuff *, const char **, string *); -static int -snarf_numeric_literal PARAMS ((const char **, string *)); +static int snarf_numeric_literal (const char **, string *); /* There is a TYPE_QUAL value for each type qualifier. They can be combined by bitwise-or to form the complete set of qualifiers for a @@ -494,36 +481,26 @@ snarf_numeric_literal PARAMS ((const char **, string *)); #define TYPE_QUAL_VOLATILE 0x2 #define TYPE_QUAL_RESTRICT 0x4 -static int -code_for_qualifier PARAMS ((int)); +static int code_for_qualifier (int); -static const char* -qualifier_string PARAMS ((int)); +static const char* qualifier_string (int); -static const char* -demangle_qualifier PARAMS ((int)); +static const char* demangle_qualifier (int); -static int -demangle_expression PARAMS ((struct work_stuff *, const char **, string *, - type_kind_t)); +static int demangle_expression (struct work_stuff *, const char **, string *, + type_kind_t); static int -demangle_integral_value PARAMS ((struct work_stuff *, const char **, - string *)); +demangle_integral_value (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 *)); +demangle_real_value (struct work_stuff *, const char **, string *); static void -recursively_demangle PARAMS ((struct work_stuff *, const char **, string *, - int)); +demangle_arm_hp_template (struct work_stuff *, const char **, int, string *); static void -grow_vect PARAMS ((char **, size_t *, size_t, int)); +recursively_demangle (struct work_stuff *, const char **, string *, int); /* Translate count to integer, consuming tokens in the process. Conversion terminates on the first non-digit character. @@ -534,8 +511,7 @@ grow_vect PARAMS ((char **, size_t *, size_t, int)); Overflow consumes the rest of the digits, and returns -1. */ static int -consume_count (type) - const char **type; +consume_count (const char **type) { int count = 0; @@ -574,8 +550,7 @@ consume_count (type) failure, since 0 can be a valid value. */ static int -consume_count_with_underscores (mangled) - const char **mangled; +consume_count_with_underscores (const char **mangled) { int idx; @@ -608,8 +583,7 @@ consume_count_with_underscores (mangled) corresponding to this qualifier. */ static int -code_for_qualifier (c) - int c; +code_for_qualifier (int c) { switch (c) { @@ -634,8 +608,7 @@ code_for_qualifier (c) TYPE_QUALS. */ static const char* -qualifier_string (type_quals) - int type_quals; +qualifier_string (int type_quals) { switch (type_quals) { @@ -676,17 +649,13 @@ qualifier_string (type_quals) called with a valid qualifier code. */ static const char* -demangle_qualifier (c) - int c; +demangle_qualifier (int c) { return qualifier_string (code_for_qualifier (c)); } int -cplus_demangle_opname (opname, result, options) - const char *opname; - char *result; - int options; +cplus_demangle_opname (const char *opname, char *result, int options) { int len, len1, ret; string type; @@ -819,9 +788,7 @@ cplus_demangle_opname (opname, result, options) if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */ const char * -cplus_mangle_opname (opname, options) - const char *opname; - int options; +cplus_mangle_opname (const char *opname, int options) { size_t i; int len; @@ -841,8 +808,7 @@ cplus_mangle_opname (opname, options) allow for any demangler initialization that maybe necessary. */ enum demangling_styles -cplus_demangle_set_style (style) - enum demangling_styles style; +cplus_demangle_set_style (enum demangling_styles style) { const struct demangler_engine *demangler = libiberty_demanglers; @@ -859,8 +825,7 @@ cplus_demangle_set_style (style) /* Do string name to style translation */ enum demangling_styles -cplus_demangle_name_to_style (name) - const char *name; +cplus_demangle_name_to_style (const char *name) { const struct demangler_engine *demangler = libiberty_demanglers; @@ -900,9 +865,7 @@ cplus_demangle_name_to_style (name) MANGLED. */ char * -cplus_demangle (mangled, options) - const char *mangled; - int options; +cplus_demangle (const char *mangled, int options) { char *ret; struct work_stuff work[1]; @@ -916,10 +879,26 @@ cplus_demangle (mangled, options) work->options |= (int) current_demangling_style & DMGL_STYLE_MASK; /* The V3 ABI demangling is implemented elsewhere. */ - if (GNU_V3_DEMANGLING || AUTO_DEMANGLING) + if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING) { ret = cplus_demangle_v3 (mangled, work->options); - if (ret || GNU_V3_DEMANGLING) + if (GNU_V3_DEMANGLING) + return ret; + + if (ret) + { + /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. + The subtitutions are always smaller, so do in place changes. */ + if (rust_is_mangled (ret)) + rust_demangle_sym (ret); + else if (RUST_DEMANGLING) + { + free (ret); + ret = NULL; + } + } + + if (ret || RUST_DEMANGLING) return ret; } @@ -931,136 +910,297 @@ cplus_demangle (mangled, options) } if (GNAT_DEMANGLING) - return ada_demangle(mangled,options); + return ada_demangle (mangled, options); + + if (DLANG_DEMANGLING) + { + ret = dlang_demangle (mangled, options); + if (ret) + return ret; + } ret = internal_cplus_demangle (work, mangled); squangle_mop_up (work); return (ret); } - -/* 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; +char * +rust_demangle (const char *mangled, int options) { - if (*size < min_size) + /* Rust symbols are GNU_V3 mangled plus some extra subtitutions. */ + char *ret = cplus_demangle_v3 (mangled, options); + + /* The Rust subtitutions are always smaller, so do in place changes. */ + if (ret != NULL) { - *size *= 2; - if (*size < min_size) - *size = min_size; - *old_vect = (void *) xrealloc (*old_vect, *size * element_size); + if (rust_is_mangled (ret)) + rust_demangle_sym (ret); + else + { + free (ret); + ret = NULL; + } } + + return ret; } -/* 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. */ +/* Demangle ada names. The encoding is documented in gcc/ada/exp_dbug.ads. */ -static char * -ada_demangle (mangled, option) - const char *mangled; - int option ATTRIBUTE_UNUSED; +char * +ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED) { - int i, j; int len0; const char* p; + char *d; char *demangled = NULL; - int at_start_name; - int changed; - size_t demangled_size = 0; - changed = 0; - + /* Discard leading _ada_, which is used for library level subprograms. */ if (strncmp (mangled, "_ada_", 5) == 0) - { - mangled += 5; - changed = 1; - } - - if (mangled[0] == '_' || mangled[0] == '<') - goto Suppress; + mangled += 5; + + /* All ada unit names are lower-case. */ + if (!ISLOWER (mangled[0])) + goto unknown; + + /* Most of the demangling will trivially remove chars. Operator names + may add one char but because they are always preceeded by '__' which is + replaced by '.', they eventually never expand the size. + A few special names such as '___elabs' add a few chars (at most 7), but + they occur only once. */ + len0 = strlen (mangled) + 7 + 1; + demangled = XNEWVEC (char, len0); - p = strstr (mangled, "___"); - if (p == NULL) - len0 = strlen (mangled); - else + d = demangled; + p = mangled; + while (1) { - if (p[3] == 'X') - { - len0 = p - mangled; - changed = 1; - } + /* An entity names is expected. */ + if (ISLOWER (*p)) + { + /* An identifier, which is always lower case. */ + do + *d++ = *p++; + while (ISLOWER(*p) || ISDIGIT (*p) + || (p[0] == '_' && (ISLOWER (p[1]) || ISDIGIT (p[1])))); + } + else if (p[0] == 'O') + { + /* An operator name. */ + static const char * const operators[][2] = + {{"Oabs", "abs"}, {"Oand", "and"}, {"Omod", "mod"}, + {"Onot", "not"}, {"Oor", "or"}, {"Orem", "rem"}, + {"Oxor", "xor"}, {"Oeq", "="}, {"One", "/="}, + {"Olt", "<"}, {"Ole", "<="}, {"Ogt", ">"}, + {"Oge", ">="}, {"Oadd", "+"}, {"Osubtract", "-"}, + {"Oconcat", "&"}, {"Omultiply", "*"}, {"Odivide", "/"}, + {"Oexpon", "**"}, {NULL, NULL}}; + int k; + + for (k = 0; operators[k][0] != NULL; k++) + { + size_t slen = strlen (operators[k][0]); + if (strncmp (p, operators[k][0], slen) == 0) + { + p += slen; + slen = strlen (operators[k][1]); + *d++ = '"'; + memcpy (d, operators[k][1], slen); + d += slen; + *d++ = '"'; + break; + } + } + /* Operator not found. */ + if (operators[k][0] == NULL) + goto unknown; + } 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; - } + { + /* Not a GNAT encoding. */ + goto unknown; + } + + /* The name can be directly followed by some uppercase letters. */ + if (p[0] == 'T' && p[1] == 'K') + { + /* Task stuff. */ + if (p[2] == 'B' && p[3] == 0) + { + /* Subprogram for task body. */ + break; + } + else if (p[2] == '_' && p[3] == '_') + { + /* Inner declarations in a task. */ + p += 4; + *d++ = '.'; + continue; + } + else + goto unknown; + } + if (p[0] == 'E' && p[1] == 0) + { + /* Exception name. */ + goto unknown; + } + if ((p[0] == 'P' || p[0] == 'N') && p[1] == 0) + { + /* Protected type subprogram. */ + break; + } + if ((*p == 'N' || *p == 'S') && p[1] == 0) + { + /* Enumerated type name table. */ + goto unknown; + } + if (p[0] == 'X') + { + /* Body nested. */ + p++; + while (p[0] == 'n' || p[0] == 'b') + p++; + } + if (p[0] == 'S' && p[1] != 0 && (p[2] == '_' || p[2] == 0)) + { + /* Stream operations. */ + const char *name; + switch (p[1]) + { + case 'R': + name = "'Read"; + break; + case 'W': + name = "'Write"; + break; + case 'I': + name = "'Input"; + break; + case 'O': + name = "'Output"; + break; + default: + goto unknown; + } + p += 2; + strcpy (d, name); + d += strlen (name); + } + else if (p[0] == 'D') + { + /* Controlled type operation. */ + const char *name; + switch (p[1]) + { + case 'F': + name = ".Finalize"; + break; + case 'A': + name = ".Adjust"; + break; + default: + goto unknown; + } + strcpy (d, name); + d += strlen (name); + break; + } + + if (p[0] == '_') + { + /* Separator. */ + if (p[1] == '_') + { + /* Standard separator. Handled first. */ + p += 2; + + if (ISDIGIT (*p)) + { + /* Overloading number. */ + do + p++; + while (ISDIGIT (*p) || (p[0] == '_' && ISDIGIT (p[1]))); + if (*p == 'X') + { + p++; + while (p[0] == 'n' || p[0] == 'b') + p++; + } + } + else if (p[0] == '_' && p[1] != '_') + { + /* Special names. */ + static const char * const special[][2] = { + { "_elabb", "'Elab_Body" }, + { "_elabs", "'Elab_Spec" }, + { "_size", "'Size" }, + { "_alignment", "'Alignment" }, + { "_assign", ".\":=\"" }, + { NULL, NULL } + }; + int k; + + for (k = 0; special[k][0] != NULL; k++) + { + size_t slen = strlen (special[k][0]); + if (strncmp (p, special[k][0], slen) == 0) + { + p += slen; + slen = strlen (special[k][1]); + memcpy (d, special[k][1], slen); + d += slen; + break; + } + } + if (special[k][0] != NULL) + break; + else + goto unknown; + } + else + { + *d++ = '.'; + continue; + } + } + else if (p[1] == 'B' || p[1] == 'E') + { + /* Entry Body or barrier Evaluation. */ + p += 2; + while (ISDIGIT (*p)) + p++; + if (p[0] == 's' && p[1] == 0) + break; + else + goto unknown; + } + else + goto unknown; + } + + if (p[0] == '.' && ISDIGIT (p[1])) + { + /* Nested subprogram. */ + p += 2; + while (ISDIGIT (*p)) + p++; + } + if (*p == 0) + { + /* End of mangled name. */ + break; + } else - { - demangled[j] = mangled[i]; - i += 1; j += 1; - } + goto unknown; } - demangled[j] = '\000'; - - for (i = 0; demangled[i] != '\0'; i += 1) - if (ISUPPER ((unsigned char)demangled[i]) || demangled[i] == ' ') - goto Suppress; + *d = 0; + return demangled; - if (! changed) - return NULL; - else - return demangled; - - Suppress: - grow_vect (&demangled, - &demangled_size, strlen (mangled) + 3, - sizeof (char)); + unknown: + XDELETEVEC (demangled); + len0 = strlen (mangled); + demangled = XNEWVEC (char, len0 + 3); if (mangled[0] == '<') strcpy (demangled, mangled); @@ -1077,9 +1217,7 @@ ada_demangle (mangled, option) calls go directly to this routine to avoid resetting that info. */ static char * -internal_cplus_demangle (work, mangled) - struct work_stuff *work; - const char *mangled; +internal_cplus_demangle (struct work_stuff *work, const char *mangled) { string decl; @@ -1108,6 +1246,11 @@ internal_cplus_demangle (work, mangled) if ((AUTO_DEMANGLING || GNU_DEMANGLING)) { success = gnu_special (work, &mangled, &decl); + if (!success) + { + delete_work_stuff (work); + string_delete (&decl); + } } if (!success) { @@ -1144,18 +1287,21 @@ internal_cplus_demangle (work, mangled) /* Clear out and squangling related storage */ static void -squangle_mop_up (work) - struct work_stuff *work; +squangle_mop_up (struct work_stuff *work) { /* clean up the B and K type mangling types. */ forget_B_and_K_types (work); if (work -> btypevec != NULL) { free ((char *) work -> btypevec); + work->btypevec = NULL; + work->bsize = 0; } if (work -> ktypevec != NULL) { free ((char *) work -> ktypevec); + work->ktypevec = NULL; + work->ksize = 0; } } @@ -1163,9 +1309,7 @@ squangle_mop_up (work) /* Copy the work state and storage. */ static void -work_stuff_copy_to_from (to, from) - struct work_stuff *to; - struct work_stuff *from; +work_stuff_copy_to_from (struct work_stuff *to, struct work_stuff *from) { int i; @@ -1176,56 +1320,56 @@ work_stuff_copy_to_from (to, from) /* Deep-copy dynamic storage. */ if (from->typevec_size) - to->typevec - = (char **) xmalloc (from->typevec_size * sizeof (to->typevec[0])); + to->typevec = XNEWVEC (char *, from->typevec_size); for (i = 0; i < from->ntypes; i++) { int len = strlen (from->typevec[i]) + 1; - to->typevec[i] = xmalloc (len); + to->typevec[i] = XNEWVEC (char, len); memcpy (to->typevec[i], from->typevec[i], len); } if (from->ksize) - to->ktypevec - = (char **) xmalloc (from->ksize * sizeof (to->ktypevec[0])); + to->ktypevec = XNEWVEC (char *, from->ksize); for (i = 0; i < from->numk; i++) { int len = strlen (from->ktypevec[i]) + 1; - to->ktypevec[i] = xmalloc (len); + to->ktypevec[i] = XNEWVEC (char, len); memcpy (to->ktypevec[i], from->ktypevec[i], len); } if (from->bsize) - to->btypevec - = (char **) xmalloc (from->bsize * sizeof (to->btypevec[0])); + to->btypevec = XNEWVEC (char *, from->bsize); for (i = 0; i < from->numb; i++) { int len = strlen (from->btypevec[i]) + 1; - to->btypevec[i] = xmalloc (len); + to->btypevec[i] = XNEWVEC (char , len); memcpy (to->btypevec[i], from->btypevec[i], len); } + if (from->proctypevec) + to->proctypevec = + XDUPVEC (int, from->proctypevec, from->proctypevec_size); + if (from->ntmpl_args) - to->tmpl_argvec - = (char **) xmalloc (from->ntmpl_args * sizeof (to->tmpl_argvec[0])); + to->tmpl_argvec = XNEWVEC (char *, from->ntmpl_args); for (i = 0; i < from->ntmpl_args; i++) { int len = strlen (from->tmpl_argvec[i]) + 1; - to->tmpl_argvec[i] = xmalloc (len); + to->tmpl_argvec[i] = XNEWVEC (char, len); memcpy (to->tmpl_argvec[i], from->tmpl_argvec[i], len); } if (from->previous_argument) { - to->previous_argument = (string*) xmalloc (sizeof (string)); + to->previous_argument = XNEW (string); string_init (to->previous_argument); string_appends (to->previous_argument, from->previous_argument); } @@ -1235,25 +1379,29 @@ work_stuff_copy_to_from (to, from) /* 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; +delete_non_B_K_work_stuff (struct work_stuff *work) { /* Discard the remembered types, if any. */ forget_types (work); - if (work -> typevec != NULL) + if (work->typevec != NULL) { - free ((char *) work -> typevec); - work -> typevec = NULL; - work -> typevec_size = 0; + free ((char *) work->typevec); + work->typevec = NULL; + work->typevec_size = 0; + } + if (work->proctypevec != NULL) + { + free (work->proctypevec); + work->proctypevec = NULL; + work->proctypevec_size = 0; } if (work->tmpl_argvec) { int i; for (i = 0; i < work->ntmpl_args; i++) - if (work->tmpl_argvec[i]) - free ((char*) work->tmpl_argvec[i]); + free ((char*) work->tmpl_argvec[i]); free ((char*) work->tmpl_argvec); work->tmpl_argvec = NULL; @@ -1269,8 +1417,7 @@ delete_non_B_K_work_stuff (work) /* Delete all dynamic storage in work_stuff. */ static void -delete_work_stuff (work) - struct work_stuff *work; +delete_work_stuff (struct work_stuff *work) { delete_non_B_K_work_stuff (work); squangle_mop_up (work); @@ -1280,10 +1427,7 @@ delete_work_stuff (work) /* Clear out any mangled storage */ static char * -mop_up (work, declp, success) - struct work_stuff *work; - string *declp; - int success; +mop_up (struct work_stuff *work, string *declp, int success) { char *demangled = NULL; @@ -1335,10 +1479,8 @@ DESCRIPTION argument list. */ static int -demangle_signature (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; +demangle_signature (struct work_stuff *work, + const char **mangled, string *declp) { int success = 1; int func_done = 0; @@ -1554,12 +1696,13 @@ demangle_signature (work, mangled, declp) 0); if (!(work->constructor & 1)) expect_return_type = 1; - (*mangled)++; + if (!**mangled) + success = 0; + else + (*mangled)++; break; } - else - /* fall through */ - {;} + /* fall through */ default: if (AUTO_DEMANGLING || GNU_DEMANGLING) @@ -1628,10 +1771,8 @@ demangle_signature (work, mangled, declp) #if 0 static int -demangle_method_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; +demangle_method_args (struct work_stuff *work, const char **mangled, + string *declp) { int success = 0; @@ -1651,10 +1792,8 @@ demangle_method_args (work, mangled, declp) #endif static int -demangle_template_template_parm (work, mangled, tname) - struct work_stuff *work; - const char **mangled; - string *tname; +demangle_template_template_parm (struct work_stuff *work, + const char **mangled, string *tname) { int i; int r; @@ -1715,11 +1854,8 @@ demangle_template_template_parm (work, mangled, tname) } static int -demangle_expression (work, mangled, s, tk) - struct work_stuff *work; - const char** mangled; - string* s; - type_kind_t tk; +demangle_expression (struct work_stuff *work, const char **mangled, + string *s, type_kind_t tk) { int need_operator = 0; int success; @@ -1775,10 +1911,8 @@ demangle_expression (work, mangled, s, tk) } static int -demangle_integral_value (work, mangled, s) - struct work_stuff *work; - const char** mangled; - string* s; +demangle_integral_value (struct work_stuff *work, + const char **mangled, string *s) { int success; @@ -1873,10 +2007,8 @@ demangle_integral_value (work, mangled, s) /* Demangle the real value in MANGLED. */ static int -demangle_real_value (work, mangled, s) - struct work_stuff *work; - const char **mangled; - string* s; +demangle_real_value (struct work_stuff *work, + const char **mangled, string *s) { if (**mangled == 'E') return demangle_expression (work, mangled, s, tk_real); @@ -1916,11 +2048,8 @@ demangle_real_value (work, mangled, s) } static int -demangle_template_value_parm (work, mangled, s, tk) - struct work_stuff *work; - const char **mangled; - string* s; - type_kind_t tk; +demangle_template_value_parm (struct work_stuff *work, const char **mangled, + string *s, type_kind_t tk) { int success = 1; @@ -1975,7 +2104,8 @@ demangle_template_value_parm (work, mangled, s, tk) } else if (tk == tk_real) success = demangle_real_value (work, mangled, s); - else if (tk == tk_pointer || tk == tk_reference) + else if (tk == tk_pointer || tk == tk_reference + || tk == tk_rvalue_reference) { if (**mangled == 'Q') success = demangle_qualified (work, mangled, s, @@ -1984,13 +2114,14 @@ demangle_template_value_parm (work, mangled, s, tk) else { int symbol_len = consume_count (mangled); - if (symbol_len == -1) + if (symbol_len == -1 + || symbol_len > (long) strlen (*mangled)) return -1; if (symbol_len == 0) string_appendn (s, "0", 1); else { - char *p = xmalloc (symbol_len + 1), *q; + char *p = XNEWVEC (char, symbol_len + 1), *q; strncpy (p, *mangled, symbol_len); p [symbol_len] = '\0'; /* We use cplus_demangle here, rather than @@ -2028,31 +2159,27 @@ demangle_template_value_parm (work, mangled, s, tk) types. */ static int -demangle_template (work, mangled, tname, trawname, is_type, remember) - struct work_stuff *work; - const char **mangled; - string *tname; - string *trawname; - int is_type; - int remember; +demangle_template (struct work_stuff *work, const char **mangled, + string *tname, string *trawname, + int is_type, int remember) { int i; int r; int need_comma = 0; int success = 0; - const char *start; int is_java_array = 0; string temp; (*mangled)++; if (is_type) { - start = *mangled; /* get template name */ if (**mangled == 'z') { int idx; (*mangled)++; + if (**mangled == '\0') + return (0); (*mangled)++; idx = consume_count_with_underscores (mangled); @@ -2102,7 +2229,7 @@ demangle_template (work, mangled, tname, trawname, is_type, remember) if (!is_type) { /* Create an array for saving the template argument values. */ - work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *)); + work->tmpl_argvec = XNEWVEC (char *, r); work->ntmpl_args = r; for (i = 0; i < r; i++) work->tmpl_argvec[i] = 0; @@ -2127,7 +2254,7 @@ demangle_template (work, mangled, tname, trawname, is_type, remember) { /* Save the template argument. */ int len = temp.p - temp.b; - work->tmpl_argvec[i] = xmalloc (len + 1); + work->tmpl_argvec[i] = XNEWVEC (char, len + 1); memcpy (work->tmpl_argvec[i], temp.b, len); work->tmpl_argvec[i][len] = '\0'; } @@ -2155,7 +2282,7 @@ demangle_template (work, mangled, tname, trawname, is_type, remember) { /* Save the template argument. */ int len = r2; - work->tmpl_argvec[i] = xmalloc (len + 1); + work->tmpl_argvec[i] = XNEWVEC (char, len + 1); memcpy (work->tmpl_argvec[i], *mangled, len); work->tmpl_argvec[i][len] = '\0'; } @@ -2201,7 +2328,7 @@ demangle_template (work, mangled, tname, trawname, is_type, remember) if (!is_type) { int len = s->p - s->b; - work->tmpl_argvec[i] = xmalloc (len + 1); + work->tmpl_argvec[i] = XNEWVEC (char, len + 1); memcpy (work->tmpl_argvec[i], s->b, len); work->tmpl_argvec[i][len] = '\0'; @@ -2245,11 +2372,8 @@ demangle_template (work, mangled, tname, trawname, is_type, remember) } static int -arm_pt (work, mangled, n, anchor, args) - struct work_stuff *work; - const char *mangled; - int n; - const char **anchor, **args; +arm_pt (struct work_stuff *work, const char *mangled, + int n, const char **anchor, const char **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 */ @@ -2302,11 +2426,8 @@ arm_pt (work, mangled, n, anchor, args) } static void -demangle_arm_hp_template (work, mangled, n, declp) - struct work_stuff *work; - const char **mangled; - int n; - string *declp; +demangle_arm_hp_template (struct work_stuff *work, const char **mangled, + int n, string *declp) { const char *p; const char *args; @@ -2483,10 +2604,8 @@ demangle_arm_hp_template (work, mangled, n, declp) already been dealt with */ static int -demangle_class_name (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; +demangle_class_name (struct work_stuff *work, const char **mangled, + string *declp) { int n; int success = 0; @@ -2539,10 +2658,7 @@ DESCRIPTION */ static int -demangle_class (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; +demangle_class (struct work_stuff *work, const char **mangled, string *declp) { int success = 0; int btype; @@ -2594,11 +2710,8 @@ demangle_class (work, mangled, declp) demangle_signature. */ static int -iterate_demangle_function (work, mangled, declp, scan) - struct work_stuff *work; - const char **mangled; - string *declp; - const char *scan; +iterate_demangle_function (struct work_stuff *work, const char **mangled, + string *declp, const char *scan) { const char *mangle_init = *mangled; int success = 0; @@ -2612,10 +2725,7 @@ iterate_demangle_function (work, mangled, declp, scan) "__"-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; - } + return demangle_function_name (work, mangled, declp, scan); /* Save state so we can restart if the guess at the correct "__" was wrong. */ @@ -2632,10 +2742,12 @@ iterate_demangle_function (work, mangled, declp, scan) while (scan[2]) { - demangle_function_name (work, mangled, declp, scan); - success = demangle_signature (work, mangled, declp); - if (success) - break; + if (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; @@ -2697,10 +2809,8 @@ DESCRIPTION */ static int -demangle_prefix (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; +demangle_prefix (struct work_stuff *work, const char **mangled, + string *declp) { int success = 1; const char *scan; @@ -2908,16 +3018,13 @@ DESCRIPTION */ static int -gnu_special (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; +gnu_special (struct work_stuff *work, const char **mangled, string *declp) { int n; int success = 1; const char *p; - if ((*mangled)[0] == '_' + if ((*mangled)[0] == '_' && (*mangled)[1] != '\0' && strchr (cplus_markers, (*mangled)[1]) != NULL && (*mangled)[2] == '_') { @@ -2931,7 +3038,7 @@ gnu_special (work, mangled, declp) && (*mangled)[3] == 't' && (*mangled)[4] == '_') || ((*mangled)[1] == 'v' - && (*mangled)[2] == 't' + && (*mangled)[2] == 't' && (*mangled)[3] != '\0' && strchr (cplus_markers, (*mangled)[3]) != NULL))) { /* Found a GNU style virtual table, get past "_vt" @@ -2967,6 +3074,11 @@ gnu_special (work, mangled, declp) success = 1; break; } + else if (n == -1) + { + success = 0; + break; + } } else { @@ -3112,16 +3224,13 @@ gnu_special (work, mangled, declp) } static void -recursively_demangle(work, mangled, result, namelength) - struct work_stuff *work; - const char **mangled; - string *result; - int namelength; +recursively_demangle(struct work_stuff *work, const char **mangled, + string *result, int namelength) { char * recurse = (char *)NULL; char * recurse_dem = (char *)NULL; - recurse = (char *) xmalloc (namelength + 1); + recurse = XNEWVEC (char, namelength + 1); memcpy (recurse, *mangled, namelength); recurse[namelength] = '\000'; @@ -3164,9 +3273,7 @@ DESCRIPTION */ static int -arm_special (mangled, declp) - const char **mangled; - string *declp; +arm_special (const char **mangled, string *declp) { int n; int success = 1; @@ -3249,12 +3356,8 @@ BUGS */ static int -demangle_qualified (work, mangled, result, isfuncname, append) - struct work_stuff *work; - const char **mangled; - string *result; - int isfuncname; - int append; +demangle_qualified (struct work_stuff *work, const char **mangled, + string *result, int isfuncname, int append) { int qualifiers = 0; int success = 1; @@ -3476,9 +3579,7 @@ DESCRIPTION */ static int -get_count (type, count) - const char **type; - int *count; +get_count (const char **type, int *count) { const char *p; int n; @@ -3514,12 +3615,11 @@ get_count (type, count) value returned is really a type_kind_t. */ static int -do_type (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; +do_type (struct work_stuff *work, const char **mangled, string *result) { int n; + int i; + int is_proctypevec; int done; int success; string decl; @@ -3532,6 +3632,7 @@ do_type (work, mangled, result) done = 0; success = 1; + is_proctypevec = 0; while (success && !done) { int member; @@ -3556,6 +3657,14 @@ do_type (work, mangled, result) tk = tk_reference; break; + /* An rvalue reference type */ + case 'O': + (*mangled)++; + string_prepend (&decl, "&&"); + if (tk == tk_none) + tk = tk_rvalue_reference; + break; + /* An array */ case 'A': { @@ -3579,13 +3688,20 @@ do_type (work, mangled, result) /* A back reference to a previously seen type */ case 'T': (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> ntypes) + if (!get_count (mangled, &n) || n < 0 || n >= work -> ntypes) { success = 0; } else - { - remembered_type = work -> typevec[n]; + for (i = 0; i < work->nproctypes; i++) + if (work -> proctypevec [i] == n) + success = 0; + + if (success) + { + is_proctypevec = 1; + push_processed_type (work, n); + remembered_type = work->typevec[n]; mangled = &remembered_type; } break; @@ -3613,7 +3729,6 @@ do_type (work, mangled, result) break; case 'M': - case 'O': { type_quals = TYPE_UNQUALIFIED; @@ -3658,7 +3773,10 @@ do_type (work, mangled, result) string_delete (&temp); } else - break; + { + string_delete (&temp); + break; + } } else if (**mangled == 'Q') { @@ -3690,11 +3808,12 @@ do_type (work, mangled, result) break; } - if (*(*mangled)++ != 'F') + if (*(*mangled) != 'F') { success = 0; break; } + (*mangled)++; } if ((member && !demangle_nested_args (work, mangled, &decl)) || **mangled != '_') @@ -3754,7 +3873,7 @@ do_type (work, mangled, result) /* A back reference to a previously seen squangled type */ case 'B': (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> numb) + if (!get_count (mangled, &n) || n < 0 || n >= work -> numb) success = 0; else string_append (result, work->btypevec[n]); @@ -3805,6 +3924,9 @@ do_type (work, mangled, result) string_delete (result); string_delete (&decl); + if (is_proctypevec) + pop_processed_type (work); + if (success) /* Assume an integral type, if we're not sure. */ return (int) ((tk == tk_none) ? tk_integral : tk); @@ -3826,14 +3948,12 @@ do_type (work, mangled, result) The value returned is really a type_kind_t. */ static int -demangle_fund_type (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; +demangle_fund_type (struct work_stuff *work, + const char **mangled, string *result) { int done = 0; int success = 1; - char buf[10]; + char buf[INTBUF_SIZE + 5 /* 'int%u_t' */]; unsigned int dec = 0; type_kind_t tk = tk_integral; @@ -3950,6 +4070,7 @@ demangle_fund_type (work, mangled, result) success = 0; break; } + /* fall through */ case 'I': (*mangled)++; if (**mangled == '_') @@ -4028,10 +4149,8 @@ demangle_fund_type (work, mangled, result) **mangled points to 'S' or 'U' */ static int -do_hpacc_template_const_value (work, mangled, result) - struct work_stuff *work ATTRIBUTE_UNUSED; - const char **mangled; - string *result; +do_hpacc_template_const_value (struct work_stuff *work ATTRIBUTE_UNUSED, + const char **mangled, string *result) { int unsigned_const; @@ -4085,10 +4204,8 @@ do_hpacc_template_const_value (work, mangled, result) **mangled is pointing to the 'A' */ static int -do_hpacc_template_literal (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; +do_hpacc_template_literal (struct work_stuff *work, const char **mangled, + string *result) { int literal_len = 0; char * recurse; @@ -4101,7 +4218,8 @@ do_hpacc_template_literal (work, mangled, result) literal_len = consume_count (mangled); - if (literal_len <= 0) + if (literal_len <= 0 + || literal_len > (long) strlen (*mangled)) return 0; /* Literal parameters are names of arrays, functions, etc. and the @@ -4109,7 +4227,7 @@ do_hpacc_template_literal (work, mangled, result) string_append (result, "&"); /* Now recursively demangle the literal name */ - recurse = (char *) xmalloc (literal_len + 1); + recurse = XNEWVEC (char, literal_len + 1); memcpy (recurse, *mangled, literal_len); recurse[literal_len] = '\000'; @@ -4131,9 +4249,7 @@ do_hpacc_template_literal (work, mangled, result) } static int -snarf_numeric_literal (args, arg) - const char ** args; - string * arg; +snarf_numeric_literal (const char **args, string *arg) { if (**args == '-') { @@ -4162,10 +4278,7 @@ snarf_numeric_literal (args, arg) and free'd should anything go wrong. */ static int -do_arg (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; +do_arg (struct work_stuff *work, const char **mangled, string *result) { /* Remember where we started so that we can record the type, for non-squangling type remembering. */ @@ -4216,7 +4329,7 @@ do_arg (work, mangled, result) if (work->previous_argument) string_delete (work->previous_argument); else - work->previous_argument = (string*) xmalloc (sizeof (string)); + work->previous_argument = XNEW (string); if (!do_type (work, mangled, work->previous_argument)) return 0; @@ -4228,10 +4341,42 @@ do_arg (work, mangled, result) } static void -remember_type (work, start, len) - struct work_stuff *work; - const char *start; - int len; +push_processed_type (struct work_stuff *work, int typevec_index) +{ + if (work->nproctypes >= work->proctypevec_size) + { + if (!work->proctypevec_size) + { + work->proctypevec_size = 4; + work->proctypevec = XNEWVEC (int, work->proctypevec_size); + } + else + { + if (work->proctypevec_size < 16) + /* Double when small. */ + work->proctypevec_size *= 2; + else + { + /* Grow slower when large. */ + if (work->proctypevec_size > (INT_MAX / 3) * 2) + xmalloc_failed (INT_MAX); + work->proctypevec_size = (work->proctypevec_size * 3 / 2); + } + work->proctypevec + = XRESIZEVEC (int, work->proctypevec, work->proctypevec_size); + } + } + work->proctypevec [work->nproctypes++] = typevec_index; +} + +static void +pop_processed_type (struct work_stuff *work) +{ + work->nproctypes--; +} + +static void +remember_type (struct work_stuff *work, const char *start, int len) { char *tem; @@ -4243,18 +4388,18 @@ remember_type (work, start, len) if (work -> typevec_size == 0) { work -> typevec_size = 3; - work -> typevec - = (char **) xmalloc (sizeof (char *) * work -> typevec_size); + work -> typevec = XNEWVEC (char *, work->typevec_size); } else { + if (work -> typevec_size > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> typevec_size *= 2; work -> typevec - = (char **) xrealloc ((char *)work -> typevec, - sizeof (char *) * work -> typevec_size); + = XRESIZEVEC (char *, work->typevec, work->typevec_size); } } - tem = xmalloc (len + 1); + tem = XNEWVEC (char, len + 1); memcpy (tem, start, len); tem[len] = '\0'; work -> typevec[work -> ntypes++] = tem; @@ -4263,10 +4408,7 @@ remember_type (work, start, len) /* Remember a K type class qualifier. */ static void -remember_Ktype (work, start, len) - struct work_stuff *work; - const char *start; - int len; +remember_Ktype (struct work_stuff *work, const char *start, int len) { char *tem; @@ -4275,18 +4417,18 @@ remember_Ktype (work, start, len) if (work -> ksize == 0) { work -> ksize = 5; - work -> ktypevec - = (char **) xmalloc (sizeof (char *) * work -> ksize); + work -> ktypevec = XNEWVEC (char *, work->ksize); } else { + if (work -> ksize > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> ksize *= 2; work -> ktypevec - = (char **) xrealloc ((char *)work -> ktypevec, - sizeof (char *) * work -> ksize); + = XRESIZEVEC (char *, work->ktypevec, work->ksize); } } - tem = xmalloc (len + 1); + tem = XNEWVEC (char, len + 1); memcpy (tem, start, len); tem[len] = '\0'; work -> ktypevec[work -> numk++] = tem; @@ -4297,8 +4439,7 @@ remember_Ktype (work, start, len) registers map > as B0, and temp as B1 */ static int -register_Btype (work) - struct work_stuff *work; +register_Btype (struct work_stuff *work) { int ret; @@ -4307,15 +4448,15 @@ register_Btype (work) if (work -> bsize == 0) { work -> bsize = 5; - work -> btypevec - = (char **) xmalloc (sizeof (char *) * work -> bsize); + work -> btypevec = XNEWVEC (char *, work->bsize); } else { + if (work -> bsize > INT_MAX / 2) + xmalloc_failed (INT_MAX); work -> bsize *= 2; work -> btypevec - = (char **) xrealloc ((char *)work -> btypevec, - sizeof (char *) * work -> bsize); + = XRESIZEVEC (char *, work->btypevec, work->bsize); } } ret = work -> numb++; @@ -4326,14 +4467,12 @@ register_Btype (work) /* Store a value into a previously registered B code type. */ static void -remember_Btype (work, start, len, index) - struct work_stuff *work; - const char *start; - int len, index; +remember_Btype (struct work_stuff *work, const char *start, + int len, int index) { char *tem; - tem = xmalloc (len + 1); + tem = XNEWVEC (char, len + 1); memcpy (tem, start, len); tem[len] = '\0'; work -> btypevec[index] = tem; @@ -4341,8 +4480,7 @@ remember_Btype (work, start, len, index) /* Lose all the info related to B and K type codes. */ static void -forget_B_and_K_types (work) - struct work_stuff *work; +forget_B_and_K_types (struct work_stuff *work) { int i; @@ -4369,8 +4507,7 @@ forget_B_and_K_types (work) /* Forget the remembered types, but not the type vector itself. */ static void -forget_types (work) - struct work_stuff *work; +forget_types (struct work_stuff *work) { int i; @@ -4428,10 +4565,8 @@ forget_types (work) */ static int -demangle_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; +demangle_args (struct work_stuff *work, const char **mangled, + string *declp) { string arg; int need_comma = 0; @@ -4504,10 +4639,13 @@ demangle_args (work, mangled, declp) { string_append (declp, ", "); } + push_processed_type (work, t); if (!do_arg (work, &tem, &arg)) { + pop_processed_type (work); return (0); } + pop_processed_type (work); if (PRINT_ARG_TYPES) { string_appends (declp, &arg); @@ -4553,10 +4691,8 @@ demangle_args (work, mangled, declp) and method pointers or references, not top-level declarations. */ static int -demangle_nested_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; +demangle_nested_args (struct work_stuff *work, const char **mangled, + string *declp) { string* saved_previous_argument; int result; @@ -4591,12 +4727,11 @@ demangle_nested_args (work, mangled, declp) return result; } -static void -demangle_function_name (work, mangled, declp, scan) - struct work_stuff *work; - const char **mangled; - string *declp; - const char *scan; +/* Returns 1 if a valid function name was found or 0 otherwise. */ + +static int +demangle_function_name (struct work_stuff *work, const char **mangled, + string *declp, const char *scan) { size_t i; string type; @@ -4634,13 +4769,13 @@ demangle_function_name (work, mangled, declp, scan) { work -> constructor += 1; string_clear (declp); - return; + return 1; } else if (strcmp (declp -> b, "__dt") == 0) { work -> destructor += 1; string_clear (declp); - return; + return 1; } } @@ -4748,14 +4883,19 @@ demangle_function_name (work, mangled, declp, scan) } } } + + /* If a function name was obtained but it's not valid, we were not + successful. */ + if (LEN_STRING (declp) == 1 && declp->b[0] == '.') + return 0; + else + return 1; } /* a mini string-handling package */ static void -string_need (s, n) - string *s; - int n; +string_need (string *s, int n) { int tem; @@ -4765,23 +4905,24 @@ string_need (s, n) { n = 32; } - s->p = s->b = xmalloc (n); + s->p = s->b = XNEWVEC (char, n); s->e = s->b + n; } else if (s->e - s->p < n) { tem = s->p - s->b; + if (n > INT_MAX / 2 - tem) + xmalloc_failed (INT_MAX); n += tem; n *= 2; - s->b = xrealloc (s->b, n); + s->b = XRESIZEVEC (char, s->b, n); s->p = s->b + tem; s->e = s->b + n; } } static void -string_delete (s) - string *s; +string_delete (string *s) { if (s->b != NULL) { @@ -4791,15 +4932,13 @@ string_delete (s) } static void -string_init (s) - string *s; +string_init (string *s) { s->b = s->p = s->e = NULL; } static void -string_clear (s) - string *s; +string_clear (string *s) { s->p = s->b; } @@ -4807,8 +4946,7 @@ string_clear (s) #if 0 static int -string_empty (s) - string *s; +string_empty (string *s) { return (s->b == s->p); } @@ -4816,9 +4954,7 @@ string_empty (s) #endif static void -string_append (p, s) - string *p; - const char *s; +string_append (string *p, const char *s) { int n; if (s == NULL || *s == '\0') @@ -4830,8 +4966,7 @@ string_append (p, s) } static void -string_appends (p, s) - string *p, *s; +string_appends (string *p, string *s) { int n; @@ -4845,10 +4980,7 @@ string_appends (p, s) } static void -string_appendn (p, s, n) - string *p; - const char *s; - int n; +string_appendn (string *p, const char *s, int n) { if (n != 0) { @@ -4859,9 +4991,7 @@ string_appendn (p, s, n) } static void -string_prepend (p, s) - string *p; - const char *s; +string_prepend (string *p, const char *s) { if (s != NULL && *s != '\0') { @@ -4870,8 +5000,7 @@ string_prepend (p, s) } static void -string_prepends (p, s) - string *p, *s; +string_prepends (string *p, string *s) { if (s->b != s->p) { @@ -4880,10 +5009,7 @@ string_prepends (p, s) } static void -string_prependn (p, s, n) - string *p; - const char *s; - int n; +string_prependn (string *p, const char *s, int n) { char *q; @@ -4900,9 +5026,7 @@ string_prependn (p, s, n) } static void -string_append_template_idx (s, idx) - string *s; - int idx; +string_append_template_idx (string *s, int idx) { char buf[INTBUF_SIZE + 1 /* 'T' */]; sprintf(buf, "T%d", idx);