merge from gcc

This commit is contained in:
DJ Delorie 2003-11-27 01:17:34 +00:00
parent f2d0e87dbf
commit 331c3da232
3 changed files with 178 additions and 73 deletions

View File

@ -1,3 +1,29 @@
2003-11-26 Ian Lance Taylor <ian@wasabisystems.com>
* cp-demangle.c (struct d_print_mod): Add templates field.
(d_make_builtin_type): Check for NULL type.
(d_make_extended_operator): Check for NULL name.
(d_make_ctor, d_make_dtor): Likewise.
(d_mangled_name): Add top_level parameter. Change all callers.
(d_encoding): If DMGL_PARAMS is not set, strip off initial
CV-qualifiers.
(d_type): Check some return values we rely on.
(d_bare_function_type, d_array_type): Likewise.
(d_pointer_to_member_type, d_template_args): Likewise.
(d_add_substitution): Fail if argument is NULL.
(d_print_resize): Check whether buf is NULL.
(d_print_comp): Save current templates list with each modifier.
Don't pass the modifier list down when printing a template.
(d_print_cast): Don't pass the modifier list down when printing a
template.
(d_print_mod_list): Temporarily set templates list while printing
a modifier.
(d_print_mod): Check that buf is not NULL before using it.
(d_print_function_type): Print parens if there is no modifier.
(d_init_info): Permit as many substitutions as there are
characters in the mangled name.
* testsuite/demangle-expected: Add two new test cases.
2003-11-25 Ian Lance Taylor <ian@wasabisystems.com> 2003-11-25 Ian Lance Taylor <ian@wasabisystems.com>
* cp-demangle.c (java_demangle_v3): Pass DMGL_PARAMS to * cp-demangle.c (java_demangle_v3): Pass DMGL_PARAMS to

View File

@ -331,6 +331,8 @@ struct d_print_mod
const struct d_comp *mod; const struct d_comp *mod;
/* Whether this modifier was printed. */ /* Whether this modifier was printed. */
int printed; int printed;
/* The list of templates which applies to this modifier. */
struct d_print_template *templates;
}; };
/* We use this structure to hold information during printing. */ /* We use this structure to hold information during printing. */
@ -411,7 +413,7 @@ static struct d_comp *d_make_dtor PARAMS ((struct d_info *,
struct d_comp *)); struct d_comp *));
static struct d_comp *d_make_template_param PARAMS ((struct d_info *, long)); static struct d_comp *d_make_template_param PARAMS ((struct d_info *, long));
static struct d_comp *d_make_sub PARAMS ((struct d_info *, const char *)); static struct d_comp *d_make_sub PARAMS ((struct d_info *, const char *));
static struct d_comp *d_mangled_name PARAMS ((struct d_info *)); static struct d_comp *d_mangled_name PARAMS ((struct d_info *, int));
static int has_return_type PARAMS ((struct d_comp *)); static int has_return_type PARAMS ((struct d_comp *));
static int is_ctor_dtor_or_conversion PARAMS ((struct d_comp *)); static int is_ctor_dtor_or_conversion PARAMS ((struct d_comp *));
static struct d_comp *d_encoding PARAMS ((struct d_info *, int)); static struct d_comp *d_encoding PARAMS ((struct d_info *, int));
@ -664,7 +666,8 @@ d_make_comp (di, type, left, right)
struct d_comp *p; struct d_comp *p;
/* We check for errors here. A typical error would be a NULL return /* We check for errors here. A typical error would be a NULL return
from a subroutine. We catch here, and return NULL on upward. */ from a subroutine. We catch those here, and return NULL
upward. */
switch (type) switch (type)
{ {
/* These types require two parameters. */ /* These types require two parameters. */
@ -766,6 +769,8 @@ d_make_builtin_type (di, type)
{ {
struct d_comp *p; struct d_comp *p;
if (type == NULL)
return NULL;
p = d_make_empty (di, D_COMP_BUILTIN_TYPE); p = d_make_empty (di, D_COMP_BUILTIN_TYPE);
if (p != NULL) if (p != NULL)
p->u.s_builtin.type = type; p->u.s_builtin.type = type;
@ -797,6 +802,8 @@ d_make_extended_operator (di, args, name)
{ {
struct d_comp *p; struct d_comp *p;
if (name == NULL)
return NULL;
p = d_make_empty (di, D_COMP_EXTENDED_OPERATOR); p = d_make_empty (di, D_COMP_EXTENDED_OPERATOR);
if (p != NULL) if (p != NULL)
{ {
@ -816,6 +823,8 @@ d_make_ctor (di, kind, name)
{ {
struct d_comp *p; struct d_comp *p;
if (name == NULL)
return NULL;
p = d_make_empty (di, D_COMP_CTOR); p = d_make_empty (di, D_COMP_CTOR);
if (p != NULL) if (p != NULL)
{ {
@ -835,6 +844,8 @@ d_make_dtor (di, kind, name)
{ {
struct d_comp *p; struct d_comp *p;
if (name == NULL)
return NULL;
p = d_make_empty (di, D_COMP_DTOR); p = d_make_empty (di, D_COMP_DTOR);
if (p != NULL) if (p != NULL)
{ {
@ -874,17 +885,20 @@ d_make_sub (di, name)
return p; return p;
} }
/* <mangled-name> ::= _Z <encoding> */ /* <mangled-name> ::= _Z <encoding>
TOP_LEVEL is non-zero when called at the top level. */
static struct d_comp * static struct d_comp *
d_mangled_name (di) d_mangled_name (di, top_level)
struct d_info *di; struct d_info *di;
int top_level;
{ {
if (d_next_char (di) != '_') if (d_next_char (di) != '_')
return NULL; return NULL;
if (d_next_char (di) != 'Z') if (d_next_char (di) != 'Z')
return NULL; return NULL;
return d_encoding (di, 1); return d_encoding (di, top_level);
} }
/* Return whether a function should have a return type. The argument /* Return whether a function should have a return type. The argument
@ -961,10 +975,21 @@ d_encoding (di, top_level)
struct d_comp *dc; struct d_comp *dc;
dc = d_name (di); dc = d_name (di);
if (dc != NULL && top_level && (di->options & DMGL_PARAMS) == 0)
{
/* Strip off any initial CV-qualifiers, as they really apply
to the `this' parameter, and they were not output by the
v2 demangler without DMGL_PARAMS. */
while (dc->type == D_COMP_RESTRICT
|| dc->type == D_COMP_VOLATILE
|| dc->type == D_COMP_CONST)
dc = d_left (dc);
return dc;
}
peek = d_peek_char (di); peek = d_peek_char (di);
if (peek == '\0' if (peek == '\0' || peek == 'E')
|| peek == 'E'
|| (top_level && (di->options & DMGL_PARAMS) == 0))
return dc; return dc;
return d_make_comp (di, D_COMP_TYPED_NAME, dc, return d_make_comp (di, D_COMP_TYPED_NAME, dc,
d_bare_function_type (di, has_return_type (dc))); d_bare_function_type (di, has_return_type (dc)));
@ -1610,9 +1635,13 @@ d_type (di)
CV-qualifiers would cause subsets to be substitutable, so instead CV-qualifiers would cause subsets to be substitutable, so instead
we pull them all off now. we pull them all off now.
FIXME: The ABI specifies that vendor qualifiers are handled just FIXME: The ABI says that order-insensitive vendor qualifiers
like the standard CV-qualifiers with respect to subsetting and should be handled in the same way, but we have no way to tell
substitution, but g++ does not appear to work this way. */ which vendor qualifiers are order-insensitive and which are
order-sensitive. So we just assume that they are all
order-sensitive. g++ 3.4 supports only one vendor qualifier,
__vector, and it treats it as order-sensitive when mangling
names. */
peek = d_peek_char (di); peek = d_peek_char (di);
if (peek == 'r' || peek == 'V' || peek == 'K') if (peek == 'r' || peek == 'V' || peek == 'K')
@ -1620,6 +1649,8 @@ d_type (di)
struct d_comp **pret; struct d_comp **pret;
pret = d_cv_qualifiers (di, &ret); pret = d_cv_qualifiers (di, &ret);
if (pret == NULL)
return NULL;
*pret = d_type (di); *pret = d_type (di);
if (! d_add_substitution (di, ret)) if (! d_add_substitution (di, ret))
return NULL; return NULL;
@ -1703,7 +1734,7 @@ d_type (di)
a new substitution candidate. However, if the a new substitution candidate. However, if the
substitution was followed by template arguments, then substitution was followed by template arguments, then
the whole thing is a substitution candidate. */ the whole thing is a substitution candidate. */
if (ret->type == D_COMP_SUB_STD) if (ret != NULL && ret->type == D_COMP_SUB_STD)
can_subst = 0; can_subst = 0;
} }
} }
@ -1836,6 +1867,8 @@ d_bare_function_type (di, has_return_type)
else else
{ {
*ptl = d_make_comp (di, D_COMP_ARGLIST, type, NULL); *ptl = d_make_comp (di, D_COMP_ARGLIST, type, NULL);
if (*ptl == NULL)
return NULL;
ptl = &d_right (*ptl); ptl = &d_right (*ptl);
} }
} }
@ -1893,6 +1926,8 @@ d_array_type (di)
} }
while (IS_DIGIT (peek)); while (IS_DIGIT (peek));
dim = d_make_name (di, s, d_str (di) - s); dim = d_make_name (di, s, d_str (di) - s);
if (dim == NULL)
return NULL;
} }
else else
{ {
@ -1936,6 +1971,8 @@ d_pointer_to_member_type (di)
avoid calling add_substitution() in d_type(). */ avoid calling add_substitution() in d_type(). */
pmem = d_cv_qualifiers (di, &mem); pmem = d_cv_qualifiers (di, &mem);
if (pmem == NULL)
return NULL;
*pmem = d_type (di); *pmem = d_type (di);
return d_make_comp (di, D_COMP_PTRMEM_TYPE, cl, mem); return d_make_comp (di, D_COMP_PTRMEM_TYPE, cl, mem);
@ -1999,6 +2036,8 @@ d_template_args (di)
return NULL; return NULL;
*pal = d_make_comp (di, D_COMP_TEMPLATE_ARGLIST, a, NULL); *pal = d_make_comp (di, D_COMP_TEMPLATE_ARGLIST, a, NULL);
if (*pal == NULL)
return NULL;
pal = &d_right (*pal); pal = &d_right (*pal);
if (d_peek_char (di) == 'E') if (d_peek_char (di) == 'E')
@ -2152,7 +2191,7 @@ d_expr_primary (di)
if (d_next_char (di) != 'L') if (d_next_char (di) != 'L')
return NULL; return NULL;
if (d_peek_char (di) == '_') if (d_peek_char (di) == '_')
ret = d_mangled_name (di); ret = d_mangled_name (di, 0);
else else
{ {
struct d_comp *type; struct d_comp *type;
@ -2247,6 +2286,8 @@ d_add_substitution (di, dc)
struct d_info *di; struct d_info *di;
struct d_comp *dc; struct d_comp *dc;
{ {
if (dc == NULL)
return 0;
if (di->next_sub >= di->num_subs) if (di->next_sub >= di->num_subs)
return 0; return 0;
di->subs[di->next_sub] = dc; di->subs[di->next_sub] = dc;
@ -2341,6 +2382,8 @@ d_print_resize (dpi, add)
{ {
size_t need; size_t need;
if (dpi->buf == NULL)
return;
need = dpi->len + add; need = dpi->len + add;
while (need > dpi->alc) while (need > dpi->alc)
{ {
@ -2505,6 +2548,7 @@ d_print_comp (dpi, dc)
dpi->modifiers = &dpm; dpi->modifiers = &dpm;
dpm.mod = typed_name; dpm.mod = typed_name;
dpm.printed = 0; dpm.printed = 0;
dpm.templates = dpi->templates;
/* If typed_name is a template, then it applies to the /* If typed_name is a template, then it applies to the
function type as well. */ function type as well. */
@ -2545,15 +2589,29 @@ d_print_comp (dpi, dc)
} }
case D_COMP_TEMPLATE: case D_COMP_TEMPLATE:
d_print_comp (dpi, d_left (dc)); {
d_append_char (dpi, '<'); struct d_print_mod *hold_dpm;
d_print_comp (dpi, d_right (dc));
/* Avoid generating two consecutive '>' characters, to avoid the /* Don't push modifiers into a template definition. Doing so
C++ syntactic ambiguity. */ could give the wrong definition for a template argument.
if (dpi->buf[dpi->len - 1] == '>') Instead, treat the template essentially as a name. */
d_append_char (dpi, ' ');
d_append_char (dpi, '>'); hold_dpm = dpi->modifiers;
return; dpi->modifiers = NULL;
d_print_comp (dpi, d_left (dc));
d_append_char (dpi, '<');
d_print_comp (dpi, d_right (dc));
/* Avoid generating two consecutive '>' characters, to avoid
the C++ syntactic ambiguity. */
if (dpi->buf != NULL && dpi->buf[dpi->len - 1] == '>')
d_append_char (dpi, ' ');
d_append_char (dpi, '>');
dpi->modifiers = hold_dpm;
return;
}
case D_COMP_TEMPLATE_PARAM: case D_COMP_TEMPLATE_PARAM:
{ {
@ -2692,6 +2750,7 @@ d_print_comp (dpi, dc)
dpi->modifiers = &dpm; dpi->modifiers = &dpm;
dpm.mod = dc; dpm.mod = dc;
dpm.printed = 0; dpm.printed = 0;
dpm.templates = dpi->templates;
d_print_comp (dpi, d_left (dc)); d_print_comp (dpi, d_left (dc));
@ -2729,6 +2788,7 @@ d_print_comp (dpi, dc)
dpi->modifiers = &dpm; dpi->modifiers = &dpm;
dpm.mod = dc; dpm.mod = dc;
dpm.printed = 0; dpm.printed = 0;
dpm.templates = dpi->templates;
d_print_comp (dpi, d_left (dc)); d_print_comp (dpi, d_left (dc));
@ -2756,6 +2816,7 @@ d_print_comp (dpi, dc)
dpi->modifiers = &dpm; dpi->modifiers = &dpm;
dpm.mod = dc; dpm.mod = dc;
dpm.printed = 0; dpm.printed = 0;
dpm.templates = dpi->templates;
d_print_comp (dpi, d_right (dc)); d_print_comp (dpi, d_right (dc));
@ -2789,6 +2850,7 @@ d_print_comp (dpi, dc)
dpi->modifiers = &dpm; dpi->modifiers = &dpm;
dpm.mod = dc; dpm.mod = dc;
dpm.printed = 0; dpm.printed = 0;
dpm.templates = dpi->templates;
d_print_comp (dpi, target_type); d_print_comp (dpi, target_type);
@ -3035,29 +3097,36 @@ d_print_mod_list (dpi, mods)
struct d_print_info *dpi; struct d_print_info *dpi;
struct d_print_mod *mods; struct d_print_mod *mods;
{ {
struct d_print_template *hold_dpt;
if (mods == NULL || mods->printed || d_print_saw_error (dpi)) if (mods == NULL || mods->printed || d_print_saw_error (dpi))
return; return;
mods->printed = 1;
hold_dpt = dpi->templates;
dpi->templates = mods->templates;
if (mods->mod->type == D_COMP_FUNCTION_TYPE) if (mods->mod->type == D_COMP_FUNCTION_TYPE)
{ {
mods->printed = 1;
d_print_function_type (dpi, mods->mod, mods->next); d_print_function_type (dpi, mods->mod, mods->next);
dpi->templates = hold_dpt;
return; return;
} }
else if (mods->mod->type == D_COMP_ARRAY_TYPE) else if (mods->mod->type == D_COMP_ARRAY_TYPE)
{ {
mods->printed = 1;
d_print_array_type (dpi, mods->mod, mods->next); d_print_array_type (dpi, mods->mod, mods->next);
dpi->templates = hold_dpt;
return; return;
} }
mods->printed = 1;
d_print_mod (dpi, mods->mod); d_print_mod (dpi, mods->mod);
dpi->templates = hold_dpt;
d_print_mod_list (dpi, mods->next); d_print_mod_list (dpi, mods->next);
} }
/* Print a modifier. */ /* Print a modifier. */
static void static void
@ -3095,7 +3164,7 @@ d_print_mod (dpi, mod)
d_append_string (dpi, "imaginary "); d_append_string (dpi, "imaginary ");
return; return;
case D_COMP_PTRMEM_TYPE: case D_COMP_PTRMEM_TYPE:
if (dpi->buf[dpi->len - 1] != '(') if (dpi->buf != NULL && dpi->buf[dpi->len - 1] != '(')
d_append_char (dpi, ' '); d_append_char (dpi, ' ');
d_print_comp (dpi, d_left (mod)); d_print_comp (dpi, d_left (mod));
d_append_string (dpi, "::*"); d_append_string (dpi, "::*");
@ -3119,52 +3188,49 @@ d_print_function_type (dpi, dc, mods)
const struct d_comp *dc; const struct d_comp *dc;
struct d_print_mod *mods; struct d_print_mod *mods;
{ {
if (mods != NULL) int need_paren;
int saw_mod;
struct d_print_mod *p;
need_paren = 0;
saw_mod = 0;
for (p = mods; p != NULL; p = p->next)
{ {
int need_paren; if (p->printed)
int saw_mod; break;
struct d_print_mod *p;
need_paren = 0; saw_mod = 1;
saw_mod = 0; switch (p->mod->type)
for (p = mods; p != NULL; p = p->next)
{ {
if (p->printed) case D_COMP_RESTRICT:
break; case D_COMP_VOLATILE:
case D_COMP_CONST:
saw_mod = 1; case D_COMP_VENDOR_TYPE_QUAL:
switch (p->mod->type) case D_COMP_POINTER:
{ case D_COMP_REFERENCE:
case D_COMP_RESTRICT: case D_COMP_COMPLEX:
case D_COMP_VOLATILE: case D_COMP_IMAGINARY:
case D_COMP_CONST: case D_COMP_PTRMEM_TYPE:
case D_COMP_VENDOR_TYPE_QUAL: need_paren = 1;
case D_COMP_POINTER: break;
case D_COMP_REFERENCE: default:
case D_COMP_COMPLEX: break;
case D_COMP_IMAGINARY:
case D_COMP_PTRMEM_TYPE:
need_paren = 1;
break;
default:
break;
}
if (need_paren)
break;
} }
if (d_left (dc) != NULL && ! saw_mod)
need_paren = 1;
if (need_paren) if (need_paren)
d_append_char (dpi, '('); break;
d_print_mod_list (dpi, mods);
if (need_paren)
d_append_char (dpi, ')');
} }
if (d_left (dc) != NULL && ! saw_mod)
need_paren = 1;
if (need_paren)
d_append_char (dpi, '(');
d_print_mod_list (dpi, mods);
if (need_paren)
d_append_char (dpi, ')');
d_append_char (dpi, '('); d_append_char (dpi, '(');
if (d_right (dc) != NULL) if (d_right (dc) != NULL)
@ -3252,6 +3318,7 @@ d_print_cast (dpi, dc)
d_print_comp (dpi, d_left (dc)); d_print_comp (dpi, d_left (dc));
else else
{ {
struct d_print_mod *hold_dpm;
struct d_print_template dpt; struct d_print_template dpt;
/* It appears that for a templated cast operator, we need to put /* It appears that for a templated cast operator, we need to put
@ -3259,6 +3326,9 @@ d_print_cast (dpi, dc)
not for the parameters. The effect is that we need to handle not for the parameters. The effect is that we need to handle
the template printing here. FIXME: Verify this. */ the template printing here. FIXME: Verify this. */
hold_dpm = dpi->modifiers;
dpi->modifiers = NULL;
dpt.next = dpi->templates; dpt.next = dpi->templates;
dpi->templates = &dpt; dpi->templates = &dpt;
dpt.template = d_left (dc); dpt.template = d_left (dc);
@ -3271,9 +3341,11 @@ d_print_cast (dpi, dc)
d_print_comp (dpi, d_right (d_left (dc))); d_print_comp (dpi, d_right (d_left (dc)));
/* Avoid generating two consecutive '>' characters, to avoid /* Avoid generating two consecutive '>' characters, to avoid
the C++ syntactic ambiguity. */ the C++ syntactic ambiguity. */
if (dpi->buf[dpi->len - 1] == '>') if (dpi->buf != NULL && dpi->buf[dpi->len - 1] == '>')
d_append_char (dpi, ' '); d_append_char (dpi, ' ');
d_append_char (dpi, '>'); d_append_char (dpi, '>');
dpi->modifiers = hold_dpm;
} }
} }
@ -3301,9 +3373,8 @@ d_init_info (mangled, options, len, di)
di->next_comp = 0; di->next_comp = 0;
/* Similarly, we can not need more substitutions than there are /* Similarly, we can not need more substitutions than there are
chars in the mangled string divided by 2, since it takes at least chars in the mangled string. */
two chars to refer to a substitution. */ di->num_subs = len;
di->num_subs = (len + 1) / 2;
di->subs = (struct d_comp **) malloc (di->num_subs di->subs = (struct d_comp **) malloc (di->num_subs
* sizeof (struct d_comp *)); * sizeof (struct d_comp *));
di->next_sub = 0; di->next_sub = 0;
@ -3381,7 +3452,7 @@ d_demangle (mangled, options, palc)
} }
if (! type) if (! type)
dc = d_mangled_name (&di); dc = d_mangled_name (&di, 1);
else else
dc = d_type (&di); dc = d_type (&di);
@ -3584,7 +3655,7 @@ is_ctor_or_dtor (mangled, ctor_kind, dtor_kind)
if (! d_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di)) if (! d_init_info (mangled, DMGL_GNU_V3, strlen (mangled), &di))
return 0; return 0;
dc = d_mangled_name (&di); dc = d_mangled_name (&di, 1);
if (dc == NULL) if (dc == NULL)
return 0; return 0;

View File

@ -2879,6 +2879,14 @@ void f<1>(A<(1) + (((int)(-((float)3f800000))))>)
_ZNK11__gnu_debug16_Error_formatter14_M_format_wordImEEvPciPKcT_ _ZNK11__gnu_debug16_Error_formatter14_M_format_wordImEEvPciPKcT_
void __gnu_debug::_Error_formatter::_M_format_word<unsigned long>(char*, int, char const*, unsigned long) const void __gnu_debug::_Error_formatter::_M_format_word<unsigned long>(char*, int, char const*, unsigned long) const
# #
# The new demangler used to core dump on this.
--format=gnu-v3
_ZSt18uninitialized_copyIN9__gnu_cxx17__normal_iteratorIPSt4pairISsPFbP6sqlitePPcEESt6vectorIS9_SaIS9_EEEESE_ET0_T_SG_SF_
__gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > > std::uninitialized_copy<__gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > >, __gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > > >(__gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > >, __gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > >, __gnu_cxx::__normal_iterator<std::pair<std::string, bool (*)(sqlite*, char**)>*, std::vector<std::pair<std::string, bool (*)(sqlite*, char**)>, std::allocator<std::pair<std::string, bool (*)(sqlite*, char**)> > > >)
# The new demangler used to fail on this.
--format=gnu-v3
_Z1fP1cIPFiiEE
f(c<int (*)(int)>*)
# #
# This caused an infinite loop. # This caused an infinite loop.
# We still don't demangle this correctly, but at least we don't hang. # We still don't demangle this correctly, but at least we don't hang.