diff options
author | Ian Lance Taylor <ian@wasabisystems.com> | 2003-12-15 14:37:25 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2003-12-15 14:37:25 +0000 |
commit | 374caa503bcf9605a85f8b68c79ca2d918c96fb0 (patch) | |
tree | ceddf800710ca602c6497bf9eb391a6baf0c777f /libiberty | |
parent | 58cd2515ae19e8aac09b3615b0a105e055bb4081 (diff) | |
download | gcc-374caa503bcf9605a85f8b68c79ca2d918c96fb0.zip gcc-374caa503bcf9605a85f8b68c79ca2d918c96fb0.tar.gz gcc-374caa503bcf9605a85f8b68c79ca2d918c96fb0.tar.bz2 |
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.
From-SVN: r74632
Diffstat (limited to 'libiberty')
-rw-r--r-- | libiberty/ChangeLog | 16 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 134 | ||||
-rw-r--r-- | libiberty/testsuite/demangle-expected | 12 |
3 files changed, 129 insertions, 33 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index ef65982..a2a430e 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,19 @@ +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. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index a5835df..e675752 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<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 +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 c47c6ae..b39e2f4 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -2905,7 +2905,17 @@ 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() +# # This caused an infinite loop. # # This is generated by an EDG compiler (kcc 4.0). To demangle it |