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
This commit is contained in:
Mark Mitchell 1997-09-28 19:37:05 +00:00 committed by Jason Merrill
parent a98d45ff1f
commit a3a5b5b7bf
2 changed files with 252 additions and 52 deletions

View File

@ -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

View File

@ -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);
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;
}
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, "<");
}
*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 = &param;
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;