Demangling fixes
This commit is contained in:
parent
7b92f6e1a2
commit
e8865c2811
2 changed files with 248 additions and 31 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
2000-07-24 Daniel Berlin <dberlin@redhat.com>
|
||||||
|
|
||||||
|
* cplus-dem.c (demangle_signature): Change if (GNU_DEMANGLING) to
|
||||||
|
if (AUTO_DEMANGLING || GNU_DEMANGLING)
|
||||||
|
|
||||||
2000-07-23 Michael Sokolov <msokolov@ivan.Harhan.ORG>
|
2000-07-23 Michael Sokolov <msokolov@ivan.Harhan.ORG>
|
||||||
Jeff Law <law@cygnus.com>
|
Jeff Law <law@cygnus.com>
|
||||||
|
|
||||||
|
|
|
@ -317,12 +317,21 @@ struct demangler_engine libiberty_demanglers[] =
|
||||||
|
|
||||||
/* Prototypes for local functions */
|
/* 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 *
|
static char *
|
||||||
mop_up PARAMS ((struct work_stuff *, string *, int));
|
mop_up PARAMS ((struct work_stuff *, string *, int));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
squangle_mop_up PARAMS ((struct work_stuff *));
|
squangle_mop_up PARAMS ((struct work_stuff *));
|
||||||
|
|
||||||
|
static void
|
||||||
|
work_stuff_copy_to_from PARAMS ((struct work_stuff *, struct work_stuff *));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static int
|
static int
|
||||||
demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
|
demangle_method_args PARAMS ((struct work_stuff *, const char **, string *));
|
||||||
|
@ -428,6 +437,10 @@ static void
|
||||||
demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
|
demangle_function_name PARAMS ((struct work_stuff *, const char **, string *,
|
||||||
const char *));
|
const char *));
|
||||||
|
|
||||||
|
static int
|
||||||
|
iterate_demangle_function PARAMS ((struct work_stuff *,
|
||||||
|
const char **, string *, const char *));
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remember_type PARAMS ((struct work_stuff *, const char *, int));
|
remember_type PARAMS ((struct work_stuff *, const char *, int));
|
||||||
|
|
||||||
|
@ -981,16 +994,85 @@ squangle_mop_up (work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear out any mangled storage */
|
|
||||||
|
|
||||||
static char *
|
/* Copy the work state and storage. */
|
||||||
mop_up (work, declp, success)
|
|
||||||
struct work_stuff *work;
|
static void
|
||||||
string *declp;
|
work_stuff_copy_to_from (to, from)
|
||||||
int success;
|
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
|
||||||
|
= 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. */
|
/* Discard the remembered types, if any. */
|
||||||
|
|
||||||
forget_types (work);
|
forget_types (work);
|
||||||
|
@ -1017,6 +1099,30 @@ mop_up (work, declp, success)
|
||||||
free ((char*) work->previous_argument);
|
free ((char*) work->previous_argument);
|
||||||
work->previous_argument = NULL;
|
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
|
/* If demangling was successful, ensure that the demangled string is null
|
||||||
terminated and return it. Otherwise, free the demangling decl. */
|
terminated and return it. Otherwise, free the demangling decl. */
|
||||||
|
@ -1242,7 +1348,7 @@ demangle_signature (work, mangled, declp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '_':
|
case '_':
|
||||||
if (GNU_DEMANGLING && expect_return_type)
|
if ((AUTO_DEMANGLING || GNU_DEMANGLING) && expect_return_type)
|
||||||
{
|
{
|
||||||
/* Read the return type. */
|
/* Read the return type. */
|
||||||
string return_type;
|
string return_type;
|
||||||
|
@ -1276,7 +1382,7 @@ demangle_signature (work, mangled, declp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'H':
|
case 'H':
|
||||||
if (GNU_DEMANGLING)
|
if (AUTO_DEMANGLING || GNU_DEMANGLING)
|
||||||
{
|
{
|
||||||
/* A G++ template function. Read the template arguments. */
|
/* A G++ template function. Read the template arguments. */
|
||||||
success = demangle_template (work, mangled, declp, 0, 0,
|
success = demangle_template (work, mangled, declp, 0, 0,
|
||||||
|
@ -1521,6 +1627,11 @@ demangle_integral_value (work, mangled, s)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
|
/* By default, we let the number decide whether we shall consume an
|
||||||
|
underscore. */
|
||||||
|
int consume_following_underscore = 0;
|
||||||
|
int leave_following_underscore = 0;
|
||||||
|
|
||||||
success = 0;
|
success = 0;
|
||||||
|
|
||||||
/* Negative numbers are indicated with a leading `m'. */
|
/* Negative numbers are indicated with a leading `m'. */
|
||||||
|
@ -1529,17 +1640,49 @@ demangle_integral_value (work, mangled, s)
|
||||||
string_appendn (s, "-", 1);
|
string_appendn (s, "-", 1);
|
||||||
(*mangled)++;
|
(*mangled)++;
|
||||||
}
|
}
|
||||||
|
else if (mangled[0][0] == '_' && mangled[0][1] == 'm')
|
||||||
|
{
|
||||||
|
/* 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. */
|
||||||
|
consume_following_underscore = 1;
|
||||||
|
string_appendn (s, "-", 1);
|
||||||
|
(*mangled) += 2;
|
||||||
|
}
|
||||||
|
else if (**mangled == '_')
|
||||||
|
{
|
||||||
|
/* Do not consume a following underscore;
|
||||||
|
consume_following_underscore will consume what should be
|
||||||
|
consumed. */
|
||||||
|
leave_following_underscore = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Read the rest of the number. */
|
/* 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 (consume_following_underscore)
|
||||||
|
value = consume_count (mangled);
|
||||||
|
else
|
||||||
value = consume_count_with_underscores (mangled);
|
value = consume_count_with_underscores (mangled);
|
||||||
|
|
||||||
if (value != -1)
|
if (value != -1)
|
||||||
{
|
{
|
||||||
char buf[INTBUF_SIZE];
|
char buf[INTBUF_SIZE];
|
||||||
sprintf (buf, "%d", value);
|
sprintf (buf, "%d", value);
|
||||||
string_append (s, buf);
|
string_append (s, buf);
|
||||||
|
|
||||||
/* If the next character is an underscore, skip it. */
|
/* Numbers not otherwise delimited, might have an underscore
|
||||||
if (**mangled == '_')
|
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 || consume_following_underscore)
|
||||||
|
&& ! leave_following_underscore
|
||||||
|
&& **mangled == '_')
|
||||||
(*mangled)++;
|
(*mangled)++;
|
||||||
|
|
||||||
/* All is well. */
|
/* All is well. */
|
||||||
|
@ -1704,7 +1847,7 @@ demangle_template_value_parm (work, mangled, s, tk)
|
||||||
template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is
|
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,
|
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,
|
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. */
|
types. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -2236,6 +2379,86 @@ demangle_class (work, mangled, declp)
|
||||||
return (success);
|
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
|
||||||
|
|| mystrstr (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
|
LOCAL FUNCTION
|
||||||
|
@ -2251,6 +2474,8 @@ SYNOPSIS
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
|
||||||
Consume and demangle the prefix of the mangled name.
|
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
|
DECLP points to the string buffer into which demangled output is
|
||||||
placed. On entry, the buffer is empty. On exit it contains
|
placed. On entry, the buffer is empty. On exit it contains
|
||||||
|
@ -2424,29 +2649,16 @@ demangle_prefix (work, mangled, declp)
|
||||||
success = 0;
|
success = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
return iterate_demangle_function (work, mangled, declp, scan);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*(scan + 2) != '\0')
|
else if (*(scan + 2) != '\0')
|
||||||
{
|
{
|
||||||
/* Mangled name does not start with "__" but does have one somewhere
|
/* Mangled name does not start with "__" but does have one somewhere
|
||||||
in there with non empty stuff after it. Looks like a global
|
in there with non empty stuff after it. Looks like a global
|
||||||
function name. */
|
function name. Iterate over all "__":s until the right
|
||||||
demangle_function_name (work, mangled, declp, scan);
|
one is found. */
|
||||||
|
return iterate_demangle_function (work, mangled, declp, scan);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue