diff options
author | Mark Mitchell <mark@markmitchell.com> | 1998-07-11 16:20:54 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1998-07-11 16:20:54 +0000 |
commit | 59e621fcddabe616abdf2e113b3418fb1770ad00 (patch) | |
tree | d8664c3d171ecf5264e39c9fca37dc4dc6580f5e /gcc/cplus-dem.c | |
parent | 6b9ab5cc45bfc38ce768e9c472cad34e81c857f7 (diff) | |
download | gcc-59e621fcddabe616abdf2e113b3418fb1770ad00.zip gcc-59e621fcddabe616abdf2e113b3418fb1770ad00.tar.gz gcc-59e621fcddabe616abdf2e113b3418fb1770ad00.tar.bz2 |
cplus-dem.c (string): Move definition before work_stuff.
* cplus-dem.c (string): Move definition before work_stuff.
(work_stuff): Add volatile_type, forgetting_types,
previous_argument, and nrepeats fields.
(SCOPE_STRING): New macro.
(demangle_template): Add `remember' parameter. Add comment.
Register the `B' code type here, if remembering. Tidy. Fix crash
on NULL tmpl_argvec. Be consistent with use of tname/trawname.
(demangle_nested_args): New function.
(internal_cplus_demangle): Handle volatile-qualified member
functions.
(mop_up): Delete the previous_argument string if present.
(demangle_signature): Tidy. Handle volatile-qualified member
functions. Handle back-references using the `B' code. Use extra
parameter to demangle_template and SCOPE_STRING where appropriate.
(demangle_template_value_parm): Fix thinko; 'B' is not an integral
code.
(demangle_class): Use SCOPE_STRING.
(gnu_special): Pass additional argument to demangle_template.
Use SCOPE_STRING.
(demangle_qualified): Save qualified types for later
back-references. Handle constructors and destructors for template
types correctly.
(do_type): Tidy. Use SCOPE_STRING. Pass extra argument to
demangle_template. Use demangled_nested_args. Don't remember
qualified types here; that's now done in demangle_qualified.
Similarly for templates.
(do_arg): Improve commment. Handle 'n' repeat code.
(remember_type): Check forgetting_types.
(demangle_args): Deal with 'n' repeat codes. Tidy.
* method.c (flush_repeats): Add nrepeats parameter.
(issue_nrepeats): Likewise.
(is_back_referenceable_type): New function. Don't back-reference
TEMPLATE_TYPE_PARMs as well as simple types like integers.
(build_mangled_name_for_type): Likewise.
(build_mangled_name_for_type_with_Gcode): Likewise.
(lasttype): Remove.
(nrepeats): Likewise.
(Nrepeats): Likewise.
(start_squangling): Don't clear the variables removed above.
(end_squangling): Likewise.
(flush_repeats): Tidy. Use nrepeats parameter rather than
Nrepeats global.
(issue_nrepeats): Likewise, but with nrepeats global. Use
is_backreferenceable_type.
(build_overload_nested_name): Tidy. Add comment. Use
build_mangled_name_for_type.
(build_underscore_int): Comment.
(build_overload_scope_ref): Use build_mangled_name_for_type.
(build_overload_int): Likewise.
(build_template_template_parm_names): Tidy.
(build_template_parm_names): Use build_mangled_name_for_type.
(build_overload_identifier): Add comments.
(build_mangled_name_for_type_with_Gcode): Split out from
build_mangled_name.
(build_mangled_name_for_type): Use it.
(build_mangled_name): Rework to use build_mangled_name_for_type
and to not use global nrepeats/Nrepeats. Tidy.
(process_modifiers): Tidy.
(check_btype): Use is_backreferenceable_type. Add comment.
Rename `node' to `type'.
(process_overload_item): Set numeric_output_need_bar here.
Use build_mangled_name_for_type. Tidy.
(build_decl_overload_real): Tidy. Don't use Nrepeats. Use
build_mangled_name_for_type.
From-SVN: r21062
Diffstat (limited to 'gcc/cplus-dem.c')
-rw-r--r-- | gcc/cplus-dem.c | 360 |
1 files changed, 245 insertions, 115 deletions
diff --git a/gcc/cplus-dem.c b/gcc/cplus-dem.c index b05c948..ce67d22 100644 --- a/gcc/cplus-dem.c +++ b/gcc/cplus-dem.c @@ -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,10 @@ 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) \ + (((work)->options & DMGL_JAVA) ? "." : "::") + #define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */ #define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */ @@ -247,7 +257,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 +336,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 @@ -631,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')) { @@ -677,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); } @@ -727,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. */ @@ -795,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; @@ -826,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': @@ -852,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 @@ -884,12 +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, (work -> options & DMGL_JAVA) ? "." : "::"); + string_append(&tname, SCOPE_STRING (work)); string_prepends(declp, &tname); if (work -> destructor & 1) { @@ -936,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)++; @@ -993,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); } @@ -1211,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; @@ -1360,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; @@ -1375,10 +1418,13 @@ demangle_template (work, mangled, tname, trawname, is_type) const char *start; int is_java_array = 0; string temp; + int bindex; (*mangled)++; if (is_type) { + if (remember) + bindex = register_Btype (work); start = *mangled; /* get template name */ if (**mangled == 'z') @@ -1391,9 +1437,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]); @@ -1406,7 +1451,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 @@ -1415,13 +1460,13 @@ demangle_template (work, mangled, tname, trawname, is_type) { return (0); } - if (trawname) - string_appendn (trawname, *mangled, r); is_java_array = (work -> options & DMGL_JAVA) && strncmp (*mangled, "JArray1Z", 8) == 0; if (! is_java_array) { string_appendn (tname, *mangled, r); + if (trawname) + string_appendn (trawname, *mangled, r); } *mangled += r; } @@ -1565,6 +1610,9 @@ demangle_template (work, mangled, tname, trawname, is_type) string_append (tname, ">"); } + if (is_type && remember) + remember_Btype (work, tname->b, LEN_STRING (tname), bindex); + /* if (work -> static_type) { @@ -1722,7 +1770,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, (work -> options & DMGL_JAVA) ? "." : "::"); + string_prepend (declp, SCOPE_STRING (work)); string_prepends (declp, &class_name); success = 1; } @@ -1996,7 +2044,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])) @@ -2024,8 +2073,7 @@ gnu_special (work, mangled, declp) { if (p != NULL) { - string_append (declp, - (work -> options & DMGL_JAVA) ? "." : "::"); + string_append (declp, SCOPE_STRING (work)); (*mangled)++; } } @@ -2051,7 +2099,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); @@ -2063,7 +2111,7 @@ gnu_special (work, mangled, declp) /* Consumed everything up to the cplus_marker, append the variable name. */ (*mangled)++; - string_append (declp, (work -> options & DMGL_JAVA) ? "." : "::"); + string_append (declp, SCOPE_STRING (work)); n = strlen (*mangled); string_appendn (declp, *mangled, n); (*mangled) += n; @@ -2104,7 +2152,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); @@ -2236,13 +2284,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') { @@ -2315,18 +2370,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; @@ -2341,60 +2402,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, (work -> options & DMGL_JAVA) ? "." : "::"); - } + 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, (work -> options & DMGL_JAVA) ? "." : "::"); + 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, (work -> options & DMGL_JAVA) ? "." : "::"); - } + string_append (&temp, SCOPE_STRING (work)); string_prepends (result, &temp); } + string_delete (&last_name); string_delete (&temp); return (success); } @@ -2542,15 +2591,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': @@ -2568,7 +2616,7 @@ do_type (work, mangled, result) } string_append (&decl, ")"); - string_prepend (&decl, (work -> options & DMGL_JAVA) ? "." : "::"); + string_prepend (&decl, SCOPE_STRING (work)); if (isdigit (**mangled)) { n = consume_count (mangled); @@ -2584,7 +2632,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); @@ -2612,7 +2661,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; @@ -2673,10 +2722,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; } @@ -2906,9 +2952,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; } @@ -2920,7 +2964,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) @@ -2928,17 +2974,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 @@ -2949,6 +3045,9 @@ remember_type (work, start, len) { char *tem; + if (work->forgetting_types) + return; + if (work -> ntypes >= work -> typevec_size) { if (work -> typevec_size == 0) @@ -3160,7 +3259,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')) { @@ -3207,7 +3307,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) @@ -3228,18 +3328,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; } @@ -3265,6 +3359,42 @@ 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; +} + static void demangle_function_name (work, mangled, declp, scan) struct work_stuff *work; |