diff options
author | DJ Delorie <dj@redhat.com> | 2003-12-15 17:45:42 +0000 |
---|---|---|
committer | DJ Delorie <dj@redhat.com> | 2003-12-15 17:45:42 +0000 |
commit | 97ceaf5b4df58353b0a8e5663cb7ee6e4ae63605 (patch) | |
tree | 947568cb9d232c502316f07f18b7e543cdb63f37 /libiberty/cp-demangle.c | |
parent | a711c44f29cfb1af925157ef24ec9254ccd0e68a (diff) | |
download | gdb-97ceaf5b4df58353b0a8e5663cb7ee6e4ae63605.zip gdb-97ceaf5b4df58353b0a8e5663cb7ee6e4ae63605.tar.gz gdb-97ceaf5b4df58353b0a8e5663cb7ee6e4ae63605.tar.bz2 |
merge from gcc
Diffstat (limited to 'libiberty/cp-demangle.c')
-rw-r--r-- | libiberty/cp-demangle.c | 134 |
1 files changed, 102 insertions, 32 deletions
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; |