From 7864eaaff7740c356f4b5c0a9dd9765b64a667ef Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 18 Jul 2016 11:28:51 -0400 Subject: [PATCH] Demangle C++17 fold-expressions. * cp-demangle.c (cplus_demangle_operators): Add f[lrLR]. (d_expression_1): Handle them. (d_maybe_print_fold_expression): New. (d_print_comp_inner): Use it. (d_index_template_argument): Handle negative index. From-SVN: r238437 --- libiberty/ChangeLog | 6 ++ libiberty/cp-demangle.c | 91 ++++++++++++++++++++++++++- libiberty/testsuite/demangle-expected | 12 ++++ 3 files changed, 107 insertions(+), 2 deletions(-) diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 3b50cdcd5b4..6209195ab38 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,5 +1,11 @@ 2016-07-15 Jason Merrill + * cp-demangle.c (cplus_demangle_operators): Add f[lrLR]. + (d_expression_1): Handle them. + (d_maybe_print_fold_expression): New. + (d_print_comp_inner): Use it. + (d_index_template_argument): Handle negative index. + * cp-demangle.c (cplus_demangle_operators): Add sP and sZ. (d_print_comp_inner): Handle them. (d_template_args_1): Split out from d_template_args. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 56d3bcb28fd..0c6d71436e3 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -344,7 +344,7 @@ struct d_print_info /* Set to 1 if we saw a demangling error. */ int demangle_failure; /* The current index into any template argument packs we are using - for printing. */ + for printing, or -1 to print the whole pack. */ int pack_index; /* Number of d_print_flush calls so far. */ unsigned long int flush_count; @@ -1762,6 +1762,10 @@ const struct demangle_operator_info cplus_demangle_operators[] = { "eO", NL ("^="), 2 }, { "eo", NL ("^"), 2 }, { "eq", NL ("=="), 2 }, + { "fL", NL ("..."), 3 }, + { "fR", NL ("..."), 3 }, + { "fl", NL ("..."), 2 }, + { "fr", NL ("..."), 2 }, { "ge", NL (">="), 2 }, { "gs", NL ("::"), 1 }, { "gt", NL (">"), 2 }, @@ -3305,6 +3309,9 @@ d_expression_1 (struct d_info *di) return NULL; if (op_is_new_cast (op)) left = cplus_demangle_type (di); + else if (code[0] == 'f') + /* fold-expression. */ + left = d_operator_name (di); else left = d_expression_1 (di); if (!strcmp (code, "cl")) @@ -3339,6 +3346,13 @@ d_expression_1 (struct d_info *di) second = d_expression_1 (di); third = d_expression_1 (di); } + else if (code[0] == 'f') + { + /* fold-expression. */ + first = d_operator_name (di); + second = d_expression_1 (di); + third = d_expression_1 (di); + } else if (code[0] == 'n') { /* new-expression. */ @@ -4196,13 +4210,17 @@ cplus_demangle_print (int options, const struct demangle_component *dc, } /* Returns the I'th element of the template arglist ARGS, or NULL on - failure. */ + failure. If I is negative, return the entire arglist. */ static struct demangle_component * d_index_template_argument (struct demangle_component *args, int i) { struct demangle_component *a; + if (i < 0) + /* Print the whole argument pack. */ + return args; + for (a = args; a != NULL; a = d_right (a)) @@ -4402,6 +4420,70 @@ d_get_saved_scope (struct d_print_info *dpi, return NULL; } +/* If DC is a C++17 fold-expression, print it and return true; otherwise + return false. */ + +static int +d_maybe_print_fold_expression (struct d_print_info *dpi, int options, + const struct demangle_component *dc) +{ + const struct demangle_component *ops, *operator_, *op1, *op2; + int save_idx; + + const char *fold_code = d_left (dc)->u.s_operator.op->code; + if (fold_code[0] != 'f') + return 0; + + ops = d_right (dc); + operator_ = d_left (ops); + op1 = d_right (ops); + op2 = 0; + if (op1->type == DEMANGLE_COMPONENT_TRINARY_ARG2) + { + op2 = d_right (op1); + op1 = d_left (op1); + } + + /* Print the whole pack. */ + save_idx = dpi->pack_index; + dpi->pack_index = -1; + + switch (fold_code[1]) + { + /* Unary left fold, (... + X). */ + case 'l': + d_append_string (dpi, "(..."); + d_print_expr_op (dpi, options, operator_); + d_print_subexpr (dpi, options, op1); + d_append_char (dpi, ')'); + break; + + /* Unary right fold, (X + ...). */ + case 'r': + d_append_char (dpi, '('); + d_print_subexpr (dpi, options, op1); + d_print_expr_op (dpi, options, operator_); + d_append_string (dpi, "...)"); + break; + + /* Binary left fold, (42 + ... + X). */ + case 'L': + /* Binary right fold, (X + ... + 42). */ + case 'R': + d_append_char (dpi, '('); + d_print_subexpr (dpi, options, op1); + d_print_expr_op (dpi, options, operator_); + d_append_string (dpi, "..."); + d_print_expr_op (dpi, options, operator_); + d_print_subexpr (dpi, options, op2); + d_append_char (dpi, ')'); + break; + } + + dpi->pack_index = save_idx; + return 1; +} + /* Subroutine to handle components. */ static void @@ -5218,6 +5300,9 @@ d_print_comp_inner (struct d_print_info *dpi, int options, return; } + if (d_maybe_print_fold_expression (dpi, options, dc)) + return; + /* We wrap an expression which uses the greater-than operator in an extra layer of parens so that it does not get confused with the '>' which ends the template parameters. */ @@ -5273,6 +5358,8 @@ d_print_comp_inner (struct d_print_info *dpi, int options, d_print_error (dpi); return; } + if (d_maybe_print_fold_expression (dpi, options, dc)) + return; { struct demangle_component *op = d_left (dc); struct demangle_component *first = d_left (d_right (dc)); diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 92ad01f6e61..535f2c143ee 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -4542,6 +4542,18 @@ void f(A<2>) _ZN1A1fIJiiEiJiiiEEEvRAsPDpT_T0_DpT1_E_iS3_S5_ void A::f(int (&) [6], int, int, int, int) + +_Z10unary_leftIJLi1ELi2ELi3EEEv1AIXflplT_EE +void unary_left<1, 2, 3>(A<(...+(1, 2, 3))>) + +_Z11unary_rightIJLi1ELi2ELi3EEEv1AIXfrplT_EE +void unary_right<1, 2, 3>(A<((1, 2, 3)+...)>) + +_Z11binary_leftIJLi1ELi2ELi3EEEv1AIXfLplLi42ET_EE +void binary_left<1, 2, 3>(A<((42)+...+(1, 2, 3))>) + +_Z12binary_rightIJLi1ELi2ELi3EEEv1AIXfRplT_Li42EEE +void binary_right<1, 2, 3>(A<((1, 2, 3)+...+(42))>) # # Tests a use-after-free problem PR70481 -- 2.30.2