aboutsummaryrefslogtreecommitdiff
path: root/libiberty
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2016-07-18 11:28:51 -0400
committerJason Merrill <jason@gcc.gnu.org>2016-07-18 11:28:51 -0400
commit7864eaaff7740c356f4b5c0a9dd9765b64a667ef (patch)
tree71bba0c83fb0345dbe4c8523a8595db27c3d49b3 /libiberty
parent40f3e913345c7d43c4677631f90fdff0780d2dce (diff)
downloadgcc-7864eaaff7740c356f4b5c0a9dd9765b64a667ef.zip
gcc-7864eaaff7740c356f4b5c0a9dd9765b64a667ef.tar.gz
gcc-7864eaaff7740c356f4b5c0a9dd9765b64a667ef.tar.bz2
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
Diffstat (limited to 'libiberty')
-rw-r--r--libiberty/ChangeLog6
-rw-r--r--libiberty/cp-demangle.c91
-rw-r--r--libiberty/testsuite/demangle-expected12
3 files changed, 107 insertions, 2 deletions
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 3b50cdc..6209195 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,5 +1,11 @@
2016-07-15 Jason Merrill <jason@redhat.com>
+ * 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 56d3bcb..0c6d714 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 92ad01f..535f2c1 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -4542,6 +4542,18 @@ void f<int, double>(A<2>)
_ZN1A1fIJiiEiJiiiEEEvRAsPDpT_T0_DpT1_E_iS3_S5_
void A::f<int, int, int, int, int, int>(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