From: Per Bothner Date: Wed, 29 Apr 1992 22:32:12 +0000 (+0000) Subject: Various fixes to cplus_demangle(); see ChangeLog. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f536aa3956bee24a6b3c5d0cd5c78d84f8492b38;p=binutils-gdb.git Various fixes to cplus_demangle(); see ChangeLog. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a726a9ff29d..cff4c1a9304 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +Wed Apr 29 15:26:51 1992 Per Bothner (bothner@rtl.cygnus.com) + + * cplus-dem.c: Allow nested class names (as in + Foo::Bar::method()). + Allow the cleaner cfront style of nested class names + (Q2_3Foo3Bar as well as Q23Foo3Bar). + Make cplus_demangle re-entrant by removing use of global + variables. Instead, place all shared variables in a + stack-allocated structure, and pass around its address. + Fri Apr 24 07:41:19 1992 Stu Grossman (grossman at cygnus.com) * Makefile.in (make-proto-gdb-1): 1st cut at packaging diff --git a/gdb/cplus-dem.c b/gdb/cplus-dem.c index bc3b27c9b7f..d42c8b7b1ab 100644 --- a/gdb/cplus-dem.c +++ b/gdb/cplus-dem.c @@ -78,9 +78,15 @@ extern char *cplus_demangle (const char *type, int mode); extern char *cplus_demangle (); #endif -static char **typevec = 0; -static int ntypes = 0; -static int typevec_size = 0; +/* Stuff that is shared betwen sub-routines. + * Using a shared structure allows cplus_demange to be reentrant. */ + +struct work_stuff { + int arg_mode; + char **typevec; + int ntypes; + int typevec_size; +}; const static struct optable { const char *in; @@ -204,19 +210,19 @@ static int get_count PARAMS ((const char **, int *)); static int -do_args PARAMS ((const char **, string *, int)); +do_args PARAMS ((const char **, string *, struct work_stuff *)); static int -do_type PARAMS ((const char **, string *, int)); +do_type PARAMS ((const char **, string *, struct work_stuff *)); static int -do_arg PARAMS ((const char **, string *, int)); +do_arg PARAMS ((const char **, string *, struct work_stuff*)); static void -munge_function_name PARAMS ((string *, int)); +munge_function_name PARAMS ((string *, struct work_stuff*)); static void -remember_type PARAMS ((const char *, int)); +remember_type PARAMS ((const char *, int, struct work_stuff *)); #if 0 static void @@ -262,13 +268,14 @@ cplus_demangle (type, arg_mode) int static_type = 0; int const_flag = 0; int i; + struct work_stuff work[1]; const char *p; #ifndef LONGERNAMES const char *premangle; #endif -# define print_ansi_qualifiers (arg_mode > 0) -# define print_arg_types (arg_mode >= 0) +# define print_ansi_qualifiers (work->arg_mode > 0) +# define print_arg_types (work->arg_mode >= 0) if (type == NULL || *type == '\0') return NULL; @@ -276,6 +283,12 @@ cplus_demangle (type, arg_mode) if (*type++ != '_') return NULL; #endif + + work->arg_mode = arg_mode; + work->typevec = NULL; + work->ntypes = 0; + work->typevec_size = 0; + p = type; while (*p != '\0' && !(*p == '_' && p[1] == '_')) p++; @@ -344,7 +357,7 @@ cplus_demangle (type, arg_mode) string_appendn (&decl, type, p - type); string_need (&decl, 1); *(decl.p) = '\0'; - munge_function_name (&decl, 1); + munge_function_name (&decl, work); /* arg_mode=1 ?? */ if (decl.b[0] == '_') { string_delete (&decl); @@ -364,7 +377,7 @@ cplus_demangle (type, arg_mode) string_appendn (&decl, type, p - type); string_need (&decl, 1); *(decl.p) = '\0'; - munge_function_name (&decl, arg_mode); + munge_function_name (&decl, work); p += 2; } @@ -373,6 +386,32 @@ cplus_demangle (type, arg_mode) #endif switch (*p) { + string class; + case 'Q': + string_init (&class); + n = p[1] - '0'; + if (n < 0 || n > 9) + success = 0; + if (p[2] == '_') /* cfront style */ + p += 1; + p += 2; + while (n-- > 0) + { + string tmp; + do_type (&p, &tmp, work); + string_appends (&class, &tmp); + string_append (&class, "::"); + if (n == 0 && (constructor || destructor)) + { + if (destructor) + string_append(&class, "~"); + string_appends (&class, &tmp); + } + string_delete (&tmp); + } + string_prependn (&decl, class.b, class.p - class.b); + string_delete (&class); + goto do_method_args; case 'C': /* a const member function */ if (!isdigit (p[1])) @@ -421,8 +460,9 @@ cplus_demangle (type, arg_mode) } p += n; #ifndef LONGERNAMES - remember_type (premangle, p - premangle); + remember_type (premangle, p - premangle, work); #endif + do_method_args: if (static_type) { string_append(&decl, p+1); @@ -430,13 +470,13 @@ cplus_demangle (type, arg_mode) success = 1; } else - success = do_args (&p, &decl, arg_mode); + success = do_args (&p, &decl, work); if (const_flag && print_arg_types) string_append (&decl, " const"); break; case 'F': p += 1; - success = do_args (&p, &decl, arg_mode); + success = do_args (&p, &decl, work); break; /* template additions */ case 't': @@ -472,7 +512,7 @@ cplus_demangle (type, arg_mode) { p += 1; - success = do_type (&p, &temp, arg_mode); + success = do_type (&p, &temp, work); string_appendn (&temp, "", 1); if (success) string_append (&tname, temp.b); @@ -489,7 +529,7 @@ cplus_demangle (type, arg_mode) int is_integral = 0; int done = 0; - success = do_type (&p, &temp, arg_mode); + success = do_type (&p, &temp, work); string_appendn (&temp, "", 1); if (success) string_append (&tname, temp.b); @@ -620,21 +660,16 @@ cplus_demangle (type, arg_mode) success = 1; } else - success = do_args (&p, &decl, arg_mode); + success = do_args (&p, &decl, work); break; } } - for (i = 0; i < ntypes; i++) - if (typevec[i] != NULL) - free (typevec[i]); - ntypes = 0; - if (typevec != NULL) - { - free ((char *)typevec); - typevec = NULL; - typevec_size = 0; - } + for (i = 0; i < work->ntypes; i++) + if (work->typevec[i] != NULL) + free (work->typevec[i]); + if (work->typevec != NULL) + free ((char *)work->typevec); if (success) { @@ -681,10 +716,10 @@ get_count (type, count) /* result will be initialised here; it will be freed on failure */ static int -do_type (type, result, arg_mode) +do_type (type, result, work) const char **type; string *result; - int arg_mode; + struct work_stuff *work; { int n; int done; @@ -707,9 +742,11 @@ do_type (type, result, arg_mode) n = (*type)[1] - '0'; if (n < 0 || n > 9) success = 0; + if ((*type)[2] == '_') /* cfront style */ + *type += 1; *type += 2; while (n-- > 0) - do_type (type, result, arg_mode); + do_type (type, result, work); break; case 'P': @@ -724,11 +761,11 @@ do_type (type, result, arg_mode) case 'T': *type += 1; - if (!get_count (type, &n) || n >= ntypes) + if (!get_count (type, &n) || n >= work->ntypes) success = 0; else { - remembered_type = typevec[n]; + remembered_type = work->typevec[n]; type = &remembered_type; } break; @@ -740,7 +777,7 @@ do_type (type, result, arg_mode) string_prepend (&decl, "("); string_append (&decl, ")"); } - if (!do_args (type, &decl, arg_mode) || **type != '_') + if (!do_args (type, &decl, work) || **type != '_') success = 0; else *type += 1; @@ -795,7 +832,7 @@ do_type (type, result, arg_mode) break; } } - if ((member && !do_args (type, &decl, arg_mode)) || **type != '_') + if ((member && !do_args (type, &decl, work)) || **type != '_') { success = 0; break; @@ -1014,53 +1051,54 @@ do_type (type, result, arg_mode) /* `result' will be initialised in do_type; it will be freed on failure */ static int -do_arg (type, result, arg_mode) +do_arg (type, result, work) const char **type; string *result; - int arg_mode; + struct work_stuff *work; { const char *start = *type; - if (!do_type (type, result, arg_mode)) + if (!do_type (type, result, work)) return 0; - remember_type (start, *type - start); + remember_type (start, *type - start, work); return 1; } static void -remember_type (start, len) +remember_type (start, len, work) const char *start; int len; + struct work_stuff *work; { char *tem; - if (ntypes >= typevec_size) + if (work->ntypes >= work->typevec_size) { - if (typevec_size == 0) + if (work->typevec_size == 0) { - typevec_size = 3; - typevec = (char **) xmalloc (sizeof (char*)*typevec_size); + work->typevec_size = 3; + work->typevec = (char **) xmalloc (sizeof (char*)*work->typevec_size); } else { - typevec_size *= 2; - typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size); + work->typevec_size *= 2; + work->typevec = (char **) xrealloc ((char *)work->typevec, sizeof (char*)*work->typevec_size); } } tem = (char *) xmalloc (len + 1); memcpy (tem, start, len); tem[len] = '\0'; - typevec[ntypes++] = tem; + work->typevec[work->ntypes++] = tem; } /* `decl' must be already initialised, usually non-empty; it won't be freed on failure */ static int -do_args (type, decl, arg_mode) +do_args (type, decl, work) const char **type; string *decl; - int arg_mode; + struct work_stuff *work; { string arg; int need_comma = 0; @@ -1075,14 +1113,14 @@ do_args (type, decl, arg_mode) int r; int t; *type += 1; - if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes) + if (!get_count (type, &r) || !get_count (type, &t) || t >= work->ntypes) return 0; while (--r >= 0) { - const char *tem = typevec[t]; + const char *tem = work->typevec[t]; if (need_comma && print_arg_types) string_append (decl, ", "); - if (!do_arg (&tem, &arg, arg_mode)) + if (!do_arg (&tem, &arg, work)) return 0; if (print_arg_types) string_appends (decl, &arg); @@ -1094,7 +1132,7 @@ do_args (type, decl, arg_mode) { if (need_comma & print_arg_types) string_append (decl, ", "); - if (!do_arg (type, &arg, arg_mode)) + if (!do_arg (type, &arg, work)) return 0; if (print_arg_types) string_appends (decl, &arg); @@ -1122,9 +1160,9 @@ do_args (type, decl, arg_mode) } static void -munge_function_name (name, arg_mode) +munge_function_name (name, work) string *name; - int arg_mode; + struct work_stuff *work; { if (string_empty (name)) return; @@ -1173,7 +1211,7 @@ munge_function_name (name, arg_mode) /* type conversion operator */ string type; const char *tem = name->b + 5; - if (do_type (&tem, &type, arg_mode)) + if (do_type (&tem, &type, work)) { string_clear (name); string_append (name, "operator "); @@ -1188,7 +1226,7 @@ munge_function_name (name, arg_mode) /* type conversion operator. */ string type; const char *tem = name->b + 4; - if (do_type (&tem, &type, arg_mode)) + if (do_type (&tem, &type, work)) { string_clear (name); string_append (name, "operator ");