Demangling fixes

This commit is contained in:
Daniel Berlin 2000-07-24 19:14:18 +00:00
parent 7b92f6e1a2
commit e8865c2811
2 changed files with 248 additions and 31 deletions

View File

@ -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>
Jeff Law <law@cygnus.com>

View File

@ -317,12 +317,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 *));
@ -428,6 +437,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));
@ -981,16 +994,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
= 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);
@ -1017,6 +1099,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. */
@ -1242,7 +1348,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;
@ -1276,7 +1382,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,
@ -1521,6 +1627,11 @@ demangle_integral_value (work, mangled, s)
{
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;
/* Negative numbers are indicated with a leading `m'. */
@ -1529,17 +1640,49 @@ demangle_integral_value (work, mangled, s)
string_appendn (s, "-", 1);
(*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;
}
/* 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);
/* Read the rest of the number. */
value = consume_count_with_underscores (mangled);
if (value != -1)
{
char buf[INTBUF_SIZE];
sprintf (buf, "%d", value);
string_append (s, buf);
/* If the next character is an underscore, skip it. */
if (**mangled == '_')
/* 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 || consume_following_underscore)
&& ! leave_following_underscore
&& **mangled == '_')
(*mangled)++;
/* 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
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
@ -2236,6 +2379,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
|| 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
@ -2251,6 +2474,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
@ -2424,29 +2649,16 @@ demangle_prefix (work, mangled, declp)
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
{