diff options
author | Mark Mitchell <mmitchell@usa.net> | 1997-09-28 19:37:05 +0000 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 1997-09-28 15:37:05 -0400 |
commit | a3a5b5b7bf729dda824c4b644bbe28f830e4fbc4 (patch) | |
tree | b9d61a358f04c03ae2a7ce7d0273bd37a11ce793 /libiberty | |
parent | a98d45ff1f4d45241c521994bbf03c438ba0d91f (diff) | |
download | gcc-a3a5b5b7bf729dda824c4b644bbe28f830e4fbc4.zip gcc-a3a5b5b7bf729dda824c4b644bbe28f830e4fbc4.tar.gz gcc-a3a5b5b7bf729dda824c4b644bbe28f830e4fbc4.tar.bz2 |
cplus-dem.c (demangle_template): Add new parameter.
Sun Sep 28 12:00:52 1997 Mark Mitchell <mmitchell@usa.net>
* cplus-dem.c (demangle_template): Add new parameter. Handle new
template-function mangling.
(consume_count_with_underscores): New function.
(demangle_signature): Handle new name-mangling scheme.
From-SVN: r15778
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/ChangeLog | 7 | ||||
-rw-r--r-- | libiberty/cplus-dem.c | 297 |
2 files changed, 252 insertions, 52 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 0fae0d2..a2c2274 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,10 @@ +Sun Sep 28 12:00:52 1997 Mark Mitchell <mmitchell@usa.net> + + * cplus-dem.c (demangle_template): Add new parameter. Handle new + template-function mangling. + (consume_count_with_underscores): New function. + (demangle_signature): Handle new name-mangling scheme. + Tue Sep 9 19:39:12 1997 Jim Wilson <wilson@cygnus.com> * Makefile.in (install_to_libdir, install_to_tooldir): Add MULTISUBDIR diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index 5794a5b..055ab08 100644 --- a/libiberty/cplus-dem.c +++ b/libiberty/cplus-dem.c @@ -102,6 +102,8 @@ struct work_stuff int destructor; int static_type; /* A static member function */ int const_type; /* A const member function */ + char **tmpl_argvec; /* Template function arguments. */ + int ntmpl_args; /* The number of template function arguments. */ }; #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) @@ -222,7 +224,7 @@ demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *)) static int demangle_template PARAMS ((struct work_stuff *work, const char **, string *, - string *)); + string *, int)); static int arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **, @@ -294,6 +296,9 @@ get_count PARAMS ((const char **, int *)); static int consume_count PARAMS ((const char **)); +static int +consume_count_with_underscores PARAMS ((const char**)); + static int demangle_args PARAMS ((struct work_stuff *, const char **, string *)); @@ -336,6 +341,42 @@ consume_count (type) return (count); } + +/* Like consume_count, but for counts that are preceeded and followed + by '_' if they are greater than 10. Also, -1 is returned for + failure, since 0 can be a valid value. */ + +static int +consume_count_with_underscores (mangled) + const char **mangled; +{ + int idx; + + if (**mangled == '_') + { + (*mangled)++; + if (!isdigit (**mangled)) + return -1; + + idx = consume_count (mangled); + if (**mangled != '_') + /* The trailing underscore was missing. */ + return -1; + + (*mangled)++; + } + else + { + if (**mangled < '0' || **mangled > '9') + return -1; + + idx = **mangled - '0'; + (*mangled)++; + } + + return idx; +} + int cplus_demangle_opname (opname, result, options) const char *opname; @@ -580,7 +621,17 @@ mop_up (work, declp, success) { free ((char *) work -> typevec); } - + if (work->tmpl_argvec) + { + int i; + + for (i = 0; i < work->ntmpl_args; i++) + if (work->tmpl_argvec[i]) + free ((char*) work->tmpl_argvec[i]); + + free ((char*) work->tmpl_argvec); + } + /* If demangling was successful, ensure that the demangled string is null terminated and return it. Otherwise, free the demangling decl. */ @@ -635,6 +686,7 @@ demangle_signature (work, mangled, declp) int success = 1; int func_done = 0; int expect_func = 0; + int expect_return_type = 0; const char *oldmangled = NULL; string trawname; string tname; @@ -726,7 +778,7 @@ demangle_signature (work, mangled, declp) { oldmangled = *mangled; } - success = demangle_template (work, mangled, &tname, &trawname); + success = demangle_template (work, mangled, &tname, &trawname, 1); if (success) { remember_type (work, oldmangled, *mangled - oldmangled); @@ -751,14 +803,42 @@ demangle_signature (work, mangled, declp) break; case '_': - /* At the outermost level, we cannot have a return type specified, - so if we run into another '_' at this point we are dealing with - a mangled name that is either bogus, or has been mangled by - some algorithm we don't know how to deal with. So just - reject the entire demangling. */ - success = 0; + if (GNU_DEMANGLING && expect_return_type) + { + /* Read the return type. */ + string return_type; + string_init (&return_type); + + (*mangled)++; + success = do_type (work, mangled, &return_type); + APPEND_BLANK (&return_type); + + string_prepends (declp, &return_type); + string_delete (&return_type); + break; + } + else + /* At the outermost level, we cannot have a return type specified, + so if we run into another '_' at this point we are dealing with + a mangled name that is either bogus, or has been mangled by + some algorithm we don't know how to deal with. So just + reject the entire demangling. */ + success = 0; break; + case 'H': + if (GNU_DEMANGLING) + { + /* A G++ template function. Read the template arguments. */ + success = demangle_template (work, mangled, declp, 0, 0); + expect_return_type = 1; + (*mangled)++; + break; + } + else + /* fall through */ + ; + default: if (AUTO_DEMANGLING || GNU_DEMANGLING) { @@ -785,6 +865,10 @@ demangle_signature (work, mangled, declp) { func_done = 1; success = demangle_args (work, mangled, declp); + /* Since template include the mangling of their return types, + we must set expect_func to 0 so that we don't try do + demangle more arguments the next time we get here. */ + expect_func = 0; } } } @@ -838,11 +922,12 @@ demangle_method_args (work, mangled, declp) #endif static int -demangle_template (work, mangled, tname, trawname) +demangle_template (work, mangled, tname, trawname, is_type) struct work_stuff *work; const char **mangled; string *tname; string *trawname; + int is_type; { int i; int is_pointer; @@ -857,31 +942,43 @@ demangle_template (work, mangled, tname, trawname) const char *old_p; const char *start; int symbol_len; - int is_java_array; + int is_java_array = 0; string temp; (*mangled)++; - start = *mangled; - /* get template name */ - if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r) + if (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); - string_append (tname, "<"); + start = *mangled; + /* get template name */ + if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r) + { + 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); + } + *mangled += r; } - *mangled += r; + if (!is_java_array) + string_append (tname, "<"); /* get size of template parameter list */ if (!get_count (mangled, &r)) { return (0); } + if (!is_type) + { + /* Create an array for saving the template argument values. */ + work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *)); + work->ntmpl_args = r; + for (i = 0; i < r; i++) + work->tmpl_argvec[i] = 0; + } for (i = 0; i < r; i++) { if (need_comma) @@ -897,6 +994,15 @@ demangle_template (work, mangled, tname, trawname) if (success) { string_appends (tname, &temp); + + if (!is_type) + { + /* Save the template argument. */ + int len = temp.p - temp.b; + work->tmpl_argvec[i] = xmalloc (len + 1); + memcpy (work->tmpl_argvec[i], temp.b, len); + work->tmpl_argvec[i][len] = '\0'; + } } string_delete(&temp); if (!success) @@ -906,6 +1012,9 @@ demangle_template (work, mangled, tname, trawname) } else { + string param; + string* s; + /* otherwise, value parameter */ old_p = *mangled; is_pointer = 0; @@ -919,7 +1028,7 @@ demangle_template (work, mangled, tname, trawname) /* if (success) { - string_appends (tname, &temp); + string_appends (s, &temp); } */ string_delete(&temp); @@ -928,8 +1037,17 @@ demangle_template (work, mangled, tname, trawname) break; } /* - string_append (tname, "="); + string_append (s, "="); */ + + if (!is_type) + { + s = ¶m; + string_init (s); + } + else + s = tname; + while (*old_p && !done) { switch (*old_p) @@ -983,16 +1101,41 @@ demangle_template (work, mangled, tname, trawname) done = is_integral = 1; } } - if (is_integral) + if (**mangled == 'Y') + { + /* The next argument is a template parameter. */ + int idx; + + (*mangled)++; + idx = consume_count_with_underscores (mangled); + if (idx == -1 + || (work->tmpl_argvec && idx >= work->ntmpl_args) + || consume_count_with_underscores (mangled) == -1) + { + success = 0; + if (!is_type) + string_delete (s); + break; + } + if (work->tmpl_argvec) + string_append (s, work->tmpl_argvec[idx]); + else + { + char buf[10]; + sprintf(buf, "T%d", idx); + string_append (s, buf); + } + } + else if (is_integral) { if (**mangled == 'm') { - string_appendn (tname, "-", 1); + string_appendn (s, "-", 1); (*mangled)++; } while (isdigit (**mangled)) { - string_appendn (tname, *mangled, 1); + string_appendn (s, *mangled, 1); (*mangled)++; } } @@ -1002,28 +1145,30 @@ demangle_template (work, mangled, tname, trawname) int val; if (**mangled == 'm') { - string_appendn (tname, "-", 1); + string_appendn (s, "-", 1); (*mangled)++; } - string_appendn (tname, "'", 1); + string_appendn (s, "'", 1); val = consume_count(mangled); if (val == 0) { success = 0; + if (!is_type) + string_delete (s); break; } tmp[0] = (char)val; tmp[1] = '\0'; - string_appendn (tname, &tmp[0], 1); - string_appendn (tname, "'", 1); + string_appendn (s, &tmp[0], 1); + string_appendn (s, "'", 1); } else if (is_bool) { int val = consume_count (mangled); if (val == 0) - string_appendn (tname, "false", 5); + string_appendn (s, "false", 5); else if (val == 1) - string_appendn (tname, "true", 4); + string_appendn (s, "true", 4); else success = 0; } @@ -1031,31 +1176,31 @@ demangle_template (work, mangled, tname, trawname) { if (**mangled == 'm') { - string_appendn (tname, "-", 1); + string_appendn (s, "-", 1); (*mangled)++; } while (isdigit (**mangled)) { - string_appendn (tname, *mangled, 1); + string_appendn (s, *mangled, 1); (*mangled)++; } if (**mangled == '.') /* fraction */ { - string_appendn (tname, ".", 1); + string_appendn (s, ".", 1); (*mangled)++; while (isdigit (**mangled)) { - string_appendn (tname, *mangled, 1); + string_appendn (s, *mangled, 1); (*mangled)++; } } if (**mangled == 'e') /* exponent */ { - string_appendn (tname, "e", 1); + string_appendn (s, "e", 1); (*mangled)++; while (isdigit (**mangled)) { - string_appendn (tname, *mangled, 1); + string_appendn (s, *mangled, 1); (*mangled)++; } } @@ -1066,28 +1211,40 @@ demangle_template (work, mangled, tname, trawname) if (symbol_len == 0) { success = 0; + if (!is_type) + string_delete (s); break; } if (symbol_len == 0) - string_appendn (tname, "0", 1); + string_appendn (s, "0", 1); else { char *p = xmalloc (symbol_len + 1), *q; strncpy (p, *mangled, symbol_len); p [symbol_len] = '\0'; q = cplus_demangle (p, work->options); - string_appendn (tname, "&", 1); + string_appendn (s, "&", 1); if (q) { - string_append (tname, q); + string_append (s, q); free (q); } else - string_append (tname, p); + string_append (s, p); free (p); } *mangled += symbol_len; } + if (!is_type) + { + int len = s->p - s->b; + work->tmpl_argvec[i] = xmalloc (len + 1); + memcpy (work->tmpl_argvec[i], s->b, len); + work->tmpl_argvec[i][len] = '\0'; + + string_appends (tname, s); + string_delete (s); + } } need_comma = 1; } @@ -1526,7 +1683,7 @@ gnu_special (work, mangled, declp) success = demangle_qualified (work, mangled, declp, 0, 1); break; case 't': - success = demangle_template (work, mangled, declp, 0); + success = demangle_template (work, mangled, declp, 0, 1); break; default: if (isdigit(*mangled[0])) @@ -1571,7 +1728,7 @@ gnu_special (work, mangled, declp) success = demangle_qualified (work, mangled, declp, 0, 1); break; case 't': - success = demangle_template (work, mangled, declp, 0); + success = demangle_template (work, mangled, declp, 0, 1); break; default: n = consume_count (mangled); @@ -1623,7 +1780,7 @@ gnu_special (work, mangled, declp) success = demangle_qualified (work, mangled, declp, 0, 1); break; case 't': - success = demangle_template (work, mangled, declp, 0); + success = demangle_template (work, mangled, declp, 0, 1); break; default: success = demangle_fund_type (work, mangled, declp); @@ -1825,7 +1982,12 @@ demangle_qualified (work, mangled, result, isfuncname, append) *mangled = *mangled + 1; if (*mangled[0] == 't') { - success = demangle_template(work, mangled, &temp, 0); + 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; } else @@ -2064,7 +2226,7 @@ do_type (work, mangled, result) { string temp; string_init (&temp); - success = demangle_template (work, mangled, &temp, NULL); + success = demangle_template (work, mangled, &temp, NULL, 1); if (success) { string_prependn (&decl, temp.b, temp.p - temp.b); @@ -2152,6 +2314,37 @@ do_type (work, mangled, result) success = demangle_qualified (work, mangled, result, 0, 1); break; + case 'X': + case 'Y': + /* A template parm. We substitute the corresponding argument. */ + { + int idx; + int lvl; + + (*mangled)++; + idx = consume_count_with_underscores (mangled); + + if (idx == -1 + || (work->tmpl_argvec && idx >= work->ntmpl_args) + || consume_count_with_underscores (mangled) == -1) + { + success = 0; + break; + } + + if (work->tmpl_argvec) + string_append (result, work->tmpl_argvec[idx]); + else + { + char buf[10]; + sprintf(buf, "T%d", idx); + string_append (result, buf); + } + + success = 1; + } + break; + default: success = demangle_fund_type (work, mangled, result); break; @@ -2326,7 +2519,7 @@ demangle_fund_type (work, mangled, result) } break; case 't': - success = demangle_template(work,mangled, result, 0); + success = demangle_template(work,mangled, result, 0, 1); break; default: success = 0; |