diff options
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/dyn-string.h | 29 | ||||
-rw-r--r-- | libiberty/ChangeLog | 27 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 166 | ||||
-rw-r--r-- | libiberty/dyn-string.c | 11 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 18 |
6 files changed, 184 insertions, 72 deletions
diff --git a/include/ChangeLog b/include/ChangeLog index e2fa68f..4e1ab9f 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2004-02-23 Ian Lance Taylor <ian@wasabisystems.com> + + * dyn-string.h: Remove test of IN_LIBGCC2 and IN_GLIBCPP_V3 and + the associated #defines. + 2004-01-12 Ian Lance Taylor <ian@wasabisystems.com> * demangle.h: Instead of checking ANSI_PROTOTYPES, just include diff --git a/include/dyn-string.h b/include/dyn-string.h index 2a771c7..aa5e385 100644 --- a/include/dyn-string.h +++ b/include/dyn-string.h @@ -40,35 +40,6 @@ typedef struct dyn_string (strcmp ((DS1)->s, (DS2)->s)) -/* dyn_string functions are used in the demangling implementation - included in the G++ runtime library. To prevent collisions with - names in user programs, the functions that are used in the - demangler are given implementation-reserved names. */ - -#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3) - -#define dyn_string_init __cxa_dyn_string_init -#define dyn_string_new __cxa_dyn_string_new -#define dyn_string_delete __cxa_dyn_string_delete -#define dyn_string_release __cxa_dyn_string_release -#define dyn_string_resize __cxa_dyn_string_resize -#define dyn_string_clear __cxa_dyn_string_clear -#define dyn_string_copy __cxa_dyn_string_copy -#define dyn_string_copy_cstr __cxa_dyn_string_copy_cstr -#define dyn_string_prepend __cxa_dyn_string_prepend -#define dyn_string_prepend_cstr __cxa_dyn_string_prepend_cstr -#define dyn_string_insert __cxa_dyn_string_insert -#define dyn_string_insert_cstr __cxa_dyn_string_insert_cstr -#define dyn_string_insert_char __cxa_dyn_string_insert_char -#define dyn_string_append __cxa_dyn_string_append -#define dyn_string_append_cstr __cxa_dyn_string_append_cstr -#define dyn_string_append_char __cxa_dyn_string_append_char -#define dyn_string_substring __cxa_dyn_string_substring -#define dyn_string_eq __cxa_dyn_string_eq - -#endif /* IN_LIBGCC2 || IN_GLIBCPP_V3 */ - - extern int dyn_string_init PARAMS ((struct dyn_string *, int)); extern dyn_string_t dyn_string_new PARAMS ((int)); extern void dyn_string_delete PARAMS ((dyn_string_t)); diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 08b7d5b..e21c34f 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,30 @@ +2004-02-24 Ian Lance Taylor <ian@wasabisystems.com> + + * cp-demangle.c (__cxa_demangle): Pass DMGL_PARAMS to d_demangle. + + * 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 + empty string correctly. + + * cp-demangle.c (__cxa_demangle): It is not an error if status is + not NULL. It is an error if the mangled name is the same as a + built-in type name. + (main): If IN_GLIBCPP_V3 is defined, test __cxa_demangle rather + than cplus_demangle_v3. + + * dyn-string.c: Remove test of IN_LIBGCC2 and IN_GLIBCPP_V3 and + the associated #define of RETURN_ON_ALLOCATION_FAILURE. + 2004-02-16 Matt Kraai <kraai@alumni.cmu.edu> * regex.c: Include <ansidecl.h>. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 19f191e..1205fcb 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; + } } } @@ -3944,29 +4009,46 @@ __cxa_demangle (mangled_name, output_buffer, length, status) char *demangled; size_t alc; - if (status == NULL) - return NULL; - if (mangled_name == NULL) { - *status = -3; + if (status != NULL) + *status = -3; return NULL; } if (output_buffer != NULL && length == NULL) { - *status = -3; + if (status != NULL) + *status = -3; return NULL; } - demangled = d_demangle (mangled_name, DMGL_TYPES, &alc); + /* The specification for __cxa_demangle() is that if the mangled + name could be either an extern "C" identifier, or an internal + built-in type name, then we resolve it as the identifier. All + internal built-in type names are a single lower case character. + Frankly, this simplistic disambiguation doesn't make sense to me, + but it is documented, so we implement it here. */ + if (IS_LOWER (mangled_name[0]) + && mangled_name[1] == '\0' + && cplus_demangle_builtin_types[mangled_name[0] - 'a'].name != NULL) + { + if (status != NULL) + *status = -2; + return NULL; + } + + demangled = d_demangle (mangled_name, DMGL_PARAMS | DMGL_TYPES, &alc); if (demangled == NULL) { - if (alc == 1) - *status = -1; - else - *status = -2; + if (status != NULL) + { + if (alc == 1) + *status = -1; + else + *status = -2; + } return NULL; } @@ -3990,7 +4072,8 @@ __cxa_demangle (mangled_name, output_buffer, length, status) } } - *status = 0; + if (status != NULL) + *status = 0; return demangled; } @@ -4296,7 +4379,11 @@ main (argc, argv) if (dyn_string_length (mangled) > 0) { +#ifdef IN_GLIBCPP_V3 + s = __cxa_demangle (dyn_string_buf (mangled), NULL, NULL, NULL); +#else s = cplus_demangle_v3 (dyn_string_buf (mangled), options); +#endif if (s != NULL) { @@ -4328,9 +4415,16 @@ main (argc, argv) for (i = optind; i < argc; ++i) { char *s; +#ifdef IN_GLIBCPP_V3 + int status; +#endif /* Attempt to demangle. */ +#ifdef IN_GLIBCPP_V3 + s = __cxa_demangle (argv[i], NULL, NULL, &status); +#else s = cplus_demangle_v3 (argv[i], options); +#endif /* If it worked, print the demangled name. */ if (s != NULL) @@ -4339,7 +4433,13 @@ main (argc, argv) free (s); } else - fprintf (stderr, "Failed: %s\n", argv[i]); + { +#ifdef IN_GLIBCPP_V3 + fprintf (stderr, "Failed: %s (status %d)\n", argv[i], status); +#else + fprintf (stderr, "Failed: %s\n", argv[i]); +#endif + } } } diff --git a/libiberty/dyn-string.c b/libiberty/dyn-string.c index 1da76c2..5d48cdc 100644 --- a/libiberty/dyn-string.c +++ b/libiberty/dyn-string.c @@ -1,5 +1,5 @@ /* An abstract string datatype. - Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc. Contributed by Mark Mitchell (mark@markmitchell.com). This file is part of GNU CC. @@ -45,15 +45,6 @@ Boston, MA 02111-1307, USA. */ #include "libiberty.h" #include "dyn-string.h" -/* If this file is being compiled for inclusion in the C++ runtime - library, as part of the demangler implementation, we don't want to - abort if an allocation fails. Instead, percolate an error code up - through the call chain. */ - -#if defined(IN_LIBGCC2) || defined(IN_GLIBCPP_V3) -#define RETURN_ON_ALLOCATION_FAILURE -#endif - /* Performs in-place initialization of a dyn_string struct. This function can be used with a dyn_string struct on the stack or embedded in another object. The contents of of the string itself 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<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. |