diff options
author | Jason Merrill <jason@redhat.com> | 2016-07-15 14:38:23 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2016-07-15 14:38:23 -0400 |
commit | aa30dfadf3234caa8a29ef23ddc5932101a0e430 (patch) | |
tree | 570594e330f0c11c2307922ac7864b02d6a70bdd | |
parent | 34bbc4c502157fb08e6eba1d09380e2599ec3720 (diff) | |
download | gcc-aa30dfadf3234caa8a29ef23ddc5932101a0e430.zip gcc-aa30dfadf3234caa8a29ef23ddc5932101a0e430.tar.gz gcc-aa30dfadf3234caa8a29ef23ddc5932101a0e430.tar.bz2 |
PR c++/71711 - mangle C++1z fold-expressions.
* operators.def: Add *_FOLD_EXPR.
* cp-tree.h (FOLD_EXPR_P): Parenthesize.
* mangle.c (write_expression): Handle fold-expressions.
* pt.c (tsubst_unary_left_fold, tsubst_binary_left_fold)
(tsubst_unary_right_fold, tsubst_binary_right_fold): Handle
partial instantiation.
From-SVN: r238390
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 10 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 23 | ||||
-rw-r--r-- | gcc/cp/operators.def | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1z/fold-mangle.C | 20 |
6 files changed, 88 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index eb4f0b9..d0d855e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2016-07-15 Jason Merrill <jason@redhat.com> + PR c++/71711 + * operators.def: Add *_FOLD_EXPR. + * cp-tree.h (FOLD_EXPR_P): Parenthesize. + * mangle.c (write_expression): Handle fold-expressions. + * pt.c (tsubst_unary_left_fold, tsubst_binary_left_fold) + (tsubst_unary_right_fold, tsubst_binary_right_fold): Handle + partial instantiation. + PR c++/71814 * mangle.c (write_expression): Handle sizeof... an argument pack. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 74b8c7c..7e84036 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3334,11 +3334,11 @@ extern void decl_shadowed_for_var_insert (tree, tree); TREE_CHECK2 (NODE, BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR) /* True if NODE is UNARY_FOLD_EXPR or a BINARY_FOLD_EXPR */ -#define FOLD_EXPR_P(NODE) \ - TREE_CODE (NODE) == UNARY_LEFT_FOLD_EXPR \ - || TREE_CODE (NODE) == UNARY_RIGHT_FOLD_EXPR \ - || TREE_CODE (NODE) == BINARY_LEFT_FOLD_EXPR \ - || TREE_CODE (NODE) == BINARY_RIGHT_FOLD_EXPR +#define FOLD_EXPR_P(NODE) \ + (TREE_CODE (NODE) == UNARY_LEFT_FOLD_EXPR \ + || TREE_CODE (NODE) == UNARY_RIGHT_FOLD_EXPR \ + || TREE_CODE (NODE) == BINARY_LEFT_FOLD_EXPR \ + || TREE_CODE (NODE) == BINARY_RIGHT_FOLD_EXPR) /* True when NODE is a fold over a compound assignment operator. */ #define FOLD_EXPR_MODIFY_P(NODE) \ diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 8205da9..d5b26d6 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -3145,6 +3145,29 @@ write_expression (tree expr) "cannot be mangled"); continue; } + else if (FOLD_EXPR_P (expr)) + { + /* The first 'operand' of a fold-expression is the operator + that it folds over. */ + if (i == 0) + { + int fcode = TREE_INT_CST_LOW (operand); + write_string (operator_name_info[fcode].mangled_name); + continue; + } + else if (code == BINARY_LEFT_FOLD_EXPR) + { + /* The order of operands of the binary left and right + folds is the same, but we want to mangle them in + lexical order, i.e. non-pack first. */ + if (i == 1) + operand = FOLD_EXPR_INIT (expr); + else + operand = FOLD_EXPR_PACK (expr); + } + if (PACK_EXPANSION_P (operand)) + operand = PACK_EXPANSION_PATTERN (operand); + } write_expression (operand); } } diff --git a/gcc/cp/operators.def b/gcc/cp/operators.def index aa657fa..5b4f1b0 100644 --- a/gcc/cp/operators.def +++ b/gcc/cp/operators.def @@ -155,3 +155,7 @@ DEF_SIMPLE_OPERATOR ("()", CALL_EXPR, "cl", -1) /* Variadic templates extension. */ DEF_SIMPLE_OPERATOR ("...", EXPR_PACK_EXPANSION, "sp", 1) +DEF_SIMPLE_OPERATOR ("... +", UNARY_LEFT_FOLD_EXPR, "fl", 2) +DEF_SIMPLE_OPERATOR ("+ ...", UNARY_RIGHT_FOLD_EXPR, "fr", 2) +DEF_SIMPLE_OPERATOR ("+ ... +", BINARY_LEFT_FOLD_EXPR, "fL", 3) +DEF_SIMPLE_OPERATOR ("+ ... +", BINARY_RIGHT_FOLD_EXPR, "fR", 3) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 73b53e2..de70fb2 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10791,6 +10791,12 @@ tsubst_unary_left_fold (tree t, tree args, tsubst_flags_t complain, tree pack = tsubst_fold_expr_pack (t, args, complain, in_decl); if (pack == error_mark_node) return error_mark_node; + if (PACK_EXPANSION_P (pack)) + { + tree r = copy_node (t); + FOLD_EXPR_PACK (r) = pack; + return r; + } if (TREE_VEC_LENGTH (pack) == 0) return expand_empty_fold (t, complain); else @@ -10813,6 +10819,14 @@ tsubst_binary_left_fold (tree t, tree args, tsubst_flags_t complain, if (init == error_mark_node) return error_mark_node; + if (PACK_EXPANSION_P (pack)) + { + tree r = copy_node (t); + FOLD_EXPR_PACK (r) = pack; + FOLD_EXPR_INIT (r) = init; + return r; + } + tree vec = make_tree_vec (TREE_VEC_LENGTH (pack) + 1); TREE_VEC_ELT (vec, 0) = init; for (int i = 0; i < TREE_VEC_LENGTH (pack); ++i) @@ -10854,6 +10868,12 @@ tsubst_unary_right_fold (tree t, tree args, tsubst_flags_t complain, tree pack = tsubst_fold_expr_pack (t, args, complain, in_decl); if (pack == error_mark_node) return error_mark_node; + if (PACK_EXPANSION_P (pack)) + { + tree r = copy_node (t); + FOLD_EXPR_PACK (r) = pack; + return r; + } if (TREE_VEC_LENGTH (pack) == 0) return expand_empty_fold (t, complain); else @@ -10876,6 +10896,14 @@ tsubst_binary_right_fold (tree t, tree args, tsubst_flags_t complain, if (init == error_mark_node) return error_mark_node; + if (PACK_EXPANSION_P (pack)) + { + tree r = copy_node (t); + FOLD_EXPR_PACK (r) = pack; + FOLD_EXPR_INIT (r) = init; + return r; + } + int n = TREE_VEC_LENGTH (pack); tree vec = make_tree_vec (n + 1); for (int i = 0; i < n; ++i) diff --git a/gcc/testsuite/g++.dg/cpp1z/fold-mangle.C b/gcc/testsuite/g++.dg/cpp1z/fold-mangle.C new file mode 100644 index 0000000..1a8f16c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/fold-mangle.C @@ -0,0 +1,20 @@ +// PR c++/71711 +// { dg-options -std=c++1z } + +template < int > struct A {}; +template < int ... N > void unary_left (A < (... + N) >); +template < int ... N > void unary_right (A < (N + ...) >); +template < int ... N > void binary_left (A < (42 + ... + N) >); +template < int ... N > void binary_right (A < (N + ... + 42) >); + +void bar () +{ + // { dg-final { scan-assembler "_Z10unary_leftIJLi1ELi2ELi3EEEv1AIXflplT_EE" } } + unary_left < 1, 2, 3 > ({}); + // { dg-final { scan-assembler "_Z11unary_rightIJLi1ELi2ELi3EEEv1AIXfrplT_EE" } } + unary_right < 1, 2, 3 > ({}); + // { dg-final { scan-assembler "_Z11binary_leftIJLi1ELi2ELi3EEEv1AIXfLplLi42ET_EE" } } + binary_left < 1, 2, 3 > ({}); + // { dg-final { scan-assembler "_Z12binary_rightIJLi1ELi2ELi3EEEv1AIXfRplT_Li42EEE" } } + binary_right < 1, 2, 3 > ({}); +} |