diff options
author | Daniel Jacobowitz <drow@false.org> | 2003-12-20 18:16:52 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2003-12-20 18:16:52 +0000 |
commit | 543385e1777075e10b3d389433e514122708c277 (patch) | |
tree | 56625b15fdcffb483fab2537e00c64e9e90823c0 /libiberty | |
parent | 61547efc7fe23d6c09acd75051e45a5a978de09f (diff) | |
download | gdb-543385e1777075e10b3d389433e514122708c277.zip gdb-543385e1777075e10b3d389433e514122708c277.tar.gz gdb-543385e1777075e10b3d389433e514122708c277.tar.bz2 |
Merge from mainline.
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/ChangeLog | 71 | ||||
-rw-r--r-- | libiberty/Makefile.in | 3 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 277 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 38 |
4 files changed, 311 insertions, 78 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 42994f4..695c450 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,56 @@ +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 + parameters with no modifiers. + * testsuite/demangle-expected: Add test case. + + * cp-demangle.c (d_demangle): If DMGL_PARAMS is not set, don't + expect that we've read the entire string. + (is_ctor_or_dtor): Don't expect that we've read the entire + string--reverse patch of 2003-11-29. + +2003-12-15 Brendan Kehoe <brendan@zen.org> + + * libiberty/Makefile.in (floatformat.o): Add dependency on + config.h to accompany change of 2003-12-03. + +2003-12-15 Ian Lance Taylor <ian@wasabisystems.com> + + Fix handling of constructor/destructor of standard substitution: + * cp-demangle.c (struct d_standard_sub_info): Define. + (d_substitution): Add prefix argument. Change all callers. + Rework handling of standard substitutions to print full name when + qualifying a constructor/destructor, or when DMGL_VERBOSE is set. + * testsuite/demangle-expected: Add test case. + + Fix handling of negative literal constants: + * cp-demangle.c (enum d_comp_type): Add D_COMP_LITERAL_NEG. + (d_dump, d_make_comp): Handle D_COMP_LITERAL_NEG. + (d_expr_primary): Use D_COMP_LITERAL_NEG for a negative number. + (d_print_comp): Handle D_COMP_LITERAL_NEG. + * testsuite/demangle-expected: Add test case. + 2003-12-04 Ian Lance Taylor <ian@wasabisystems.com> * cp-demangle.c (IS_UPPER, IS_LOWER): Define. @@ -123,10 +176,6 @@ * cp-demangle.c: Complete rewrite. -2003-11-20 Ian Lance Taylor <ian@wasabisystems.com> - - * cp-demangle.c: Complete rewrite. - 2003-11-19 Mark Mitchell <mark@codesourcery.com> * cp-demangle.c (demangle_type): Correct thinko in substitution @@ -148,19 +197,19 @@ * testsuite/Makefile.in (test-demangle): Depend upon libiberty.a. -2003-11-18 Ian Lance Taylor <ian@wasabisystems.com> - - * testsuite/test-demangle.c (main): Don't pass DMGL_VERBOSE to - cplus_demangle. - - * testsuite/Makefile.in (test-demangle): Depend upon libiberty.a. - 2003-10-31 Andreas Jaeger <aj@suse.de> * floatformat.c (floatformat_always_valid): Add unused attribute. 2003-10-30 Josef Zlomek <zlomekj@suse.cz> + Jan Hubicka <jh@suse.cz> + * vasprintf.c (int_vasprintf): Pass va_list by value. + Use va_copy for copying va_list. + (vasprintf): Pass va_list by value. + +2003-10-30 Josef Zlomek <zlomekj@suse.cz> + * hashtab.c (htab_find_slot_with_hash): Decrease n_deleted instead of increasing n_elements when inserting to deleted slot. diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in index 5d2dc3c..5fff39b 100644 --- a/libiberty/Makefile.in +++ b/libiberty/Makefile.in @@ -437,7 +437,8 @@ dyn-string.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/dyn-string.h \ fdmatch.o: $(INCDIR)/ansidecl.h $(INCDIR)/libiberty.h fibheap.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/fibheap.h \ $(INCDIR)/libiberty.h -floatformat.o: $(INCDIR)/ansidecl.h $(INCDIR)/floatformat.h +floatformat.o: config.h $(INCDIR)/ansidecl.h $(INCDIR)/floatformat.h \ + $(INCDIR)/libiberty.h fnmatch.o: config.h $(INCDIR)/fnmatch.h $(INCDIR)/safe-ctype.h getcwd.o: config.h getopt.o: config.h $(INCDIR)/getopt.h diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index a5835df..27e09df 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -141,6 +141,23 @@ struct d_builtin_type_info enum d_builtin_type_print print; }; +/* Information we keep for the standard substitutions. */ + +struct d_standard_sub_info +{ + /* The code for this substitution. */ + char code; + /* The simple string it expands to. */ + const char *simple_expansion; + /* The results of a full, verbose, expansion. This is used when + qualifying a constructor/destructor, or when in verbose mode. */ + const char *full_expansion; + /* What to set the last_name field of d_info to; NULL if we should + not set it. This is only relevant when qualifying a + constructor/destructor. */ + const char *set_last_name; +}; + /* Component types found in mangled names. */ enum d_comp_type @@ -149,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. */ @@ -239,7 +258,9 @@ enum d_comp_type D_COMP_TRINARY_ARG1, D_COMP_TRINARY_ARG2, /* A literal. */ - D_COMP_LITERAL + D_COMP_LITERAL, + /* A negative literal. */ + D_COMP_LITERAL_NEG }; /* A component of the mangled name. */ @@ -489,7 +510,7 @@ static struct d_comp *d_expr_primary PARAMS ((struct d_info *)); static struct d_comp *d_local_name PARAMS ((struct d_info *)); static int d_discriminator PARAMS ((struct d_info *)); static int d_add_substitution PARAMS ((struct d_info *, struct d_comp *)); -static struct d_comp *d_substitution PARAMS ((struct d_info *)); +static struct d_comp *d_substitution PARAMS ((struct d_info *, int)); static void d_print_resize PARAMS ((struct d_print_info *, size_t)); static void d_print_append_char PARAMS ((struct d_print_info *, int)); static void d_print_append_buffer PARAMS ((struct d_print_info *, const char *, @@ -566,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; @@ -683,6 +707,9 @@ d_dump (dc, indent) case D_COMP_LITERAL: printf ("literal\n"); break; + case D_COMP_LITERAL_NEG: + printf ("negative literal\n"); + break; } d_dump (d_left (dc), indent + 2); @@ -726,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: @@ -737,6 +765,7 @@ d_make_comp (di, type, left, right) case D_COMP_TRINARY_ARG1: case D_COMP_TRINARY_ARG2: case D_COMP_LITERAL: + case D_COMP_LITERAL_NEG: if (left == NULL || right == NULL) return NULL; break; @@ -1002,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: @@ -1087,7 +1117,7 @@ d_name (di) if (d_peek_next_char (di) != 't') { - dc = d_substitution (di); + dc = d_substitution (di, 0); subst = 1; } else @@ -1202,7 +1232,7 @@ d_prefix (di) || peek == 'D') dc = d_unqualified_name (di); else if (peek == 'S') - dc = d_substitution (di); + dc = d_substitution (di, 1); else if (peek == 'I') { if (ret == NULL) @@ -1776,7 +1806,7 @@ d_type (di) || peek_next == '_' || IS_UPPER (peek_next)) { - ret = d_substitution (di); + ret = d_substitution (di, 0); /* The substituted name may have been a template name and may be followed by tepmlate args. */ if (d_peek_char (di) == 'I') @@ -2254,6 +2284,7 @@ d_expr_primary (di) else { struct d_comp *type; + enum d_comp_type t; const char *s; type = d_type (di); @@ -2269,11 +2300,16 @@ d_expr_primary (di) constant in any readable form anyhow. We don't attempt to handle these cases. */ + t = D_COMP_LITERAL; + if (d_peek_char (di) == 'n') + { + t = D_COMP_LITERAL_NEG; + d_advance (di, 1); + } s = d_str (di); while (d_peek_char (di) != 'E') d_advance (di, 1); - ret = d_make_comp (di, D_COMP_LITERAL, type, - d_make_name (di, s, d_str (di) - s)); + ret = d_make_comp (di, t, type, d_make_name (di, s, d_str (di) - s)); } if (d_next_char (di) != 'E') return NULL; @@ -2303,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)); } @@ -2314,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); } } @@ -2363,11 +2399,39 @@ d_add_substitution (di, dc) ::= Si ::= So ::= Sd + + If PREFIX is non-zero, then this type is being used as a prefix in + a qualified name. In this case, for the standard substitutions, we + need to check whether we are being used as a prefix for a + constructor or destructor, and return a full template name. + Otherwise we will get something like std::iostream::~iostream() + which does not correspond particularly well to any function which + actually appears in the source. */ +static const struct d_standard_sub_info standard_subs[] = +{ + { 't', "std", "std", NULL }, + { 'a', "std::allocator", "std::allocator", "allocator" }, + { 'b', "std::basic_string", "std::basic_string", "basic_string" }, + { 's', "std::string", + "std::basic_string<char, std::char_traits<char>, std::allocator<char> >", + "basic_string" }, + { 'i', "std::istream", + "std::basic_istream<char, std::char_traits<char> >", + "basic_istream" }, + { 'o', "std::ostream", + "std::basic_ostream<char, std::char_traits<char> >", + "basic_ostream" }, + { 'd', "std::iostream", + "std::basic_iostream<char, std::char_traits<char> >", + "basic_iostream" } +}; + static struct d_comp * -d_substitution (di) +d_substitution (di, prefix) struct d_info *di; + int prefix; { char c; @@ -2404,31 +2468,36 @@ d_substitution (di) } else { - switch (c) + int verbose; + const struct d_standard_sub_info *p; + const struct d_standard_sub_info *pend; + + verbose = (di->options & DMGL_VERBOSE) != 0; + if (! verbose && prefix) { - case 't': - return d_make_sub (di, "std"); - case 'a': - di->last_name = d_make_sub (di, "allocator"); - return d_make_sub (di, "std::allocator"); - case 'b': - di->last_name = d_make_sub (di, "basic_string"); - return d_make_sub (di, "std::basic_string"); - case 's': - di->last_name = d_make_sub (di, "string"); - return d_make_sub (di, "std::string"); - case 'i': - di->last_name = d_make_sub (di, "istream"); - return d_make_sub (di, "std::istream"); - case 'o': - di->last_name = d_make_sub (di, "ostream"); - return d_make_sub (di, "std::ostream"); - case 'd': - di->last_name = d_make_sub (di, "iostream"); - return d_make_sub (di, "std::iostream"); - default: - return NULL; + char peek; + + peek = d_peek_char (di); + if (peek == 'C' || peek == 'D') + verbose = 1; + } + + pend = (&standard_subs[0] + + sizeof standard_subs / sizeof standard_subs[0]); + for (p = &standard_subs[0]; p < pend; ++p) + { + if (c == p->code) + { + if (p->set_last_name != NULL) + di->last_name = d_make_sub (di, p->set_last_name); + if (verbose) + return d_make_sub (di, p->full_expansion); + else + return d_make_sub (di, p->simple_expansion); + } } + + return NULL; } } @@ -2579,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)); @@ -2630,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) @@ -3031,6 +3133,7 @@ d_print_comp (dpi, dc) return; case D_COMP_LITERAL: + case D_COMP_LITERAL_NEG: /* For some builtin types, produce simpler output. */ if (d_left (dc)->type == D_COMP_BUILTIN_TYPE) { @@ -3039,6 +3142,8 @@ d_print_comp (dpi, dc) case D_PRINT_INT: if (d_right (dc)->type == D_COMP_NAME) { + if (dc->type == D_COMP_LITERAL_NEG) + d_append_char (dpi, '-'); d_print_comp (dpi, d_right (dc)); return; } @@ -3047,6 +3152,8 @@ d_print_comp (dpi, dc) case D_PRINT_LONG: if (d_right (dc)->type == D_COMP_NAME) { + if (dc->type == D_COMP_LITERAL_NEG) + d_append_char (dpi, '-'); d_print_comp (dpi, d_right (dc)); d_append_char (dpi, 'l'); return; @@ -3055,7 +3162,8 @@ d_print_comp (dpi, dc) case D_PRINT_BOOL: if (d_right (dc)->type == D_COMP_NAME - && d_right (dc)->u.s_name.len == 1) + && d_right (dc)->u.s_name.len == 1 + && dc->type == D_COMP_LITERAL) { switch (d_right (dc)->u.s_name.s[0]) { @@ -3079,6 +3187,8 @@ d_print_comp (dpi, dc) d_append_char (dpi, '('); d_print_comp (dpi, d_left (dc)); d_append_char (dpi, ')'); + if (dc->type == D_COMP_LITERAL_NEG) + d_append_char (dpi, '-'); d_print_comp (dpi, d_right (dc)); return; @@ -3190,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); @@ -3265,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; @@ -3318,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) @@ -3331,6 +3473,8 @@ d_print_function_type (dpi, dc, mods) d_append_char (dpi, ')'); d_print_mod_list (dpi, mods, 1); + + dpi->modifiers = hold_modifiers; } /* Print an array type, except for the element type. */ @@ -3552,9 +3696,11 @@ d_demangle (mangled, options, palc) else dc = d_type (&di); - /* If we didn't consume the entire mangled string, then we didn't - successfully demangle it. */ - if (d_peek_char (&di) != '\0') + /* If DMGL_PARAMS is set, then if we didn't consume the entire + mangled string, then we didn't successfully demangle it. If + DMGL_PARAMS is not set, we didn't look at the trailing + parameters. */ + if (((options & DMGL_PARAMS) != 0) && d_peek_char (&di) != '\0') dc = NULL; #ifdef CP_DEMANGLE_DEBUG @@ -3759,37 +3905,38 @@ is_ctor_or_dtor (mangled, ctor_kind, dtor_kind) dc = d_mangled_name (&di, 1); + /* Note that because we did not pass DMGL_PARAMS, we don't expect to + demangle the entire string. */ + ret = 0; - if (d_peek_char (&di) == '\0') + while (dc != NULL) { - while (dc != NULL) + switch (dc->type) { - switch (dc->type) - { - default: - dc = NULL; - break; - case D_COMP_TYPED_NAME: - case D_COMP_TEMPLATE: - case D_COMP_RESTRICT_THIS: - case D_COMP_VOLATILE_THIS: - case D_COMP_CONST_THIS: - dc = d_left (dc); - break; - case D_COMP_QUAL_NAME: - dc = d_right (dc); - break; - case D_COMP_CTOR: - *ctor_kind = dc->u.s_ctor.kind; - ret = 1; - dc = NULL; - break; - case D_COMP_DTOR: - *dtor_kind = dc->u.s_dtor.kind; - ret = 1; - dc = NULL; - break; - } + default: + dc = NULL; + break; + case D_COMP_TYPED_NAME: + case D_COMP_TEMPLATE: + case D_COMP_RESTRICT_THIS: + case D_COMP_VOLATILE_THIS: + case D_COMP_CONST_THIS: + dc = d_left (dc); + break; + case D_COMP_QUAL_NAME: + case D_COMP_LOCAL_NAME: + dc = d_right (dc); + break; + case D_COMP_CTOR: + *ctor_kind = dc->u.s_ctor.kind; + ret = 1; + dc = NULL; + break; + case D_COMP_DTOR: + *dtor_kind = dc->u.s_dtor.kind; + ret = 1; + dc = NULL; + break; } } diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index c47c6ae..8bae90e 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -2905,7 +2905,43 @@ bool std::operator< <file_path, std::string>(std::pair<file_path, std::string> c --format=gnu-v3 _Z9hairyfuncM1YKFPVPFrPA2_PM1XKFKPA3_ilEPcEiE hairyfunc(int (* const (X::** (* restrict (* volatile*(Y::*)(int) const)(char*)) [2])(long) const) [3]) -# +# +# Check that negative numbers are handled correctly. +--format=gnu-v3 +_Z1fILin1EEvv +void f<-1>() +# +# Check a destructor of a standard substitution. +--format=gnu-v3 +_ZNSdD0Ev +std::basic_iostream<char, std::char_traits<char> >::~basic_iostream() +# +# Another case where we got member function qualifiers wrong. +--format=gnu-v3 +_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 |