| Index: libiberty/cp-demangle.c
|
| diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
|
| index 0f1166be48ccee90adce883f7f143415fc1dcb37..27cc323f2a24c03c584e8ec74961d9d92e5e49b0 100644
|
| --- a/libiberty/cp-demangle.c
|
| +++ b/libiberty/cp-demangle.c
|
| @@ -648,9 +648,15 @@ d_dump (struct demangle_component *dc, int indent)
|
| case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
|
| printf ("template argument list\n");
|
| break;
|
| + case DEMANGLE_COMPONENT_INITIALIZER_LIST:
|
| + printf ("initializer list\n");
|
| + break;
|
| case DEMANGLE_COMPONENT_CAST:
|
| printf ("cast\n");
|
| break;
|
| + case DEMANGLE_COMPONENT_NULLARY:
|
| + printf ("nullary operator\n");
|
| + break;
|
| case DEMANGLE_COMPONENT_UNARY:
|
| printf ("unary operator\n");
|
| break;
|
| @@ -806,7 +812,6 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
|
| case DEMANGLE_COMPONENT_BINARY_ARGS:
|
| case DEMANGLE_COMPONENT_TRINARY:
|
| case DEMANGLE_COMPONENT_TRINARY_ARG1:
|
| - case DEMANGLE_COMPONENT_TRINARY_ARG2:
|
| case DEMANGLE_COMPONENT_LITERAL:
|
| case DEMANGLE_COMPONENT_LITERAL_NEG:
|
| case DEMANGLE_COMPONENT_COMPOUND_NAME:
|
| @@ -843,6 +848,8 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
|
| case DEMANGLE_COMPONENT_PACK_EXPANSION:
|
| case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS:
|
| case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS:
|
| + case DEMANGLE_COMPONENT_NULLARY:
|
| + case DEMANGLE_COMPONENT_TRINARY_ARG2:
|
| if (left == NULL)
|
| return NULL;
|
| break;
|
| @@ -850,6 +857,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
|
| /* This needs a right parameter, but the left parameter can be
|
| empty. */
|
| case DEMANGLE_COMPONENT_ARRAY_TYPE:
|
| + case DEMANGLE_COMPONENT_INITIALIZER_LIST:
|
| if (right == NULL)
|
| return NULL;
|
| break;
|
| @@ -1411,7 +1419,12 @@ d_unqualified_name (struct d_info *di)
|
|
|
| ret = d_operator_name (di);
|
| if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
|
| - di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2;
|
| + {
|
| + di->expansion += sizeof "operator" + ret->u.s_operator.op->len - 2;
|
| + if (!strcmp (ret->u.s_operator.op->code, "li"))
|
| + ret = d_make_comp (di, DEMANGLE_COMPONENT_UNARY, ret,
|
| + d_source_name (di));
|
| + }
|
| return ret;
|
| }
|
| else if (peek == 'C' || peek == 'D')
|
| @@ -1554,7 +1567,8 @@ d_identifier (struct d_info *di, int len)
|
| /* operator_name ::= many different two character encodings.
|
| ::= cv <type>
|
| ::= v <digit> <source-name>
|
| -*/
|
| +
|
| + This list is sorted for binary search. */
|
|
|
| #define NL(s) s, (sizeof s) - 1
|
|
|
| @@ -1566,23 +1580,28 @@ const struct demangle_operator_info cplus_demangle_operators[] =
|
| { "aa", NL ("&&"), 2 },
|
| { "ad", NL ("&"), 1 },
|
| { "an", NL ("&"), 2 },
|
| + { "at", NL ("alignof "), 1 },
|
| + { "az", NL ("alignof "), 1 },
|
| { "cl", NL ("()"), 2 },
|
| { "cm", NL (","), 2 },
|
| { "co", NL ("~"), 1 },
|
| { "dV", NL ("/="), 2 },
|
| - { "da", NL ("delete[]"), 1 },
|
| + { "da", NL ("delete[] "), 1 },
|
| { "de", NL ("*"), 1 },
|
| - { "dl", NL ("delete"), 1 },
|
| + { "dl", NL ("delete "), 1 },
|
| + { "ds", NL (".*"), 2 },
|
| { "dt", NL ("."), 2 },
|
| { "dv", NL ("/"), 2 },
|
| { "eO", NL ("^="), 2 },
|
| { "eo", NL ("^"), 2 },
|
| { "eq", NL ("=="), 2 },
|
| { "ge", NL (">="), 2 },
|
| + { "gs", NL ("::"), 1 },
|
| { "gt", NL (">"), 2 },
|
| { "ix", NL ("[]"), 2 },
|
| { "lS", NL ("<<="), 2 },
|
| { "le", NL ("<="), 2 },
|
| + { "li", NL ("operator\"\" "), 1 },
|
| { "ls", NL ("<<"), 2 },
|
| { "lt", NL ("<"), 2 },
|
| { "mI", NL ("-="), 2 },
|
| @@ -1590,11 +1609,11 @@ const struct demangle_operator_info cplus_demangle_operators[] =
|
| { "mi", NL ("-"), 2 },
|
| { "ml", NL ("*"), 2 },
|
| { "mm", NL ("--"), 1 },
|
| - { "na", NL ("new[]"), 1 },
|
| + { "na", NL ("new[]"), 3 },
|
| { "ne", NL ("!="), 2 },
|
| { "ng", NL ("-"), 1 },
|
| { "nt", NL ("!"), 1 },
|
| - { "nw", NL ("new"), 1 },
|
| + { "nw", NL ("new"), 3 },
|
| { "oR", NL ("|="), 2 },
|
| { "oo", NL ("||"), 2 },
|
| { "or", NL ("|"), 2 },
|
| @@ -1611,8 +1630,8 @@ const struct demangle_operator_info cplus_demangle_operators[] =
|
| { "rs", NL (">>"), 2 },
|
| { "st", NL ("sizeof "), 1 },
|
| { "sz", NL ("sizeof "), 1 },
|
| - { "at", NL ("alignof "), 1 },
|
| - { "az", NL ("alignof "), 1 },
|
| + { "tr", NL ("throw"), 0 },
|
| + { "tw", NL ("throw "), 1 },
|
| { NULL, NULL, 0, 0 }
|
| };
|
|
|
| @@ -2242,12 +2261,19 @@ cplus_demangle_type (struct d_info *di)
|
| d_expression (di), NULL);
|
| if (ret && d_next_char (di) != 'E')
|
| ret = NULL;
|
| + can_subst = 1;
|
| break;
|
|
|
| case 'p':
|
| /* Pack expansion. */
|
| ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION,
|
| cplus_demangle_type (di), NULL);
|
| + can_subst = 1;
|
| + break;
|
| +
|
| + case 'a':
|
| + /* auto */
|
| + ret = d_make_name (di, "auto", 4);
|
| break;
|
|
|
| case 'f':
|
| @@ -2298,6 +2324,7 @@ cplus_demangle_type (struct d_info *di)
|
|
|
| case 'v':
|
| ret = d_vector_type (di);
|
| + can_subst = 1;
|
| break;
|
|
|
| case 'n':
|
| @@ -2675,8 +2702,10 @@ d_template_args (struct d_info *di)
|
| constructor or destructor. */
|
| hold_last_name = di->last_name;
|
|
|
| - if (! d_check_char (di, 'I'))
|
| + if (d_peek_char (di) != 'I'
|
| + && d_peek_char (di) != 'J')
|
| return NULL;
|
| + d_advance (di, 1);
|
|
|
| if (d_peek_char (di) == 'E')
|
| {
|
| @@ -2735,6 +2764,7 @@ d_template_arg (struct d_info *di)
|
| return d_expr_primary (di);
|
|
|
| case 'I':
|
| + case 'J':
|
| /* An argument pack. */
|
| return d_template_args (di);
|
|
|
| @@ -2743,15 +2773,16 @@ d_template_arg (struct d_info *di)
|
| }
|
| }
|
|
|
| -/* Subroutine of <expression> ::= cl <expression>+ E */
|
| +/* Parse a sequence of expressions until we hit the terminator
|
| + character. */
|
|
|
| static struct demangle_component *
|
| -d_exprlist (struct d_info *di)
|
| +d_exprlist (struct d_info *di, char terminator)
|
| {
|
| struct demangle_component *list = NULL;
|
| struct demangle_component **p = &list;
|
|
|
| - if (d_peek_char (di) == 'E')
|
| + if (d_peek_char (di) == terminator)
|
| {
|
| d_advance (di, 1);
|
| return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL);
|
| @@ -2768,7 +2799,7 @@ d_exprlist (struct d_info *di)
|
| return NULL;
|
| p = &d_right (*p);
|
|
|
| - if (d_peek_char (di) == 'E')
|
| + if (d_peek_char (di) == terminator)
|
| {
|
| d_advance (di, 1);
|
| break;
|
| @@ -2859,9 +2890,21 @@ d_expression (struct d_info *di)
|
| else
|
| return name;
|
| }
|
| + else if ((peek == 'i' || peek == 't')
|
| + && d_peek_next_char (di) == 'l')
|
| + {
|
| + /* Brace-enclosed initializer list, untyped or typed. */
|
| + struct demangle_component *type = NULL;
|
| + if (peek == 't')
|
| + type = cplus_demangle_type (di);
|
| + d_advance (di, 2);
|
| + return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST,
|
| + type, d_exprlist (di, 'E'));
|
| + }
|
| else
|
| {
|
| struct demangle_component *op;
|
| + const char *code = NULL;
|
| int args;
|
|
|
| op = d_operator_name (di);
|
| @@ -2869,12 +2912,13 @@ d_expression (struct d_info *di)
|
| return NULL;
|
|
|
| if (op->type == DEMANGLE_COMPONENT_OPERATOR)
|
| - di->expansion += op->u.s_operator.op->len - 2;
|
| -
|
| - if (op->type == DEMANGLE_COMPONENT_OPERATOR
|
| - && strcmp (op->u.s_operator.op->code, "st") == 0)
|
| - return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
| - cplus_demangle_type (di));
|
| + {
|
| + code = op->u.s_operator.op->code;
|
| + di->expansion += op->u.s_operator.op->len - 2;
|
| + if (strcmp (code, "st") == 0)
|
| + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
| + cplus_demangle_type (di));
|
| + }
|
|
|
| switch (op->type)
|
| {
|
| @@ -2893,26 +2937,43 @@ d_expression (struct d_info *di)
|
|
|
| switch (args)
|
| {
|
| + case 0:
|
| + return d_make_comp (di, DEMANGLE_COMPONENT_NULLARY, op, NULL);
|
| +
|
| case 1:
|
| {
|
| struct demangle_component *operand;
|
| + int suffix = 0;
|
| +
|
| + if (code && (code[0] == 'p' || code[0] == 'm')
|
| + && code[1] == code[0])
|
| + /* pp_ and mm_ are the prefix variants. */
|
| + suffix = !d_check_char (di, '_');
|
| +
|
| if (op->type == DEMANGLE_COMPONENT_CAST
|
| && d_check_char (di, '_'))
|
| - operand = d_exprlist (di);
|
| + operand = d_exprlist (di, 'E');
|
| else
|
| operand = d_expression (di);
|
| - return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
| - operand);
|
| +
|
| + if (suffix)
|
| + /* Indicate the suffix variant for d_print_comp. */
|
| + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
| + d_make_comp (di,
|
| + DEMANGLE_COMPONENT_BINARY_ARGS,
|
| + operand, operand));
|
| + else
|
| + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op,
|
| + operand);
|
| }
|
| case 2:
|
| {
|
| struct demangle_component *left;
|
| struct demangle_component *right;
|
| - const char *code = op->u.s_operator.op->code;
|
|
|
| left = d_expression (di);
|
| if (!strcmp (code, "cl"))
|
| - right = d_exprlist (di);
|
| + right = d_exprlist (di, 'E');
|
| else if (!strcmp (code, "dt") || !strcmp (code, "pt"))
|
| {
|
| right = d_unqualified_name (di);
|
| @@ -2932,17 +2993,50 @@ d_expression (struct d_info *di)
|
| {
|
| struct demangle_component *first;
|
| struct demangle_component *second;
|
| + struct demangle_component *third;
|
|
|
| - first = d_expression (di);
|
| - second = d_expression (di);
|
| + if (!strcmp (code, "qu"))
|
| + {
|
| + /* ?: expression. */
|
| + first = d_expression (di);
|
| + second = d_expression (di);
|
| + third = d_expression (di);
|
| + }
|
| + else if (code[0] == 'n')
|
| + {
|
| + /* new-expression. */
|
| + if (code[1] != 'w' && code[1] != 'a')
|
| + return NULL;
|
| + first = d_exprlist (di, '_');
|
| + second = cplus_demangle_type (di);
|
| + if (d_peek_char (di) == 'E')
|
| + {
|
| + d_advance (di, 1);
|
| + third = NULL;
|
| + }
|
| + else if (d_peek_char (di) == 'p'
|
| + && d_peek_next_char (di) == 'i')
|
| + {
|
| + /* Parenthesized initializer. */
|
| + d_advance (di, 2);
|
| + third = d_exprlist (di, 'E');
|
| + }
|
| + else if (d_peek_char (di) == 'i'
|
| + && d_peek_next_char (di) == 'l')
|
| + /* initializer-list. */
|
| + third = d_expression (di);
|
| + else
|
| + return NULL;
|
| + }
|
| + else
|
| + return NULL;
|
| return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op,
|
| d_make_comp (di,
|
| DEMANGLE_COMPONENT_TRINARY_ARG1,
|
| first,
|
| d_make_comp (di,
|
| DEMANGLE_COMPONENT_TRINARY_ARG2,
|
| - second,
|
| - d_expression (di))));
|
| + second, third)));
|
| }
|
| default:
|
| return NULL;
|
| @@ -3621,6 +3715,7 @@ d_find_pack (struct d_print_info *dpi,
|
| case DEMANGLE_COMPONENT_SUB_STD:
|
| case DEMANGLE_COMPONENT_CHARACTER:
|
| case DEMANGLE_COMPONENT_FUNCTION_PARAM:
|
| + case DEMANGLE_COMPONENT_UNNAMED_TYPE:
|
| return NULL;
|
|
|
| case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
|
| @@ -3662,6 +3757,8 @@ d_print_subexpr (struct d_print_info *dpi, int options,
|
| {
|
| int simple = 0;
|
| if (dc->type == DEMANGLE_COMPONENT_NAME
|
| + || dc->type == DEMANGLE_COMPONENT_QUAL_NAME
|
| + || dc->type == DEMANGLE_COMPONENT_INITIALIZER_LIST
|
| || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM)
|
| simple = 1;
|
| if (!simple)
|
| @@ -4257,16 +4354,32 @@ d_print_comp (struct d_print_info *dpi, int options,
|
| }
|
| return;
|
|
|
| + case DEMANGLE_COMPONENT_INITIALIZER_LIST:
|
| + {
|
| + struct demangle_component *type = d_left (dc);
|
| + struct demangle_component *list = d_right (dc);
|
| +
|
| + if (type)
|
| + d_print_comp (dpi, options, type);
|
| + d_append_char (dpi, '{');
|
| + d_print_comp (dpi, options, list);
|
| + d_append_char (dpi, '}');
|
| + }
|
| + return;
|
| +
|
| case DEMANGLE_COMPONENT_OPERATOR:
|
| {
|
| - char c;
|
| + const struct demangle_operator_info *op = dc->u.s_operator.op;
|
| + int len = op->len;
|
|
|
| d_append_string (dpi, "operator");
|
| - c = dc->u.s_operator.op->name[0];
|
| - if (IS_LOWER (c))
|
| + /* Add a space before new/delete. */
|
| + if (IS_LOWER (op->name[0]))
|
| d_append_char (dpi, ' ');
|
| - d_append_buffer (dpi, dc->u.s_operator.op->name,
|
| - dc->u.s_operator.op->len);
|
| + /* Omit a trailing space. */
|
| + if (op->name[len-1] == ' ')
|
| + --len;
|
| + d_append_buffer (dpi, op->name, len);
|
| return;
|
| }
|
|
|
| @@ -4280,55 +4393,59 @@ d_print_comp (struct d_print_info *dpi, int options,
|
| d_print_cast (dpi, options, dc);
|
| return;
|
|
|
| + case DEMANGLE_COMPONENT_NULLARY:
|
| + d_print_expr_op (dpi, options, d_left (dc));
|
| + return;
|
| +
|
| case DEMANGLE_COMPONENT_UNARY:
|
| - if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
|
| - && d_left (dc)->u.s_operator.op->len == 1
|
| - && d_left (dc)->u.s_operator.op->name[0] == '&'
|
| - && d_right (dc)->type == DEMANGLE_COMPONENT_TYPED_NAME
|
| - && d_left (d_right (dc))->type == DEMANGLE_COMPONENT_QUAL_NAME
|
| - && d_right (d_right (dc))->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
|
| - {
|
| - /* Address of a function (therefore in an expression context) must
|
| - have its argument list suppressed.
|
| -
|
| - unary operator ... dc
|
| - operator & ... d_left (dc)
|
| - typed name ... d_right (dc)
|
| - qualified name ... d_left (d_right (dc))
|
| - <names>
|
| - function type ... d_right (d_right (dc))
|
| - argument list
|
| - <arguments> */
|
| -
|
| - d_print_expr_op (dpi, options, d_left (dc));
|
| - d_print_comp (dpi, options, d_left (d_right (dc)));
|
| - return;
|
| - }
|
| - else if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR
|
| - && d_left (dc)->u.s_operator.op->len == 1
|
| - && d_left (dc)->u.s_operator.op->name[0] == '&'
|
| - && d_right (dc)->type == DEMANGLE_COMPONENT_QUAL_NAME)
|
| - {
|
| - /* Keep also already processed variant without the argument list.
|
| + {
|
| + struct demangle_component *op = d_left (dc);
|
| + struct demangle_component *operand = d_right (dc);
|
| + const char *code = NULL;
|
|
|
| - unary operator ... dc
|
| - operator & ... d_left (dc)
|
| - qualified name ... d_right (dc)
|
| - <names> */
|
| + if (op->type == DEMANGLE_COMPONENT_OPERATOR)
|
| + {
|
| + code = op->u.s_operator.op->code;
|
| + if (!strcmp (code, "ad"))
|
| + {
|
| + /* Don't print the argument list for the address of a
|
| + function. */
|
| + if (operand->type == DEMANGLE_COMPONENT_TYPED_NAME
|
| + && d_left (operand)->type == DEMANGLE_COMPONENT_QUAL_NAME
|
| + && d_right (operand)->type == DEMANGLE_COMPONENT_FUNCTION_TYPE)
|
| + operand = d_left (operand);
|
| + }
|
| + if (operand->type == DEMANGLE_COMPONENT_BINARY_ARGS)
|
| + {
|
| + /* This indicates a suffix operator. */
|
| + operand = d_left (operand);
|
| + d_print_subexpr (dpi, options, operand);
|
| + d_print_expr_op (dpi, options, op);
|
| + return;
|
| + }
|
| + }
|
|
|
| - d_print_expr_op (dpi, options, d_left (dc));
|
| - d_print_comp (dpi, options, d_right (dc));
|
| - return;
|
| - }
|
| - else if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST)
|
| - d_print_expr_op (dpi, options, d_left (dc));
|
| - else
|
| - {
|
| - d_append_char (dpi, '(');
|
| - d_print_cast (dpi, options, d_left (dc));
|
| - d_append_char (dpi, ')');
|
| - }
|
| - d_print_subexpr (dpi, options, d_right (dc));
|
| + if (op->type != DEMANGLE_COMPONENT_CAST)
|
| + d_print_expr_op (dpi, options, op);
|
| + else
|
| + {
|
| + d_append_char (dpi, '(');
|
| + d_print_cast (dpi, options, op);
|
| + d_append_char (dpi, ')');
|
| + }
|
| + if (code && !strcmp (code, "gs"))
|
| + /* Avoid parens after '::'. */
|
| + d_print_comp (dpi, options, operand);
|
| + else if (code && !strcmp (code, "st"))
|
| + /* Always print parens for sizeof (type). */
|
| + {
|
| + d_append_char (dpi, '(');
|
| + d_print_comp (dpi, options, operand);
|
| + d_append_char (dpi, ')');
|
| + }
|
| + else
|
| + d_print_subexpr (dpi, options, operand);
|
| + }
|
| return;
|
|
|
| case DEMANGLE_COMPONENT_BINARY:
|
| @@ -4393,11 +4510,33 @@ d_print_comp (struct d_print_info *dpi, int options,
|
| d_print_error (dpi);
|
| return;
|
| }
|
| - d_print_subexpr (dpi, options, d_left (d_right (dc)));
|
| - d_print_expr_op (dpi, options, d_left (dc));
|
| - d_print_subexpr (dpi, options, d_left (d_right (d_right (dc))));
|
| - d_append_string (dpi, " : ");
|
| - d_print_subexpr (dpi, options, d_right (d_right (d_right (dc))));
|
| + {
|
| + struct demangle_component *op = d_left (dc);
|
| + struct demangle_component *first = d_left (d_right (dc));
|
| + struct demangle_component *second = d_left (d_right (d_right (dc)));
|
| + struct demangle_component *third = d_right (d_right (d_right (dc)));
|
| +
|
| + if (!strcmp (op->u.s_operator.op->code, "qu"))
|
| + {
|
| + d_print_subexpr (dpi, options, first);
|
| + d_print_expr_op (dpi, options, op);
|
| + d_print_subexpr (dpi, options, second);
|
| + d_append_string (dpi, " : ");
|
| + d_print_subexpr (dpi, options, third);
|
| + }
|
| + else
|
| + {
|
| + d_append_string (dpi, "new ");
|
| + if (d_left (first) != NULL)
|
| + {
|
| + d_print_subexpr (dpi, options, first);
|
| + d_append_char (dpi, ' ');
|
| + }
|
| + d_print_comp (dpi, options, second);
|
| + if (third)
|
| + d_print_subexpr (dpi, options, third);
|
| + }
|
| + }
|
| return;
|
|
|
| case DEMANGLE_COMPONENT_TRINARY_ARG1:
|
|
|