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: r15780
This commit is contained in:
Mark Mitchell 1997-09-28 19:59:54 +00:00 committed by Jason Merrill
parent a3a5b5b7bf
commit 37f6b6bfd2
3 changed files with 282 additions and 54 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.
Sun Sep 28 01:55:04 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
* flow.c (print_rtl_with_bb): Cast alloca return values for variables

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;

View File

@ -104,8 +104,9 @@ in the following sections.
@smallexample
-fall-virtual -fdollars-in-identifiers -felide-constructors
-fenum-int-equiv -fexternal-templates -ffor-scope -fno-for-scope
-fhandle-signatures -fmemoize-lookups -fno-default-inline -fno-gnu-keywords
-fnonnull-objects -foperator-names -fstrict-prototype -fthis-is-variable
-fhandle-signatures -fmemoize-lookups -fname-mangling-version-@var{n}
-fno-default-inline -fno-gnu-keywords -fnonnull-objects -fguiding-decls
-foperator-names -fstrict-prototype -fthis-is-variable
-ftemplate-depth-@var{n} -nostdinc++ -traditional +e@var{n}
@end smallexample
@ -925,11 +926,15 @@ Cause template instantiations to obey @samp{#pragma interface} and
to the location of the template definition. @xref{Template
Instantiation}, for more information.
This option is deprecated.
@item -falt-external-templates
Similar to -fexternal-templates, but template instances are emitted or
not according to the place where they are first instantiated.
@xref{Template Instantiation}, for more information.
This option is deprecated.
@item -ffor-scope
@item -fno-for-scope
If -ffor-scope is specified, the scope of variables declared in
@ -952,6 +957,18 @@ words as identifiers. You can use the keywords @code{__classof__},
@code{__typeof__} instead. @samp{-ansi} implies
@samp{-fno-gnu-keywords}.
@item -fguiding-decls
Treat a function declaration with the same type as a potential function
template instantiation as though it declares that instantiation, not a
normal function. If a definition is given for the function later in the
translation unit (or another translation unit if the target supports
weak symbols), that definition will be used; otherwise the template will
be instantiated. This behavior reflects the C++ language prior to
September 1996, when guiding declarations were removed.
This option implies @samp{-fname-mangling-version-0}, and will not work
with other name mangling versions.
@item -fno-implicit-templates
Never emit code for templates which are instantiated implicitly (i.e. by
use); only emit code for explicit instantiations. @xref{Template
@ -1029,6 +1046,17 @@ overridden with @samp{-fno-strict-prototype}.
This flag no longer affects declarations with C++ linkage.
@item -fname-mangling-version-@var{n}
Control the way in which names are mangled. Version 0 is compatible
with versions of g++ before 2.8. Version 1 is the default. Version 1
will allow correct mangling of function templates. For example,
version 0 mangling does not mangle foo<int, double> and foo<int, char>
given this declaration:
@example
template <class T, class U> void foo(T t);
@end example
@item -fno-nonnull-objects
Don't assume that a reference is initialized to refer to a valid object.
Although the current C++ Working Paper prohibits null references, some