summaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-09-17 18:26:06 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-09-17 18:26:06 +0000
commita4c3da45a877599791191334536d1a1f155f50e1 (patch)
tree6946be114431b50821732989faea2214c6fb345a /gcc/cp/semantics.c
parentd93fbda6e21e83a9a010c47a1f0959cfe3a8c1aa (diff)
downloadgcc-a4c3da45a877599791191334536d1a1f155f50e1.tar.gz
Implement N4295 fold-expressions.
* cp-tree.def: Add UNARY_LEFT_FOLD_EXPR, UNARY_RIGHT_FOLD_EXPR, BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR. * cp-objcp-common.c (cp_common_init_ts): Handle them. * cp-tree.h (FOLD_EXPR_CHECK, BINARY_FOLD_EXPR_CHECK, FOLD_EXPR_P) (FOLD_EXPR_MODIFY_P, FOLD_EXPR_OP, FOLD_EXPR_PACK, FOLD_EXPR_INIT): New. * parser.c (cp_parser_skip_to_closing_parenthesis): Split out... (cp_parser_skip_to_closing_parenthesis_1): This function. Change or_comma parameter to or_ttype. (cp_parser_fold_operator, cp_parser_fold_expr_p) (cp_parser_fold_expression): New. (cp_parser_primary_expression): Use them. * pt.c (expand_empty_fold, fold_expression, tsubst_fold_expr_pack) (tsubst_fold_expr_init, expand_left_fold, tsubst_unary_left_fold) (tsubst_binary_left_fold, expand_right_fold) (tsubst_unary_right_fold, tsubst_binary_right_fold): New. (tsubst_copy): Use them. (type_dependent_expression_p): Handle fold-expressions. * semantics.c (finish_unary_fold_expr) (finish_left_unary_fold_expr, finish_right_unary_fold_expr) (finish_binary_fold_expr): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@227883 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7215dc672b6..f5bb0c1beb4 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7763,4 +7763,73 @@ capture_decltype (tree decl)
return type;
}
+/* Build a unary fold expression of EXPR over OP. If IS_RIGHT is true,
+ this is a right unary fold. Otherwise it is a left unary fold. */
+
+static tree
+finish_unary_fold_expr (tree expr, int op, tree_code dir)
+{
+ // Build a pack expansion (assuming expr has pack type).
+ if (!uses_parameter_packs (expr))
+ {
+ error_at (location_of (expr), "operand of fold expression has no "
+ "unexpanded parameter packs");
+ return error_mark_node;
+ }
+ tree pack = make_pack_expansion (expr);
+
+ // Build the fold expression.
+ tree code = build_int_cstu (integer_type_node, abs (op));
+ tree fold = build_min (dir, unknown_type_node, code, pack);
+ FOLD_EXPR_MODIFY_P (fold) = (op < 0);
+ return fold;
+}
+
+tree
+finish_left_unary_fold_expr (tree expr, int op)
+{
+ return finish_unary_fold_expr (expr, op, UNARY_LEFT_FOLD_EXPR);
+}
+
+tree
+finish_right_unary_fold_expr (tree expr, int op)
+{
+ return finish_unary_fold_expr (expr, op, UNARY_RIGHT_FOLD_EXPR);
+}
+
+/* Build a binary fold expression over EXPR1 and EXPR2. The
+ associativity of the fold is determined by EXPR1 and EXPR2 (whichever
+ has an unexpanded parameter pack). */
+
+tree
+finish_binary_fold_expr (tree pack, tree init, int op, tree_code dir)
+{
+ pack = make_pack_expansion (pack);
+ tree code = build_int_cstu (integer_type_node, abs (op));
+ tree fold = build_min (dir, unknown_type_node, code, pack, init);
+ FOLD_EXPR_MODIFY_P (fold) = (op < 0);
+ return fold;
+}
+
+tree
+finish_binary_fold_expr (tree expr1, tree expr2, int op)
+{
+ // Determine which expr has an unexpanded parameter pack and
+ // set the pack and initial term.
+ bool pack1 = uses_parameter_packs (expr1);
+ bool pack2 = uses_parameter_packs (expr2);
+ if (pack1 && !pack2)
+ return finish_binary_fold_expr (expr1, expr2, op, BINARY_RIGHT_FOLD_EXPR);
+ else if (pack2 && !pack1)
+ return finish_binary_fold_expr (expr2, expr1, op, BINARY_LEFT_FOLD_EXPR);
+ else
+ {
+ if (pack1)
+ error ("both arguments in binary fold have unexpanded parameter packs");
+ else
+ error ("no unexpanded parameter packs in binary fold");
+ }
+ return error_mark_node;
+}
+
#include "gt-cp-semantics.h"