summaryrefslogtreecommitdiff
path: root/libiberty
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-07-13 10:54:01 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-07-13 10:54:01 +0000
commit9923cc566f10f6f44612351d3e4e73c3cee0e38f (patch)
tree46efcb7a189c30cfd1760ca97a6db3bea02e1dca /libiberty
parentc78ea26788708f5ed39e269f256862a679995f39 (diff)
downloadgcc-9923cc566f10f6f44612351d3e4e73c3cee0e38f.tar.gz
cplus-dem.c: Incorporate changes from GCC version not present in the libiberty version.
* cplus-dem.c: Incorporate changes from GCC version not present in the libiberty version. From-SVN: r21101
Diffstat (limited to 'libiberty')
-rw-r--r--libiberty/ChangeLog5
-rw-r--r--libiberty/cplus-dem.c377
2 files changed, 258 insertions, 124 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index e6a6e45f16d..3695690f3f7 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,8 @@
+1998-07-13 Mark Mitchell <mark@markmitchell.com>
+
+ * cplus-dem.c: Incorporate changes from GCC version not present in
+ the libiberty version.
+
Sat May 30 22:17:13 1998 Mumit Khan <khan@xraylith.wisc.edu>
* configure.in (checkfuncs): Add missing "'".
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index f1ac763984a..c754734f077 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -1,5 +1,5 @@
/* Demangler for GNU C++
- Copyright 1989, 1991, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
+ Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
Written by James Clark (jjc@jclark.uucp)
Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
@@ -94,6 +94,13 @@ set_cplus_marker_for_demangling (ch)
cplus_markers[0] = ch;
}
+typedef struct string /* Beware: these aren't required to be */
+{ /* '\0' terminated. */
+ char *b; /* pointer to start of string */
+ char *p; /* pointer after last character */
+ char *e; /* pointer after end of allocated space */
+} string;
+
/* Stuff that is shared between sub-routines.
Using a shared structure allows cplus_demangle to be reentrant. */
@@ -113,8 +120,14 @@ struct work_stuff
int destructor;
int static_type; /* A static member function */
int const_type; /* A const member function */
+ int volatile_type; /* A volatile member function */
char **tmpl_argvec; /* Template function arguments. */
int ntmpl_args; /* The number of template function arguments. */
+ int forgetting_types; /* Nonzero if we are not remembering the types
+ we see. */
+ string* previous_argument; /* The last function argument demangled. */
+ int nrepeats; /* The number of times to repeat the previous
+ argument. */
};
#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
@@ -208,13 +221,6 @@ static const struct optable
};
-typedef struct string /* Beware: these aren't required to be */
-{ /* '\0' terminated. */
- char *b; /* pointer to start of string */
- char *p; /* pointer after last character */
- char *e; /* pointer after end of allocated space */
-} string;
-
#define STRING_EMPTY(str) ((str) -> b == (str) -> p)
#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \
string_prepend(str, " ");}
@@ -222,6 +228,9 @@ typedef struct string /* Beware: these aren't required to be */
string_append(str, " ");}
#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b))
+/* The scope separator appropriate for the language being demangled. */
+#define SCOPE_STRING(work) "::"
+
#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */
#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */
@@ -247,7 +256,7 @@ demangle_template_template_parm PARAMS ((struct work_stuff *work,
static int
demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
- string *, int));
+ string *, int, int));
static int
arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
@@ -326,6 +335,9 @@ static int
demangle_args PARAMS ((struct work_stuff *, const char **, string *));
static int
+demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*));
+
+static int
do_type PARAMS ((struct work_stuff *, const char **, string *));
static int
@@ -632,12 +644,15 @@ internal_cplus_demangle (work, mangled)
int success = 0;
char *demangled = NULL;
int s1,s2,s3,s4;
+ int saved_volatile_type;
s1 = work->constructor;
s2 = work->destructor;
s3 = work->static_type;
s4 = work->const_type;
+ saved_volatile_type = work->volatile_type;
work->constructor = work->destructor = 0;
work->static_type = work->const_type = 0;
+ work->volatile_type = 0;
if ((mangled != NULL) && (*mangled != '\0'))
{
@@ -678,6 +693,7 @@ internal_cplus_demangle (work, mangled)
work->destructor = s2;
work->static_type = s3;
work->const_type = s4;
+ work->volatile_type = saved_volatile_type;
return (demangled);
}
@@ -728,6 +744,11 @@ mop_up (work, declp, success)
free ((char*) work->tmpl_argvec);
work->tmpl_argvec = NULL;
}
+ if (work->previous_argument)
+ {
+ string_delete (work->previous_argument);
+ free ((char*) work->previous_argument);
+ }
/* If demangling was successful, ensure that the demangled string is null
terminated and return it. Otherwise, free the demangling decl. */
@@ -796,13 +817,9 @@ demangle_signature (work, mangled, declp)
oldmangled = *mangled;
success = demangle_qualified (work, mangled, declp, 1, 0);
if (success)
- {
- remember_type (work, oldmangled, *mangled - oldmangled);
- }
+ remember_type (work, oldmangled, *mangled - oldmangled);
if (AUTO_DEMANGLING || GNU_DEMANGLING)
- {
- expect_func = 1;
- }
+ expect_func = 1;
oldmangled = NULL;
break;
@@ -827,13 +844,16 @@ demangle_signature (work, mangled, declp)
break;
case 'C':
- /* a const member function */
+ case 'V':
+ if (**mangled == 'C')
+ work -> const_type = 1;
+ else
+ work->volatile_type = 1;
+
+ /* a qualified member function */
if (oldmangled == NULL)
- {
- oldmangled = *mangled;
- }
+ oldmangled = *mangled;
(*mangled)++;
- work -> const_type = 1;
break;
case '0': case '1': case '2': case '3': case '4':
@@ -853,7 +873,21 @@ demangle_signature (work, mangled, declp)
}
oldmangled = NULL;
break;
-
+
+ case 'B':
+ {
+ string s;
+ success = do_type (work, mangled, &s);
+ if (success)
+ {
+ string_append (&s, SCOPE_STRING (work));
+ string_prepends (declp, &s);
+ }
+ oldmangled = NULL;
+ expect_func = 1;
+ }
+ break;
+
case 'F':
/* Function */
/* ARM style demangling includes a specific 'F' character after
@@ -885,13 +919,13 @@ demangle_signature (work, mangled, declp)
{
oldmangled = *mangled;
}
- success = demangle_template (work, mangled, &tname, &trawname, 1);
+ success = demangle_template (work, mangled, &tname,
+ &trawname, 1, 1);
if (success)
{
remember_type (work, oldmangled, *mangled - oldmangled);
}
- string_append (&tname, "::");
-
+ string_append(&tname, SCOPE_STRING (work));
string_prepends(declp, &tname);
if (work -> destructor & 1)
{
@@ -938,7 +972,8 @@ demangle_signature (work, mangled, declp)
if (GNU_DEMANGLING)
{
/* A G++ template function. Read the template arguments. */
- success = demangle_template (work, mangled, declp, 0, 0);
+ success = demangle_template (work, mangled, declp, 0, 0,
+ 0);
if (!(work->constructor & 1))
expect_return_type = 1;
(*mangled)++;
@@ -995,13 +1030,12 @@ demangle_signature (work, mangled, declp)
}
}
if (success && work -> static_type && PRINT_ARG_TYPES)
- {
- string_append (declp, " static");
- }
+ string_append (declp, " static");
if (success && work -> const_type && PRINT_ARG_TYPES)
- {
- string_append (declp, " const");
- }
+ string_append (declp, " const");
+ else if (success && work->volatile_type && PRINT_ARG_TYPES)
+ string_append (declp, " volatile");
+
return (success);
}
@@ -1213,12 +1247,10 @@ demangle_template_value_parm (work, mangled, s)
continue;
case 'E': /* expression */
case 'Q': /* qualified name */
- case 'K': /* qualified name */
- done = is_integral = 1;
- break;
- case 'B': /* squangled name */
+ case 'K': /* qualified name */
done = is_integral = 1;
break;
+ case 'B': /* remembered type */
case 'T': /* remembered type */
abort ();
break;
@@ -1362,13 +1394,22 @@ demangle_template_value_parm (work, mangled, s)
return success;
}
+/* Demangle the template name in MANGLED. The full name of the
+ template (e.g., S<int>) is placed in TNAME. The name without the
+ 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
+ types. */
+
static int
-demangle_template (work, mangled, tname, trawname, is_type)
+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;
{
int i;
int r;
@@ -1376,10 +1417,13 @@ demangle_template (work, mangled, tname, trawname, is_type)
int success = 0;
const char *start;
string temp;
+ int bindex;
(*mangled)++;
if (is_type)
{
+ if (remember)
+ bindex = register_Btype (work);
start = *mangled;
/* get template name */
if (**mangled == 'z')
@@ -1392,9 +1436,8 @@ demangle_template (work, mangled, tname, trawname, is_type)
if (idx == -1
|| (work->tmpl_argvec && idx >= work->ntmpl_args)
|| consume_count_with_underscores (mangled) == -1)
- {
- return (0);
- }
+ return (0);
+
if (work->tmpl_argvec)
{
string_append (tname, work->tmpl_argvec[idx]);
@@ -1407,7 +1450,7 @@ demangle_template (work, mangled, tname, trawname, is_type)
sprintf(buf, "T%d", idx);
string_append (tname, buf);
if (trawname)
- string_append (trawname, work->tmpl_argvec[idx]);
+ string_append (trawname, buf);
}
}
else
@@ -1416,13 +1459,13 @@ demangle_template (work, mangled, tname, trawname, is_type)
{
return (0);
}
+ string_appendn (tname, *mangled, r);
if (trawname)
string_appendn (trawname, *mangled, r);
- string_appendn (tname, *mangled, r);
*mangled += r;
}
}
- string_append (tname, "<");
+ string_append (tname, "<");
/* get size of template parameter list */
if (!get_count (mangled, &r))
{
@@ -1549,12 +1592,13 @@ demangle_template (work, mangled, tname, trawname, is_type)
}
need_comma = 1;
}
- {
- if (tname->p[-1] == '>')
- string_append (tname, " ");
- string_append (tname, ">");
- }
+ if (tname->p[-1] == '>')
+ string_append (tname, " ");
+ string_append (tname, ">");
+ if (is_type && remember)
+ remember_Btype (work, tname->b, LEN_STRING (tname), bindex);
+
/*
if (work -> static_type)
{
@@ -1712,7 +1756,7 @@ demangle_class (work, mangled, declp)
}
remember_Ktype (work, class_name.b, LEN_STRING(&class_name));
remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype);
- string_prepend (declp, "::");
+ string_prepend (declp, SCOPE_STRING (work));
string_prepends (declp, &class_name);
success = 1;
}
@@ -1986,7 +2030,8 @@ gnu_special (work, mangled, declp)
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
- success = demangle_template (work, mangled, declp, 0, 1);
+ success = demangle_template (work, mangled, declp, 0, 1,
+ 1);
break;
default:
if (isdigit(*mangled[0]))
@@ -2014,7 +2059,7 @@ gnu_special (work, mangled, declp)
{
if (p != NULL)
{
- string_append (declp, "::");
+ string_append (declp, SCOPE_STRING (work));
(*mangled)++;
}
}
@@ -2040,7 +2085,7 @@ gnu_special (work, mangled, declp)
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
- success = demangle_template (work, mangled, declp, 0, 1);
+ success = demangle_template (work, mangled, declp, 0, 1, 1);
break;
default:
n = consume_count (mangled);
@@ -2052,7 +2097,7 @@ gnu_special (work, mangled, declp)
/* Consumed everything up to the cplus_marker, append the
variable name. */
(*mangled)++;
- string_append (declp, "::");
+ string_append (declp, SCOPE_STRING (work));
n = strlen (*mangled);
string_appendn (declp, *mangled, n);
(*mangled) += n;
@@ -2093,7 +2138,7 @@ gnu_special (work, mangled, declp)
success = demangle_qualified (work, mangled, declp, 0, 1);
break;
case 't':
- success = demangle_template (work, mangled, declp, 0, 1);
+ success = demangle_template (work, mangled, declp, 0, 1, 1);
break;
default:
success = demangle_fund_type (work, mangled, declp);
@@ -2225,13 +2270,20 @@ demangle_qualified (work, mangled, result, isfuncname, append)
int append;
{
int qualifiers = 0;
- int namelength;
int success = 1;
const char *p;
char num[2];
string temp;
+ string last_name;
+ int bindex = register_Btype (work);
+
+ /* We only make use of ISFUNCNAME if the entity is a constructor or
+ destructor. */
+ isfuncname = (isfuncname
+ && ((work->constructor & 1) || (work->destructor & 1)));
string_init (&temp);
+ string_init (&last_name);
if ((*mangled)[0] == 'K')
{
@@ -2304,18 +2356,24 @@ demangle_qualified (work, mangled, result, isfuncname, append)
while (qualifiers-- > 0)
{
int remember_K = 1;
+ string_clear (&last_name);
+
if (*mangled[0] == '_')
- *mangled = *mangled + 1;
+ (*mangled)++;
+
if (*mangled[0] == 't')
{
- success = demangle_template(work, mangled, &temp, 0, 1);
- if (!success) break;
- }
- else if (*mangled[0] == 'X')
- {
- success = do_type (work, mangled, &temp);
- if (!success) break;
- }
+ /* Here we always append to TEMP since we will want to use
+ the template name without the template parameters as a
+ constructor or destructor name. The appropriate
+ (parameter-less) value is returned by demangle_template
+ in LAST_NAME. We do not remember the template type here,
+ in order to match the G++ mangling algorithm. */
+ success = demangle_template(work, mangled, &temp,
+ &last_name, 1, 0);
+ if (!success)
+ break;
+ }
else if (*mangled[0] == 'K')
{
int idx;
@@ -2330,60 +2388,48 @@ demangle_qualified (work, mangled, result, isfuncname, append)
if (!success) break;
}
else
- {
- namelength = consume_count (mangled);
- if (strlen (*mangled) < namelength)
- {
- /* Simple sanity check failed */
- success = 0;
- break;
- }
- string_appendn (&temp, *mangled, namelength);
- *mangled += namelength;
+ {
+ success = do_type (work, mangled, &last_name);
+ if (!success)
+ break;
+ string_appends (&temp, &last_name);
}
if (remember_K)
- {
- remember_Ktype (work, temp.b, LEN_STRING (&temp));
- }
+ remember_Ktype (work, temp.b, LEN_STRING (&temp));
if (qualifiers > 0)
- {
- string_append (&temp, "::");
- }
+ string_append (&temp, SCOPE_STRING (work));
}
+ remember_Btype (work, temp.b, LEN_STRING (&temp), bindex);
+
/* If we are using the result as a function name, we need to append
the appropriate '::' separated constructor or destructor name.
We do this here because this is the most convenient place, where
we already have a pointer to the name and the length of the name. */
- if (isfuncname && (work->constructor & 1 || work->destructor & 1))
+ if (isfuncname)
{
- string_append (&temp, "::");
+ string_append (&temp, SCOPE_STRING (work));
if (work -> destructor & 1)
- {
- string_append (&temp, "~");
- }
- string_appendn (&temp, (*mangled) - namelength, namelength);
+ string_append (&temp, "~");
+ string_appends (&temp, &last_name);
}
/* Now either prepend the temp buffer to the result, or append it,
depending upon the state of the append flag. */
if (append)
- {
- string_appends (result, &temp);
- }
+ string_appends (result, &temp);
else
{
if (!STRING_EMPTY (result))
- {
- string_append (&temp, "::");
- }
+ string_append (&temp, SCOPE_STRING (work));
string_prepends (result, &temp);
}
+ string_delete (&last_name);
string_delete (&temp);
return (success);
}
@@ -2474,7 +2520,7 @@ do_type (work, mangled, result)
case 'P':
case 'p':
(*mangled)++;
- string_prepend (&decl, "*");
+ string_prepend (&decl, "*");
break;
/* A reference type */
@@ -2530,15 +2576,14 @@ do_type (work, mangled, result)
/* After picking off the function args, we expect to either find the
function return type (preceded by an '_') or the end of the
string. */
- if (!demangle_args (work, mangled, &decl)
+ if (!demangle_nested_args (work, mangled, &decl)
|| (**mangled != '_' && **mangled != '\0'))
{
success = 0;
+ break;
}
if (success && (**mangled == '_'))
- {
- (*mangled)++;
- }
+ (*mangled)++;
break;
case 'M':
@@ -2556,7 +2601,7 @@ do_type (work, mangled, result)
}
string_append (&decl, ")");
- string_prepend (&decl, "::");
+ string_prepend (&decl, SCOPE_STRING (work));
if (isdigit (**mangled))
{
n = consume_count (mangled);
@@ -2572,7 +2617,8 @@ do_type (work, mangled, result)
{
string temp;
string_init (&temp);
- success = demangle_template (work, mangled, &temp, NULL, 1);
+ success = demangle_template (work, mangled, &temp,
+ NULL, 1, 1);
if (success)
{
string_prependn (&decl, temp.b, temp.p - temp.b);
@@ -2600,7 +2646,7 @@ do_type (work, mangled, result)
break;
}
}
- if ((member && !demangle_args (work, mangled, &decl))
+ if ((member && !demangle_nested_args (work, mangled, &decl))
|| **mangled != '_')
{
success = 0;
@@ -2661,10 +2707,7 @@ do_type (work, mangled, result)
case 'Q':
case 'K':
{
- int btype = register_Btype (work);
success = demangle_qualified (work, mangled, result, 0, 1);
- remember_Btype (work, result->b, LEN_STRING (result), btype);
-
break;
}
@@ -2894,9 +2937,7 @@ demangle_fund_type (work, mangled, result)
}
case 't':
{
- int bindex= register_Btype (work);
- success = demangle_template (work, mangled, &btype, 0, 1);
- remember_Btype (work, btype.b, LEN_STRING (&btype), bindex);
+ success = demangle_template (work, mangled, &btype, 0, 1, 1);
string_appends (result, &btype);
break;
}
@@ -2908,7 +2949,9 @@ demangle_fund_type (work, mangled, result)
return (success);
}
-/* `result' will be initialized in do_type; it will be freed on failure */
+/* Demangle the next argument, given by MANGLED into RESULT, which
+ *should be an uninitialized* string. It will be initialized here,
+ and free'd should anything go wrong. */
static int
do_arg (work, mangled, result)
@@ -2916,17 +2959,67 @@ do_arg (work, mangled, result)
const char **mangled;
string *result;
{
+ /* Remember where we started so that we can record the type, for
+ non-squangling type remembering. */
const char *start = *mangled;
- if (!do_type (work, mangled, result))
+ string_init (result);
+
+ if (work->nrepeats > 0)
{
- return (0);
+ --work->nrepeats;
+
+ if (work->previous_argument == 0)
+ return 0;
+
+ /* We want to reissue the previous type in this argument list. */
+ string_appends (result, work->previous_argument);
+ return 1;
+ }
+
+ if (**mangled == 'n')
+ {
+ /* A squangling-style repeat. */
+ (*mangled)++;
+ work->nrepeats = consume_count(mangled);
+
+ if (work->nrepeats == 0)
+ /* This was not a repeat count after all. */
+ return 0;
+
+ if (work->nrepeats > 9)
+ {
+ if (**mangled != '_')
+ /* The repeat count should be followed by an '_' in this
+ case. */
+ return 0;
+ else
+ (*mangled)++;
+ }
+
+ /* Now, the repeat is all set up. */
+ return do_arg (work, mangled, result);
}
+
+ /* Save the result in WORK->previous_argument so that we can find it
+ if it's repeated. Note that saving START is not good enough: we
+ do not want to add additional types to the back-referenceable
+ type vector when processing a repeated type. */
+ if (work->previous_argument)
+ string_clear (work->previous_argument);
else
{
- remember_type (work, start, *mangled - start);
- return (1);
+ work->previous_argument = (string*) xmalloc (sizeof (string));
+ string_init (work->previous_argument);
}
+
+ if (!do_type (work, mangled, work->previous_argument))
+ return 0;
+
+ string_appends (result, work->previous_argument);
+
+ remember_type (work, start, *mangled - start);
+ return 1;
}
static void
@@ -2937,6 +3030,9 @@ remember_type (work, start, len)
{
char *tem;
+ if (work->forgetting_types)
+ return;
+
if (work -> ntypes >= work -> typevec_size)
{
if (work -> typevec_size == 0)
@@ -3116,8 +3212,8 @@ forget_types (work)
foo__FiR3fooT1T2T1T2
__ct__3fooFiR3fooT1T2T1T2
- Note that g++ bases it's type numbers starting at zero and counts all
- previously seen types, while lucid/ARM bases it's type numbers starting
+ Note that g++ bases its type numbers starting at zero and counts all
+ previously seen types, while lucid/ARM bases its type numbers starting
at one and only considers types after it has seen the 'F' character
indicating the start of the function args. For lucid/ARM style, we
account for this difference by discarding any previously seen types when
@@ -3148,7 +3244,8 @@ demangle_args (work, mangled, declp)
}
}
- while (**mangled != '_' && **mangled != '\0' && **mangled != 'e')
+ while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e')
+ || work->nrepeats > 0)
{
if ((**mangled == 'N') || (**mangled == 'T'))
{
@@ -3195,7 +3292,7 @@ demangle_args (work, mangled, declp)
{
return (0);
}
- while (--r >= 0)
+ while (work->nrepeats > 0 || --r >= 0)
{
tem = work -> typevec[t];
if (need_comma && PRINT_ARG_TYPES)
@@ -3216,18 +3313,12 @@ demangle_args (work, mangled, declp)
}
else
{
- if (need_comma & PRINT_ARG_TYPES)
- {
- string_append (declp, ", ");
- }
+ if (need_comma && PRINT_ARG_TYPES)
+ string_append (declp, ", ");
if (!do_arg (work, mangled, &arg))
- {
- return (0);
- }
+ return (0);
if (PRINT_ARG_TYPES)
- {
- string_appends (declp, &arg);
- }
+ string_appends (declp, &arg);
string_delete (&arg);
need_comma = 1;
}
@@ -3253,6 +3344,44 @@ demangle_args (work, mangled, declp)
return (1);
}
+/* Like demangle_args, but for demangling the argument lists of function
+ and method pointers or references, not top-level declarations. */
+
+int
+demangle_nested_args (work, mangled, declp)
+ struct work_stuff *work;
+ const char **mangled;
+ string *declp;
+{
+ string* saved_previous_argument;
+ int result;
+ int saved_nrepeats;
+
+ /* The G++ name-mangling algorithm does not remember types on nested
+ argument lists, unless -fsquangling is used, and in that case the
+ type vector updated by remember_type is not used. So, we turn
+ off remembering of types here. */
+ ++work->forgetting_types;
+
+ /* For the repeat codes used with -fsquangling, we must keep track of
+ the last argument. */
+ saved_previous_argument = work->previous_argument;
+ saved_nrepeats = work->nrepeats;
+ work->previous_argument = 0;
+ work->nrepeats = 0;
+
+ /* Actually demangle the arguments. */
+ result = demangle_args (work, mangled, declp);
+
+ /* Restore the previous_argument field. */
+ if (work->previous_argument)
+ string_delete (work->previous_argument);
+ work->previous_argument = saved_previous_argument;
+ work->nrepeats = saved_nrepeats;
+
+ return result;
+}
+
static void
demangle_function_name (work, mangled, declp, scan)
struct work_stuff *work;