Various fixes to cplus_demangle(); see ChangeLog.

This commit is contained in:
Per Bothner
1992-04-29 22:32:12 +00:00
parent b96a430e09
commit f536aa3956
2 changed files with 105 additions and 57 deletions

View File

@ -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) Fri Apr 24 07:41:19 1992 Stu Grossman (grossman at cygnus.com)
* Makefile.in (make-proto-gdb-1): 1st cut at packaging * Makefile.in (make-proto-gdb-1): 1st cut at packaging

View File

@ -78,9 +78,15 @@ extern char *cplus_demangle (const char *type, int mode);
extern char *cplus_demangle (); extern char *cplus_demangle ();
#endif #endif
static char **typevec = 0; /* Stuff that is shared betwen sub-routines.
static int ntypes = 0; * Using a shared structure allows cplus_demange to be reentrant. */
static int typevec_size = 0;
struct work_stuff {
int arg_mode;
char **typevec;
int ntypes;
int typevec_size;
};
const static struct optable { const static struct optable {
const char *in; const char *in;
@ -204,19 +210,19 @@ static int
get_count PARAMS ((const char **, int *)); get_count PARAMS ((const char **, int *));
static int static int
do_args PARAMS ((const char **, string *, int)); do_args PARAMS ((const char **, string *, struct work_stuff *));
static int static int
do_type PARAMS ((const char **, string *, int)); do_type PARAMS ((const char **, string *, struct work_stuff *));
static int static int
do_arg PARAMS ((const char **, string *, int)); do_arg PARAMS ((const char **, string *, struct work_stuff*));
static void static void
munge_function_name PARAMS ((string *, int)); munge_function_name PARAMS ((string *, struct work_stuff*));
static void static void
remember_type PARAMS ((const char *, int)); remember_type PARAMS ((const char *, int, struct work_stuff *));
#if 0 #if 0
static void static void
@ -262,13 +268,14 @@ cplus_demangle (type, arg_mode)
int static_type = 0; int static_type = 0;
int const_flag = 0; int const_flag = 0;
int i; int i;
struct work_stuff work[1];
const char *p; const char *p;
#ifndef LONGERNAMES #ifndef LONGERNAMES
const char *premangle; const char *premangle;
#endif #endif
# define print_ansi_qualifiers (arg_mode > 0) # define print_ansi_qualifiers (work->arg_mode > 0)
# define print_arg_types (arg_mode >= 0) # define print_arg_types (work->arg_mode >= 0)
if (type == NULL || *type == '\0') if (type == NULL || *type == '\0')
return NULL; return NULL;
@ -276,6 +283,12 @@ cplus_demangle (type, arg_mode)
if (*type++ != '_') if (*type++ != '_')
return NULL; return NULL;
#endif #endif
work->arg_mode = arg_mode;
work->typevec = NULL;
work->ntypes = 0;
work->typevec_size = 0;
p = type; p = type;
while (*p != '\0' && !(*p == '_' && p[1] == '_')) while (*p != '\0' && !(*p == '_' && p[1] == '_'))
p++; p++;
@ -344,7 +357,7 @@ cplus_demangle (type, arg_mode)
string_appendn (&decl, type, p - type); string_appendn (&decl, type, p - type);
string_need (&decl, 1); string_need (&decl, 1);
*(decl.p) = '\0'; *(decl.p) = '\0';
munge_function_name (&decl, 1); munge_function_name (&decl, work); /* arg_mode=1 ?? */
if (decl.b[0] == '_') if (decl.b[0] == '_')
{ {
string_delete (&decl); string_delete (&decl);
@ -364,7 +377,7 @@ cplus_demangle (type, arg_mode)
string_appendn (&decl, type, p - type); string_appendn (&decl, type, p - type);
string_need (&decl, 1); string_need (&decl, 1);
*(decl.p) = '\0'; *(decl.p) = '\0';
munge_function_name (&decl, arg_mode); munge_function_name (&decl, work);
p += 2; p += 2;
} }
@ -373,6 +386,32 @@ cplus_demangle (type, arg_mode)
#endif #endif
switch (*p) 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': case 'C':
/* a const member function */ /* a const member function */
if (!isdigit (p[1])) if (!isdigit (p[1]))
@ -421,8 +460,9 @@ cplus_demangle (type, arg_mode)
} }
p += n; p += n;
#ifndef LONGERNAMES #ifndef LONGERNAMES
remember_type (premangle, p - premangle); remember_type (premangle, p - premangle, work);
#endif #endif
do_method_args:
if (static_type) if (static_type)
{ {
string_append(&decl, p+1); string_append(&decl, p+1);
@ -430,13 +470,13 @@ cplus_demangle (type, arg_mode)
success = 1; success = 1;
} }
else else
success = do_args (&p, &decl, arg_mode); success = do_args (&p, &decl, work);
if (const_flag && print_arg_types) if (const_flag && print_arg_types)
string_append (&decl, " const"); string_append (&decl, " const");
break; break;
case 'F': case 'F':
p += 1; p += 1;
success = do_args (&p, &decl, arg_mode); success = do_args (&p, &decl, work);
break; break;
/* template additions */ /* template additions */
case 't': case 't':
@ -472,7 +512,7 @@ cplus_demangle (type, arg_mode)
{ {
p += 1; p += 1;
success = do_type (&p, &temp, arg_mode); success = do_type (&p, &temp, work);
string_appendn (&temp, "", 1); string_appendn (&temp, "", 1);
if (success) if (success)
string_append (&tname, temp.b); string_append (&tname, temp.b);
@ -489,7 +529,7 @@ cplus_demangle (type, arg_mode)
int is_integral = 0; int is_integral = 0;
int done = 0; int done = 0;
success = do_type (&p, &temp, arg_mode); success = do_type (&p, &temp, work);
string_appendn (&temp, "", 1); string_appendn (&temp, "", 1);
if (success) if (success)
string_append (&tname, temp.b); string_append (&tname, temp.b);
@ -620,21 +660,16 @@ cplus_demangle (type, arg_mode)
success = 1; success = 1;
} }
else else
success = do_args (&p, &decl, arg_mode); success = do_args (&p, &decl, work);
break; break;
} }
} }
for (i = 0; i < ntypes; i++) for (i = 0; i < work->ntypes; i++)
if (typevec[i] != NULL) if (work->typevec[i] != NULL)
free (typevec[i]); free (work->typevec[i]);
ntypes = 0; if (work->typevec != NULL)
if (typevec != NULL) free ((char *)work->typevec);
{
free ((char *)typevec);
typevec = NULL;
typevec_size = 0;
}
if (success) if (success)
{ {
@ -681,10 +716,10 @@ get_count (type, count)
/* result will be initialised here; it will be freed on failure */ /* result will be initialised here; it will be freed on failure */
static int static int
do_type (type, result, arg_mode) do_type (type, result, work)
const char **type; const char **type;
string *result; string *result;
int arg_mode; struct work_stuff *work;
{ {
int n; int n;
int done; int done;
@ -707,9 +742,11 @@ do_type (type, result, arg_mode)
n = (*type)[1] - '0'; n = (*type)[1] - '0';
if (n < 0 || n > 9) if (n < 0 || n > 9)
success = 0; success = 0;
if ((*type)[2] == '_') /* cfront style */
*type += 1;
*type += 2; *type += 2;
while (n-- > 0) while (n-- > 0)
do_type (type, result, arg_mode); do_type (type, result, work);
break; break;
case 'P': case 'P':
@ -724,11 +761,11 @@ do_type (type, result, arg_mode)
case 'T': case 'T':
*type += 1; *type += 1;
if (!get_count (type, &n) || n >= ntypes) if (!get_count (type, &n) || n >= work->ntypes)
success = 0; success = 0;
else else
{ {
remembered_type = typevec[n]; remembered_type = work->typevec[n];
type = &remembered_type; type = &remembered_type;
} }
break; break;
@ -740,7 +777,7 @@ do_type (type, result, arg_mode)
string_prepend (&decl, "("); string_prepend (&decl, "(");
string_append (&decl, ")"); string_append (&decl, ")");
} }
if (!do_args (type, &decl, arg_mode) || **type != '_') if (!do_args (type, &decl, work) || **type != '_')
success = 0; success = 0;
else else
*type += 1; *type += 1;
@ -795,7 +832,7 @@ do_type (type, result, arg_mode)
break; break;
} }
} }
if ((member && !do_args (type, &decl, arg_mode)) || **type != '_') if ((member && !do_args (type, &decl, work)) || **type != '_')
{ {
success = 0; success = 0;
break; break;
@ -1014,53 +1051,54 @@ do_type (type, result, arg_mode)
/* `result' will be initialised in do_type; it will be freed on failure */ /* `result' will be initialised in do_type; it will be freed on failure */
static int static int
do_arg (type, result, arg_mode) do_arg (type, result, work)
const char **type; const char **type;
string *result; string *result;
int arg_mode; struct work_stuff *work;
{ {
const char *start = *type; const char *start = *type;
if (!do_type (type, result, arg_mode)) if (!do_type (type, result, work))
return 0; return 0;
remember_type (start, *type - start); remember_type (start, *type - start, work);
return 1; return 1;
} }
static void static void
remember_type (start, len) remember_type (start, len, work)
const char *start; const char *start;
int len; int len;
struct work_stuff *work;
{ {
char *tem; char *tem;
if (ntypes >= typevec_size) if (work->ntypes >= work->typevec_size)
{ {
if (typevec_size == 0) if (work->typevec_size == 0)
{ {
typevec_size = 3; work->typevec_size = 3;
typevec = (char **) xmalloc (sizeof (char*)*typevec_size); work->typevec = (char **) xmalloc (sizeof (char*)*work->typevec_size);
} }
else else
{ {
typevec_size *= 2; work->typevec_size *= 2;
typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size); work->typevec = (char **) xrealloc ((char *)work->typevec, sizeof (char*)*work->typevec_size);
} }
} }
tem = (char *) xmalloc (len + 1); tem = (char *) xmalloc (len + 1);
memcpy (tem, start, len); memcpy (tem, start, len);
tem[len] = '\0'; tem[len] = '\0';
typevec[ntypes++] = tem; work->typevec[work->ntypes++] = tem;
} }
/* `decl' must be already initialised, usually non-empty; /* `decl' must be already initialised, usually non-empty;
it won't be freed on failure */ it won't be freed on failure */
static int static int
do_args (type, decl, arg_mode) do_args (type, decl, work)
const char **type; const char **type;
string *decl; string *decl;
int arg_mode; struct work_stuff *work;
{ {
string arg; string arg;
int need_comma = 0; int need_comma = 0;
@ -1075,14 +1113,14 @@ do_args (type, decl, arg_mode)
int r; int r;
int t; int t;
*type += 1; *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; return 0;
while (--r >= 0) while (--r >= 0)
{ {
const char *tem = typevec[t]; const char *tem = work->typevec[t];
if (need_comma && print_arg_types) if (need_comma && print_arg_types)
string_append (decl, ", "); string_append (decl, ", ");
if (!do_arg (&tem, &arg, arg_mode)) if (!do_arg (&tem, &arg, work))
return 0; return 0;
if (print_arg_types) if (print_arg_types)
string_appends (decl, &arg); string_appends (decl, &arg);
@ -1094,7 +1132,7 @@ do_args (type, decl, arg_mode)
{ {
if (need_comma & print_arg_types) if (need_comma & print_arg_types)
string_append (decl, ", "); string_append (decl, ", ");
if (!do_arg (type, &arg, arg_mode)) if (!do_arg (type, &arg, work))
return 0; return 0;
if (print_arg_types) if (print_arg_types)
string_appends (decl, &arg); string_appends (decl, &arg);
@ -1122,9 +1160,9 @@ do_args (type, decl, arg_mode)
} }
static void static void
munge_function_name (name, arg_mode) munge_function_name (name, work)
string *name; string *name;
int arg_mode; struct work_stuff *work;
{ {
if (string_empty (name)) if (string_empty (name))
return; return;
@ -1173,7 +1211,7 @@ munge_function_name (name, arg_mode)
/* type conversion operator */ /* type conversion operator */
string type; string type;
const char *tem = name->b + 5; const char *tem = name->b + 5;
if (do_type (&tem, &type, arg_mode)) if (do_type (&tem, &type, work))
{ {
string_clear (name); string_clear (name);
string_append (name, "operator "); string_append (name, "operator ");
@ -1188,7 +1226,7 @@ munge_function_name (name, arg_mode)
/* type conversion operator. */ /* type conversion operator. */
string type; string type;
const char *tem = name->b + 4; const char *tem = name->b + 4;
if (do_type (&tem, &type, arg_mode)) if (do_type (&tem, &type, work))
{ {
string_clear (name); string_clear (name);
string_append (name, "operator "); string_append (name, "operator ");