X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=libiberty%2Fcp-demangle.c;h=d2d15e9b91aa83e85156b4340414766a8517bc89;hb=8e64f2a0d16624f14501c568f4bb2d7d79be9670;hp=4f309ef992ba5ba634f150ffdd37106bacdbad00;hpb=4e55d6c3ee45302988c77b7c1af1d842607ae416;p=binutils-gdb.git diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 4f309ef992b..d2d15e9b91a 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -1,5 +1,5 @@ /* Demangler for g++ V3 ABI. - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 + Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Written by Ian Lance Taylor . @@ -302,6 +302,8 @@ struct d_print_info /* The current index into any template argument packs we are using for printing. */ int pack_index; + /* Number of d_print_flush calls so far. */ + unsigned long int flush_count; }; #ifdef CP_DEMANGLE_DEBUG @@ -389,6 +391,8 @@ d_class_enum_type (struct d_info *); static struct demangle_component *d_array_type (struct d_info *); +static struct demangle_component *d_vector_type (struct d_info *); + static struct demangle_component * d_pointer_to_member_type (struct d_info *); @@ -408,6 +412,10 @@ static struct demangle_component *d_local_name (struct d_info *); static int d_discriminator (struct d_info *); +static struct demangle_component *d_lambda (struct d_info *); + +static struct demangle_component *d_unnamed_type (struct d_info *); + static int d_add_substitution (struct d_info *, struct demangle_component *); @@ -792,6 +800,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_LITERAL: case DEMANGLE_COMPONENT_LITERAL_NEG: case DEMANGLE_COMPONENT_COMPOUND_NAME: + case DEMANGLE_COMPONENT_VECTOR_TYPE: if (left == NULL || right == NULL) return NULL; break; @@ -819,6 +828,8 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_JAVA_RESOURCE: case DEMANGLE_COMPONENT_DECLTYPE: case DEMANGLE_COMPONENT_PACK_EXPANSION: + case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: + case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: if (left == NULL) return NULL; break; @@ -920,6 +931,20 @@ d_make_extended_operator (struct d_info *di, int args, return p; } +static struct demangle_component * +d_make_default_arg (struct d_info *di, int num, + struct demangle_component *sub) +{ + struct demangle_component *p = d_make_empty (di); + if (p) + { + p->type = DEMANGLE_COMPONENT_DEFAULT_ARG; + p->u.s_unary_num.num = num; + p->u.s_unary_num.sub = sub; + } + return p; +} + /* Add a new constructor component. */ static struct demangle_component * @@ -1151,8 +1176,9 @@ d_name (struct d_info *di) return d_local_name (di); case 'L': + case 'U': return d_unqualified_name (di); - + case 'S': { int subst; @@ -1274,6 +1300,7 @@ d_prefix (struct d_info *di) || IS_LOWER (peek) || peek == 'C' || peek == 'D' + || peek == 'U' || peek == 'L') dc = d_unqualified_name (di); else if (peek == 'S') @@ -1289,6 +1316,16 @@ d_prefix (struct d_info *di) dc = d_template_param (di); else if (peek == 'E') return ret; + else if (peek == 'M') + { + /* Initializer scope for a lambda. We don't need to represent + this; the normal code will just treat the variable as a type + scope, which gives appropriate output. */ + if (ret == NULL) + return NULL; + d_advance (di, 1); + continue; + } else return NULL; @@ -1345,6 +1382,18 @@ d_unqualified_name (struct d_info *di) return NULL; return ret; } + else if (peek == 'U') + { + switch (d_peek_next_char (di)) + { + case 'l': + return d_lambda (di); + case 't': + return d_unnamed_type (di); + default: + return NULL; + } + } else return NULL; } @@ -1398,6 +1447,20 @@ d_number (struct d_info *di) } } +/* Like d_number, but returns a demangle_component. */ + +static struct demangle_component * +d_number_component (struct d_info *di) +{ + struct demangle_component *ret = d_make_empty (di); + if (ret) + { + ret->type = DEMANGLE_COMPONENT_NUMBER; + ret->u.s_number.number = d_number (di); + } + return ret; +} + /* identifier ::= <(unqualified source code identifier)> */ static struct demangle_component * @@ -1926,6 +1989,8 @@ cplus_demangle_builtin_types[D_BUILTIN_TYPE_COUNT] = /* 29 */ { NL ("half"), NL ("half"), D_PRINT_FLOAT }, /* 30 */ { NL ("char16_t"), NL ("char16_t"), D_PRINT_DEFAULT }, /* 31 */ { NL ("char32_t"), NL ("char32_t"), D_PRINT_DEFAULT }, + /* 32 */ { NL ("decltype(nullptr)"), NL ("decltype(nullptr)"), + D_PRINT_DEFAULT }, }; CP_STATIC_IF_GLIBCPP_V3 @@ -2149,11 +2214,23 @@ cplus_demangle_type (struct d_info *di) /* For demangling we don't care about the bits. */ d_number (di); ret->u.s_fixed.length = cplus_demangle_type (di); + if (ret->u.s_fixed.length == NULL) + return NULL; d_number (di); peek = d_next_char (di); ret->u.s_fixed.sat = (peek == 's'); break; + case 'v': + ret = d_vector_type (di); + break; + + case 'n': + /* decltype(nullptr) */ + ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[32]); + di->expansion += ret->u.s_builtin.type->len; + break; + default: return NULL; } @@ -2240,50 +2317,30 @@ d_function_type (struct d_info *di) return ret; } -/* ::= [J]+ */ +/* + */ static struct demangle_component * -d_bare_function_type (struct d_info *di, int has_return_type) +d_parmlist (struct d_info *di) { - struct demangle_component *return_type; struct demangle_component *tl; struct demangle_component **ptl; - char peek; - /* Detect special qualifier indicating that the first argument - is the return type. */ - peek = d_peek_char (di); - if (peek == 'J') - { - d_advance (di, 1); - has_return_type = 1; - } - - return_type = NULL; tl = NULL; ptl = &tl; while (1) { struct demangle_component *type; - peek = d_peek_char (di); + char peek = d_peek_char (di); if (peek == '\0' || peek == 'E') break; type = cplus_demangle_type (di); if (type == NULL) return NULL; - if (has_return_type) - { - return_type = type; - has_return_type = 0; - } - else - { - *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL); - if (*ptl == NULL) - return NULL; - ptl = &d_right (*ptl); - } + *ptl = d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, type, NULL); + if (*ptl == NULL) + return NULL; + ptl = &d_right (*ptl); } /* There should be at least one parameter type besides the optional @@ -2298,10 +2355,45 @@ d_bare_function_type (struct d_info *di, int has_return_type) && d_left (tl)->u.s_builtin.type->print == D_PRINT_VOID) { di->expansion -= d_left (tl)->u.s_builtin.type->len; - tl = NULL; + d_left (tl) = NULL; + } + + return tl; +} + +/* ::= [J]+ */ + +static struct demangle_component * +d_bare_function_type (struct d_info *di, int has_return_type) +{ + struct demangle_component *return_type; + struct demangle_component *tl; + char peek; + + /* Detect special qualifier indicating that the first argument + is the return type. */ + peek = d_peek_char (di); + if (peek == 'J') + { + d_advance (di, 1); + has_return_type = 1; + } + + if (has_return_type) + { + return_type = cplus_demangle_type (di); + if (return_type == NULL) + return NULL; } + else + return_type = NULL; - return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, return_type, tl); + tl = d_parmlist (di); + if (tl == NULL) + return NULL; + + return d_make_comp (di, DEMANGLE_COMPONENT_FUNCTION_TYPE, + return_type, tl); } /* ::= */ @@ -2357,6 +2449,34 @@ d_array_type (struct d_info *di) cplus_demangle_type (di)); } +/* ::= Dv _ + ::= Dv _ _ */ + +static struct demangle_component * +d_vector_type (struct d_info *di) +{ + char peek; + struct demangle_component *dim; + + peek = d_peek_char (di); + if (peek == '_') + { + d_advance (di, 1); + dim = d_expression (di); + } + else + dim = d_number_component (di); + + if (dim == NULL) + return NULL; + + if (! d_check_char (di, '_')) + return NULL; + + return d_make_comp (di, DEMANGLE_COMPONENT_VECTOR_TYPE, dim, + cplus_demangle_type (di)); +} + /* ::= M <(class) type> <(member) type> */ static struct demangle_component * @@ -2403,6 +2523,24 @@ d_pointer_to_member_type (struct d_info *di) return d_make_comp (di, DEMANGLE_COMPONENT_PTRMEM_TYPE, cl, mem); } +/* _ */ + +static long +d_compact_number (struct d_info *di) +{ + long num; + if (d_peek_char (di) == '_') + num = 0; + else if (d_peek_char (di) == 'n') + return -1; + else + num = d_number (di) + 1; + + if (! d_check_char (di, '_')) + return -1; + return num; +} + /* ::= T_ ::= T <(parameter-2 non-negative) number> _ */ @@ -2415,17 +2553,8 @@ d_template_param (struct d_info *di) if (! d_check_char (di, 'T')) return NULL; - if (d_peek_char (di) == '_') - param = 0; - else - { - param = d_number (di); - if (param < 0) - return NULL; - param += 1; - } - - if (! d_check_char (di, '_')) + param = d_compact_number (di); + if (param < 0) return NULL; ++di->did_subs; @@ -2597,26 +2726,24 @@ d_expression (struct d_info *di) /* Function parameter used in a late-specified return type. */ int index; d_advance (di, 2); - if (d_peek_char (di) == '_') - index = 1; - else - { - index = d_number (di); - if (index < 0) - return NULL; - index += 2; - } - - if (! d_check_char (di, '_')) + index = d_compact_number (di); + if (index < 0) return NULL; return d_make_function_param (di, index); } - else if (IS_DIGIT (peek)) + else if (IS_DIGIT (peek) + || (peek == 'o' && d_peek_next_char (di) == 'n')) { /* We can get an unqualified name as an expression in the case of - a dependent member access, i.e. decltype(T().i). */ - struct demangle_component *name = d_unqualified_name (di); + a dependent function call, i.e. decltype(f(t)). */ + struct demangle_component *name; + + if (peek == 'o') + /* operator-function-id, i.e. operator+(t). */ + d_advance (di, 2); + + name = d_unqualified_name (di); if (name == NULL) return NULL; if (d_peek_char (di) == 'I') @@ -2674,10 +2801,18 @@ d_expression (struct d_info *di) { struct demangle_component *left; struct demangle_component *right; + const char *code = op->u.s_operator.op->code; left = d_expression (di); - if (!strcmp (op->u.s_operator.op->code, "cl")) + if (!strcmp (code, "cl")) right = d_exprlist (di); + else if (!strcmp (code, "dt") || !strcmp (code, "pt")) + { + right = d_unqualified_name (di); + if (d_peek_char (di) == 'I') + right = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, + right, d_template_args (di)); + } else right = d_expression (di); @@ -2800,10 +2935,31 @@ d_local_name (struct d_info *di) else { struct demangle_component *name; + int num = -1; + + if (d_peek_char (di) == 'd') + { + /* Default argument scope: d _. */ + d_advance (di, 1); + num = d_compact_number (di); + if (num < 0) + return NULL; + } name = d_name (di); - if (! d_discriminator (di)) - return NULL; + if (name) + switch (name->type) + { + /* Lambdas and unnamed types have internal discriminators. */ + case DEMANGLE_COMPONENT_LAMBDA: + case DEMANGLE_COMPONENT_UNNAMED_TYPE: + break; + default: + if (! d_discriminator (di)) + return NULL; + } + if (num >= 0) + name = d_make_default_arg (di, num, name); return d_make_comp (di, DEMANGLE_COMPONENT_LOCAL_NAME, function, name); } } @@ -2827,6 +2983,75 @@ d_discriminator (struct d_info *di) return 1; } +/* ::= Ul E [ ] _ */ + +static struct demangle_component * +d_lambda (struct d_info *di) +{ + struct demangle_component *tl; + struct demangle_component *ret; + int num; + + if (! d_check_char (di, 'U')) + return NULL; + if (! d_check_char (di, 'l')) + return NULL; + + tl = d_parmlist (di); + if (tl == NULL) + return NULL; + + if (! d_check_char (di, 'E')) + return NULL; + + num = d_compact_number (di); + if (num < 0) + return NULL; + + ret = d_make_empty (di); + if (ret) + { + ret->type = DEMANGLE_COMPONENT_LAMBDA; + ret->u.s_unary_num.sub = tl; + ret->u.s_unary_num.num = num; + } + + if (! d_add_substitution (di, ret)) + return NULL; + + return ret; +} + +/* ::= Ut [ ] _ */ + +static struct demangle_component * +d_unnamed_type (struct d_info *di) +{ + struct demangle_component *ret; + long num; + + if (! d_check_char (di, 'U')) + return NULL; + if (! d_check_char (di, 't')) + return NULL; + + num = d_compact_number (di); + if (num < 0) + return NULL; + + ret = d_make_empty (di); + if (ret) + { + ret->type = DEMANGLE_COMPONENT_UNNAMED_TYPE; + ret->u.s_number.number = num; + } + + if (! d_add_substitution (di, ret)) + return NULL; + + return ret; +} + /* Add a new substitution. */ static int @@ -3062,6 +3287,7 @@ d_print_init (struct d_print_info *dpi, int options, dpi->last_char = '\0'; dpi->templates = NULL; dpi->modifiers = NULL; + dpi->flush_count = 0; dpi->callback = callback; dpi->opaque = opaque; @@ -3091,6 +3317,7 @@ d_print_flush (struct d_print_info *dpi) dpi->buf[dpi->len] = '\0'; dpi->callback (dpi->buf, dpi->len, dpi->opaque); dpi->len = 0; + dpi->flush_count++; } /* Append characters and buffers for printing. */ @@ -3120,6 +3347,14 @@ d_append_string (struct d_print_info *dpi, const char *s) d_append_buffer (dpi, s, strlen (s)); } +static inline void +d_append_num (struct d_print_info *dpi, long l) +{ + char buf[25]; + sprintf (buf,"%ld", l); + d_append_string (dpi, buf); +} + static inline char d_last_char (struct d_print_info *dpi) { @@ -3396,6 +3631,8 @@ d_print_comp (struct d_print_info *dpi, struct demangle_component *local_name; local_name = d_right (typed_name); + if (local_name->type == DEMANGLE_COMPONENT_DEFAULT_ARG) + local_name = local_name->u.s_unary_num.sub; while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS || local_name->type == DEMANGLE_COMPONENT_CONST_THIS) @@ -3769,6 +4006,7 @@ d_print_comp (struct d_print_info *dpi, } case DEMANGLE_COMPONENT_PTRMEM_TYPE: + case DEMANGLE_COMPONENT_VECTOR_TYPE: { struct d_print_mod dpm; @@ -3783,11 +4021,7 @@ d_print_comp (struct d_print_info *dpi, /* If the modifier didn't get printed by the type, print it now. */ if (! dpm.printed) - { - d_append_char (dpi, ' '); - d_print_comp (dpi, d_left (dc)); - d_append_string (dpi, "::*"); - } + d_print_mod (dpi, dc); dpi->modifiers = dpm.next; @@ -3817,12 +4051,18 @@ d_print_comp (struct d_print_info *dpi, if (d_right (dc) != NULL) { size_t len; + unsigned long int flush_count; + /* Make sure ", " isn't flushed by d_append_string, otherwise + dpi->len -= 2 wouldn't work. */ + if (dpi->len >= sizeof (dpi->buf) - 2) + d_print_flush (dpi); d_append_string (dpi, ", "); len = dpi->len; + flush_count = dpi->flush_count; d_print_comp (dpi, d_right (dc)); /* If that didn't print anything (which can happen with empty template argument packs), remove the comma and space. */ - if (dpi->len == len) + if (dpi->flush_count == flush_count && dpi->len == len) dpi->len -= 2; } return; @@ -3878,9 +4118,18 @@ d_print_comp (struct d_print_info *dpi, d_append_char (dpi, '('); d_print_subexpr (dpi, d_left (d_right (dc))); - if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0) - d_print_expr_op (dpi, d_left (dc)); - d_print_subexpr (dpi, d_right (d_right (dc))); + if (strcmp (d_left (dc)->u.s_operator.op->code, "ix") == 0) + { + d_append_char (dpi, '['); + d_print_comp (dpi, d_right (d_right (dc))); + d_append_char (dpi, ']'); + } + else + { + if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0) + d_print_expr_op (dpi, d_left (dc)); + d_print_subexpr (dpi, d_right (d_right (dc))); + } if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR && d_left (dc)->u.s_operator.op->len == 1 @@ -3998,6 +4247,10 @@ d_print_comp (struct d_print_info *dpi, } return; + case DEMANGLE_COMPONENT_NUMBER: + d_append_num (dpi, dc->u.s_number.number); + return; + case DEMANGLE_COMPONENT_JAVA_RESOURCE: d_append_string (dpi, "java resource "); d_print_comp (dpi, d_left (dc)); @@ -4046,13 +4299,34 @@ d_print_comp (struct d_print_info *dpi, return; case DEMANGLE_COMPONENT_FUNCTION_PARAM: - { - char buf[25]; - d_append_string (dpi, "parm#"); - sprintf(buf,"%ld", dc->u.s_number.number); - d_append_string (dpi, buf); - return; - } + d_append_string (dpi, "{parm#"); + d_append_num (dpi, dc->u.s_number.number + 1); + d_append_char (dpi, '}'); + return; + + case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: + d_append_string (dpi, "global constructors keyed to "); + d_print_comp (dpi, dc->u.s_binary.left); + return; + + case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: + d_append_string (dpi, "global destructors keyed to "); + d_print_comp (dpi, dc->u.s_binary.left); + return; + + case DEMANGLE_COMPONENT_LAMBDA: + d_append_string (dpi, "{lambda("); + d_print_comp (dpi, dc->u.s_unary_num.sub); + d_append_string (dpi, ")#"); + d_append_num (dpi, dc->u.s_unary_num.num + 1); + d_append_char (dpi, '}'); + return; + + case DEMANGLE_COMPONENT_UNNAMED_TYPE: + d_append_string (dpi, "{unnamed type#"); + d_append_num (dpi, dc->u.s_number.number + 1); + d_append_char (dpi, '}'); + return; default: d_print_error (dpi); @@ -4172,6 +4446,15 @@ d_print_mod_list (struct d_print_info *dpi, d_append_char (dpi, '.'); dc = d_right (mods->mod); + + if (dc->type == DEMANGLE_COMPONENT_DEFAULT_ARG) + { + d_append_string (dpi, "{default arg#"); + d_append_num (dpi, dc->u.s_unary_num.num + 1); + d_append_string (dpi, "}::"); + dc = dc->u.s_unary_num.sub; + } + while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS || dc->type == DEMANGLE_COMPONENT_CONST_THIS) @@ -4240,6 +4523,12 @@ d_print_mod (struct d_print_info *dpi, case DEMANGLE_COMPONENT_TYPED_NAME: d_print_comp (dpi, d_left (mod)); return; + case DEMANGLE_COMPONENT_VECTOR_TYPE: + d_append_string (dpi, " __vector("); + d_print_comp (dpi, d_left (mod)); + d_append_char (dpi, ')'); + return; + default: /* Otherwise, we have something that won't go back on the modifier stack, so we can just print it. */ @@ -4484,33 +4773,30 @@ static int d_demangle_callback (const char *mangled, int options, demangle_callbackref callback, void *opaque) { - int type; + enum + { + DCT_TYPE, + DCT_MANGLED, + DCT_GLOBAL_CTORS, + DCT_GLOBAL_DTORS + } + type; struct d_info di; struct demangle_component *dc; int status; if (mangled[0] == '_' && mangled[1] == 'Z') - type = 0; + type = DCT_MANGLED; else if (strncmp (mangled, "_GLOBAL_", 8) == 0 && (mangled[8] == '.' || mangled[8] == '_' || mangled[8] == '$') && (mangled[9] == 'D' || mangled[9] == 'I') && mangled[10] == '_') - { - const char *intro; - - intro = (mangled[9] == 'I') - ? "global constructors keyed to " - : "global destructors keyed to "; - - callback (intro, strlen (intro), opaque); - callback (mangled + 11, strlen (mangled + 11), opaque); - return 1; - } + type = mangled[9] == 'I' ? DCT_GLOBAL_CTORS : DCT_GLOBAL_DTORS; else { if ((options & DMGL_TYPES) == 0) return 0; - type = 1; + type = DCT_TYPE; } cplus_demangle_init_info (mangled, options, strlen (mangled), &di); @@ -4527,10 +4813,26 @@ d_demangle_callback (const char *mangled, int options, di.subs = alloca (di.num_subs * sizeof (*di.subs)); #endif - if (type) - dc = cplus_demangle_type (&di); - else - dc = cplus_demangle_mangled_name (&di, 1); + switch (type) + { + case DCT_TYPE: + dc = cplus_demangle_type (&di); + break; + case DCT_MANGLED: + dc = cplus_demangle_mangled_name (&di, 1); + break; + case DCT_GLOBAL_CTORS: + case DCT_GLOBAL_DTORS: + d_advance (&di, 11); + dc = d_make_comp (&di, + (type == DCT_GLOBAL_CTORS + ? DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS + : DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS), + d_make_name (&di, d_str (&di), strlen (d_str (&di))), + NULL); + d_advance (&di, strlen (d_str (&di))); + break; + } /* If DMGL_PARAMS is set, then if we didn't consume the entire mangled string, then we didn't successfully demangle it. If @@ -4575,7 +4877,7 @@ d_demangle (const char *mangled, int options, size_t *palc) return NULL; } - *palc = dgs.allocation_failure ? 1 : 0; + *palc = dgs.allocation_failure ? 1 : dgs.alc; return dgs.buf; }