+2004-02-24 Ian Lance Taylor <ian@wasabisystems.com>
+
+ * cp-demangle.c (d_print_comp) [RESTRICT, VOLATILE, CONST]: Don't
+ push more than one of the same CV-qualifier on the top of the
+ stack.
+ (d_print_comp) [ARRAY_TYPE]: If the array itself is CV-qualified,
+ move the CV-qualifiers to apply to the element type instead.
+ (d_print_array_type): When checking the modifiers, keep looking
+ past ones which have been printed already.
+ * testsuite/demangle-expected: Add three test cases.
+
2004-02-23 Ian Lance Taylor <ian@wasabisystems.com>
* cp-demangle.c (__cxa_demangle): Adjust last patch to handle
case DEMANGLE_COMPONENT_RESTRICT:
case DEMANGLE_COMPONENT_VOLATILE:
case DEMANGLE_COMPONENT_CONST:
+ {
+ struct d_print_mod *pdpm;
+
+ /* When printing arrays, it's possible to have cases where the
+ same CV-qualifier gets pushed on the stack multiple times.
+ We only need to print it once. */
+
+ for (pdpm = dpi->modifiers; pdpm != NULL; pdpm = pdpm->next)
+ {
+ if (! pdpm->printed)
+ {
+ if (pdpm->mod->type != DEMANGLE_COMPONENT_RESTRICT
+ && pdpm->mod->type != DEMANGLE_COMPONENT_VOLATILE
+ && pdpm->mod->type != DEMANGLE_COMPONENT_CONST)
+ break;
+ if (pdpm->mod->type == dc->type)
+ {
+ d_print_comp (dpi, d_left (dc));
+ return;
+ }
+ }
+ }
+ }
+ /* Fall through. */
case DEMANGLE_COMPONENT_RESTRICT_THIS:
case DEMANGLE_COMPONENT_VOLATILE_THIS:
case DEMANGLE_COMPONENT_CONST_THIS:
case DEMANGLE_COMPONENT_ARRAY_TYPE:
{
- struct d_print_mod dpm;
+ struct d_print_mod *hold_modifiers;
+ struct d_print_mod adpm[4];
+ unsigned int i;
+ struct d_print_mod *pdpm;
/* We must pass this type down as a modifier in order to print
- multi-dimensional arrays correctly. */
+ multi-dimensional arrays correctly. If the array itself is
+ CV-qualified, we act as though the element type were
+ CV-qualified. We do this by copying the modifiers down
+ rather than fiddling pointers, so that we don't wind up
+ with a d_print_mod higher on the stack pointing into our
+ stack frame after we return. */
- dpm.next = dpi->modifiers;
- dpi->modifiers = &dpm;
- dpm.mod = dc;
- dpm.printed = 0;
- dpm.templates = dpi->templates;
+ hold_modifiers = dpi->modifiers;
+
+ adpm[0].next = hold_modifiers;
+ dpi->modifiers = &adpm[0];
+ adpm[0].mod = dc;
+ adpm[0].printed = 0;
+ adpm[0].templates = dpi->templates;
+
+ i = 1;
+ pdpm = hold_modifiers;
+ while (pdpm != NULL
+ && (pdpm->mod->type == DEMANGLE_COMPONENT_RESTRICT
+ || pdpm->mod->type == DEMANGLE_COMPONENT_VOLATILE
+ || pdpm->mod->type == DEMANGLE_COMPONENT_CONST))
+ {
+ if (! pdpm->printed)
+ {
+ if (i >= sizeof adpm / sizeof adpm[0])
+ {
+ d_print_error (dpi);
+ return;
+ }
+
+ adpm[i] = *pdpm;
+ adpm[i].next = dpi->modifiers;
+ dpi->modifiers = &adpm[i];
+ pdpm->printed = 1;
+ ++i;
+ }
+
+ pdpm = pdpm->next;
+ }
d_print_comp (dpi, d_right (dc));
- dpi->modifiers = dpm.next;
+ dpi->modifiers = hold_modifiers;
- if (dpm.printed)
+ if (adpm[0].printed)
return;
+ while (i > 1)
+ {
+ --i;
+ d_print_mod (dpi, adpm[i].mod);
+ }
+
d_print_array_type (dpi, dc, dpi->modifiers);
return;
need_paren = 0;
for (p = mods; p != NULL; p = p->next)
{
- if (p->printed)
- break;
-
- if (p->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
- {
- need_space = 0;
- break;
- }
- else
+ if (! p->printed)
{
- need_paren = 1;
- need_space = 1;
- break;
+ if (p->mod->type == DEMANGLE_COMPONENT_ARRAY_TYPE)
+ {
+ need_space = 0;
+ break;
+ }
+ else
+ {
+ need_paren = 1;
+ need_space = 1;
+ break;
+ }
}
}
boost::spirit::match<rcs_deltatext>::operator void (boost::spirit::impl::dummy::*)()() const
boost::spirit::match<rcs_deltatext>::operator void (boost::spirit::impl::dummy::*)()
#
+# Multi-dimensional arrays with qualifiers on the inner dimensions.
+--format=gnu-v3 --no-params
+_Z3fooIA6_KiEvA9_KT_rVPrS4_
+void foo<int const [6]>(int const [9][6], int restrict const (* volatile restrict) [9][6])
+foo<int const [6]>
+#
+# From PR libstdc++/12736
+--format=gnu-v3 --no-params
+_Z3fooIA3_iEvRKT_
+void foo<int [3]>(int const (&) [3])
+foo<int [3]>
+#
+# Related to PR libstdc++/12736
+--format=gnu-v3 --no-params
+_Z3fooIPA3_iEvRKT_
+void foo<int (*) [3]>(int (* const&) [3])
+foo<int (*) [3]>
+#
# Test GNU V3 constructor and destructor identification.
# 0 means it is not a constructor/destructor.
# Other integers correspond to enum gnu_v3_{c,d}tor_kinds in demangle.h.