re PR c++/13447 (Another demangler problem with method cv-qualifiers)

Fix for PR c++/13447:
	* cp-demangle.c (enum d_comp_type): Add D_COMP_LOCAL_NAME.
	(d_dump, d_make_comp): Handle D_COMP_LOCAL_NAME.
	(is_ctor_dtor_or_conversion): Handle D_COMP_LOCAL_NAME like
	D_COMP_QUAL_NAME.
	(is_ctor_or_dtor): Likewise.
	(d_local_name): Use D_COMP_LOCAL_NAME rather than
	D_COMP_QUAL_NAME.
	(d_print_comp) [D_COMP_LOCAL_NAME]: New.
	(d_prinT_comp) [D_COMP_TYPED_NAME]: If the left tree is
	D_COMP_LOCAL_NAME, pull any qualifiers off its right subtree.
	(d_print_mod_list): Handle D_COMP_LOCAL_NAME.
	* testsuite/demangle-expected: Add two test cases.

	* cp-demangle.c (d_print_function_type): Clear the global modifier
	list when printing the modifiers, not just when printing the
	function parameters.
	* testsuite/demangle-expected: Add two test cases.

From-SVN: r74850
This commit is contained in:
Ian Lance Taylor 2003-12-19 21:14:35 +00:00 committed by Ian Lance Taylor
parent 4656bc859d
commit a91d1af087
3 changed files with 120 additions and 10 deletions

View File

@ -1,3 +1,24 @@
2003-12-19 Ian Lance Taylor <ian@wasabisystems.com>
Fix for PR c++/13447:
* cp-demangle.c (enum d_comp_type): Add D_COMP_LOCAL_NAME.
(d_dump, d_make_comp): Handle D_COMP_LOCAL_NAME.
(is_ctor_dtor_or_conversion): Handle D_COMP_LOCAL_NAME like
D_COMP_QUAL_NAME.
(is_ctor_or_dtor): Likewise.
(d_local_name): Use D_COMP_LOCAL_NAME rather than
D_COMP_QUAL_NAME.
(d_print_comp) [D_COMP_LOCAL_NAME]: New.
(d_prinT_comp) [D_COMP_TYPED_NAME]: If the left tree is
D_COMP_LOCAL_NAME, pull any qualifiers off its right subtree.
(d_print_mod_list): Handle D_COMP_LOCAL_NAME.
* testsuite/demangle-expected: Add two test cases.
* cp-demangle.c (d_print_function_type): Clear the global modifier
list when printing the modifiers, not just when printing the
function parameters.
* testsuite/demangle-expected: Add two test cases.
2003-12-15 Ian Lance Taylor <ian@wasabisystems.com>
* cp-demangle.c (d_print_function_type): Print the function

View File

@ -166,6 +166,8 @@ enum d_comp_type
D_COMP_NAME,
/* A qualified name. */
D_COMP_QUAL_NAME,
/* A local name. */
D_COMP_LOCAL_NAME,
/* A typed name. */
D_COMP_TYPED_NAME,
/* A template. */
@ -585,6 +587,9 @@ d_dump (dc, indent)
case D_COMP_QUAL_NAME:
printf ("qualified name\n");
break;
case D_COMP_LOCAL_NAME:
printf ("local name\n");
break;
case D_COMP_TYPED_NAME:
printf ("typed name\n");
break;
@ -748,6 +753,7 @@ d_make_comp (di, type, left, right)
{
/* These types require two parameters. */
case D_COMP_QUAL_NAME:
case D_COMP_LOCAL_NAME:
case D_COMP_TYPED_NAME:
case D_COMP_TEMPLATE:
case D_COMP_VENDOR_TYPE_QUAL:
@ -1025,6 +1031,7 @@ is_ctor_dtor_or_conversion (dc)
default:
return 0;
case D_COMP_QUAL_NAME:
case D_COMP_LOCAL_NAME:
return is_ctor_dtor_or_conversion (d_right (dc));
case D_COMP_CTOR:
case D_COMP_DTOR:
@ -2332,7 +2339,7 @@ d_local_name (di)
d_advance (di, 1);
if (! d_discriminator (di))
return NULL;
return d_make_comp (di, D_COMP_QUAL_NAME, function,
return d_make_comp (di, D_COMP_LOCAL_NAME, function,
d_make_name (di, "string literal",
sizeof "string literal" - 1));
}
@ -2343,7 +2350,7 @@ d_local_name (di)
name = d_name (di);
if (! d_discriminator (di))
return NULL;
return d_make_comp (di, D_COMP_QUAL_NAME, function, name);
return d_make_comp (di, D_COMP_LOCAL_NAME, function, name);
}
}
@ -2641,6 +2648,7 @@ d_print_comp (dpi, dc)
return;
case D_COMP_QUAL_NAME:
case D_COMP_LOCAL_NAME:
d_print_comp (dpi, d_left (dc));
d_append_string (dpi, (dpi->options & DMGL_JAVA) == 0 ? "::" : ".");
d_print_comp (dpi, d_right (dc));
@ -2692,6 +2700,38 @@ d_print_comp (dpi, dc)
dpt.template = typed_name;
}
/* If typed_name is a D_COMP_LOCAL_NAME, then there may be
CV-qualifiers on its right argument which really apply
here; this happens when parsing a class which is local to a
function. */
if (typed_name->type == D_COMP_LOCAL_NAME)
{
struct d_comp *local_name;
local_name = d_right (typed_name);
while (local_name->type == D_COMP_RESTRICT_THIS
|| local_name->type == D_COMP_VOLATILE_THIS
|| local_name->type == D_COMP_CONST_THIS)
{
if (i >= sizeof adpm / sizeof adpm[0])
{
d_print_error (dpi);
return;
}
adpm[i] = adpm[i - 1];
adpm[i].next = &adpm[i - 1];
dpi->modifiers = &adpm[i];
adpm[i - 1].mod = local_name;
adpm[i - 1].printed = 0;
adpm[i - 1].templates = dpi->templates;
++i;
local_name = d_left (local_name);
}
}
d_print_comp (dpi, d_right (dc));
if (typed_name->type == D_COMP_TEMPLATE)
@ -3260,6 +3300,34 @@ d_print_mod_list (dpi, mods, suffix)
dpi->templates = hold_dpt;
return;
}
else if (mods->mod->type == D_COMP_LOCAL_NAME)
{
struct d_print_mod *hold_modifiers;
struct d_comp *dc;
/* When this is on the modifier stack, we have pulled any
qualifiers off the right argument already. Otherwise, we
print it as usual, but don't let the left argument see any
modifiers. */
hold_modifiers = dpi->modifiers;
dpi->modifiers = NULL;
d_print_comp (dpi, d_left (mods->mod));
dpi->modifiers = hold_modifiers;
d_append_string (dpi, (dpi->options & DMGL_JAVA) == 0 ? "::" : ".");
dc = d_right (mods->mod);
while (dc->type == D_COMP_RESTRICT_THIS
|| dc->type == D_COMP_VOLATILE_THIS
|| dc->type == D_COMP_CONST_THIS)
dc = d_left (dc);
d_print_comp (dpi, dc);
dpi->templates = hold_dpt;
return;
}
d_print_mod (dpi, mods->mod);
@ -3335,6 +3403,7 @@ d_print_function_type (dpi, dc, mods)
int need_paren;
int saw_mod;
struct d_print_mod *p;
struct d_print_mod *hold_modifiers;
need_paren = 0;
saw_mod = 0;
@ -3388,6 +3457,9 @@ d_print_function_type (dpi, dc, mods)
d_append_char (dpi, '(');
}
hold_modifiers = dpi->modifiers;
dpi->modifiers = NULL;
d_print_mod_list (dpi, mods, 0);
if (need_paren)
@ -3396,18 +3468,13 @@ d_print_function_type (dpi, dc, mods)
d_append_char (dpi, '(');
if (d_right (dc) != NULL)
{
struct d_print_mod *hold_modifiers;
hold_modifiers = dpi->modifiers;
dpi->modifiers = NULL;
d_print_comp (dpi, d_right (dc));
dpi->modifiers = hold_modifiers;
}
d_print_comp (dpi, d_right (dc));
d_append_char (dpi, ')');
d_print_mod_list (dpi, mods, 1);
dpi->modifiers = hold_modifiers;
}
/* Print an array type, except for the element type. */
@ -3857,6 +3924,7 @@ is_ctor_or_dtor (mangled, ctor_kind, dtor_kind)
dc = d_left (dc);
break;
case D_COMP_QUAL_NAME:
case D_COMP_LOCAL_NAME:
dc = d_right (dc);
break;
case D_COMP_CTOR:

View File

@ -2921,6 +2921,27 @@ std::basic_iostream<char, std::char_traits<char> >::~basic_iostream()
_ZNK15nsBaseHashtableI15nsUint32HashKey8nsCOMPtrI4IFooEPS2_E13EnumerateReadEPF15PLDHashOperatorRKjS4_PvES9_
nsBaseHashtable<nsUint32HashKey, nsCOMPtr<IFoo>, IFoo*>::EnumerateRead(PLDHashOperator (*)(unsigned int const&, IFoo*, void*), void*) const
#
# Another member function qualifier test case, when the member function
# returns a pointer to function.
--format=gnu-v3
_ZNK1C1fIiEEPFivEv
int (*C::f<int>() const)()
#
# Another case where we got member function qualifiers wrong.
--format=gnu-v3
_ZZ3BBdI3FooEvvENK3Fob3FabEv
void BBd<Foo>()::Fob::Fab() const
#
# The same idea one level deeper.
--format=gnu-v3
_ZZZ3BBdI3FooEvvENK3Fob3FabEvENK3Gob3GabEv
void BBd<Foo>()::Fob::Fab() const::Gob::Gab() const
#
# Yet another member function qualifier problem.
--format=gnu-v3
_ZNK5boost6spirit5matchI13rcs_deltatextEcvMNS0_4impl5dummyEFvvEEv
boost::spirit::match<rcs_deltatext>::operator void (boost::spirit::impl::dummy::*)()() const
#
# This caused an infinite loop.
#
# This is generated by an EDG compiler (kcc 4.0). To demangle it