From 97ceaf5b4df58353b0a8e5663cb7ee6e4ae63605 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Mon, 15 Dec 2003 17:45:42 +0000 Subject: [PATCH] merge from gcc --- libiberty/ChangeLog | 34 ++++--- libiberty/cp-demangle.c | 134 ++++++++++++++++++++------ libiberty/testsuite/demangle-expected | 12 ++- 3 files changed, 136 insertions(+), 44 deletions(-) diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 42994f445a8..a2a430e3992 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,19 @@ +2003-12-15 Ian Lance Taylor + + 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 * cp-demangle.c (IS_UPPER, IS_LOWER): Define. @@ -123,10 +139,6 @@ * cp-demangle.c: Complete rewrite. -2003-11-20 Ian Lance Taylor - - * cp-demangle.c: Complete rewrite. - 2003-11-19 Mark Mitchell * cp-demangle.c (demangle_type): Correct thinko in substitution @@ -148,17 +160,17 @@ * testsuite/Makefile.in (test-demangle): Depend upon libiberty.a. -2003-11-18 Ian Lance Taylor - - * 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 * floatformat.c (floatformat_always_valid): Add unused attribute. +2003-10-30 Josef Zlomek + + Jan Hubicka + * 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 * hashtab.c (htab_find_slot_with_hash): Decrease n_deleted diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index a5835df549b..e675752bbaa 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 @@ -239,7 +256,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 +508,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 *, @@ -683,6 +702,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); @@ -737,6 +759,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; @@ -1087,7 +1110,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 +1225,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 +1799,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 +2277,7 @@ d_expr_primary (di) else { struct d_comp *type; + enum d_comp_type t; const char *s; type = d_type (di); @@ -2269,11 +2293,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; @@ -2363,11 +2392,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, std::allocator >", + "basic_string" }, + { 'i', "std::istream", + "std::basic_istream >", + "basic_istream" }, + { 'o', "std::ostream", + "std::basic_ostream >", + "basic_ostream" }, + { 'd', "std::iostream", + "std::basic_iostream >", + "basic_iostream" } +}; + static struct d_comp * -d_substitution (di) +d_substitution (di, prefix) struct d_info *di; + int prefix; { char c; @@ -2404,31 +2461,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; } } @@ -3031,6 +3093,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 +3102,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 +3112,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 +3122,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 +3147,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; diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index c47c6aea5fa..b39e2f4386b 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -2905,7 +2905,17 @@ bool std::operator< (std::pair 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 >::~basic_iostream() +# # This caused an infinite loop. # # This is generated by an EDG compiler (kcc 4.0). To demangle it -- 2.30.2