From: Ian Lance Taylor Date: Tue, 24 Feb 2004 06:32:16 +0000 (+0000) Subject: cp-demangle.c (d_print_comp): Don't push more than one of the same CV-qualifier on... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=80a19ac825df0014e1e6ef95cc980bf7414e1a6a;p=platform%2Fupstream%2Fgcc.git cp-demangle.c (d_print_comp): Don't push more than one of the same CV-qualifier on the top of the stack. * 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. From-SVN: r78354 --- diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index a43fb90..aa88173 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,14 @@ +2004-02-24 Ian Lance Taylor + + * 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 * cp-demangle.c (__cxa_demangle): Adjust last patch to handle diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index be7a569..18735be 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -3050,6 +3050,30 @@ d_print_comp (dpi, dc) 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: @@ -3125,24 +3149,65 @@ d_print_comp (dpi, dc) 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; @@ -3643,19 +3708,19 @@ d_print_array_type (dpi, dc, mods) 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; + } } } diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 25e8830..5ede7ab 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3681,6 +3681,24 @@ _ZNK5boost6spirit5matchI13rcs_deltatextEcvMNS0_4impl5dummyEFvvEEv boost::spirit::match::operator void (boost::spirit::impl::dummy::*)()() const boost::spirit::match::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 [9][6], int restrict const (* volatile restrict) [9][6]) +foo +# +# From PR libstdc++/12736 +--format=gnu-v3 --no-params +_Z3fooIA3_iEvRKT_ +void foo(int const (&) [3]) +foo +# +# Related to PR libstdc++/12736 +--format=gnu-v3 --no-params +_Z3fooIPA3_iEvRKT_ +void foo(int (* const&) [3]) +foo +# # 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.