aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-parser.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2019-01-07 09:49:08 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2019-01-07 09:49:08 +0100
commitd8fcab689435a29dba2862693689c624b257d1bf (patch)
tree3ebde208f2b05c57fa2ce4a941e6c4e7811e82c3 /gcc/c/c-parser.c
parentf881693c53374c743d3b5d1561708a64dcfe7eb6 (diff)
downloadgcc-d8fcab689435a29dba2862693689c624b257d1bf.zip
gcc-d8fcab689435a29dba2862693689c624b257d1bf.tar.gz
gcc-d8fcab689435a29dba2862693689c624b257d1bf.tar.bz2
re PR c++/85052 (Implement support for clang's __builtin_convertvector)
PR c++/85052 * tree-vect-generic.c: Include insn-config.h and recog.h. (expand_vector_piecewise): Add defaulted ret_type argument, if non-NULL, use that in preference to type for the result type. (expand_vector_parallel): Formatting fix. (do_vec_conversion, do_vec_narrowing_conversion, expand_vector_conversion): New functions. (expand_vector_operations_1): Call expand_vector_conversion for VEC_CONVERT ifn calls. * internal-fn.def (VEC_CONVERT): New internal function. * internal-fn.c (expand_VEC_CONVERT): New function. * fold-const-call.c (fold_const_vec_convert): New function. (fold_const_call): Use it for CFN_VEC_CONVERT. * doc/extend.texi (__builtin_convertvector): Document. c-family/ * c-common.h (enum rid): Add RID_BUILTIN_CONVERTVECTOR. (c_build_vec_convert): Declare. * c-common.c (c_build_vec_convert): New function. c/ * c-parser.c (c_parser_postfix_expression): Parse __builtin_convertvector. cp/ * cp-tree.h (cp_build_vec_convert): Declare. * parser.c (cp_parser_postfix_expression): Parse __builtin_convertvector. * constexpr.c: Include fold-const-call.h. (cxx_eval_internal_function): Handle IFN_VEC_CONVERT. (potential_constant_expression_1): Likewise. * semantics.c (cp_build_vec_convert): New function. * pt.c (tsubst_copy_and_build): Handle CALL_EXPR to IFN_VEC_CONVERT. testsuite/ * c-c++-common/builtin-convertvector-1.c: New test. * c-c++-common/torture/builtin-convertvector-1.c: New test. * g++.dg/ext/builtin-convertvector-1.C: New test. * g++.dg/cpp0x/constexpr-builtin4.C: New test. From-SVN: r267632
Diffstat (limited to 'gcc/c/c-parser.c')
-rw-r--r--gcc/c/c-parser.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 972b629..76f314e 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -8038,6 +8038,7 @@ enum tgmath_parm_kind
__builtin_shuffle ( assignment-expression ,
assignment-expression ,
assignment-expression, )
+ __builtin_convertvector ( assignment-expression , type-name )
offsetof-member-designator:
identifier
@@ -9113,17 +9114,14 @@ c_parser_postfix_expression (c_parser *parser)
*p = convert_lvalue_to_rvalue (loc, *p, true, true);
if (vec_safe_length (cexpr_list) == 2)
- expr.value =
- c_build_vec_perm_expr
- (loc, (*cexpr_list)[0].value,
- NULL_TREE, (*cexpr_list)[1].value);
+ expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
+ NULL_TREE,
+ (*cexpr_list)[1].value);
else if (vec_safe_length (cexpr_list) == 3)
- expr.value =
- c_build_vec_perm_expr
- (loc, (*cexpr_list)[0].value,
- (*cexpr_list)[1].value,
- (*cexpr_list)[2].value);
+ expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
+ (*cexpr_list)[1].value,
+ (*cexpr_list)[2].value);
else
{
error_at (loc, "wrong number of arguments to "
@@ -9133,6 +9131,41 @@ c_parser_postfix_expression (c_parser *parser)
set_c_expr_source_range (&expr, loc, close_paren_loc);
break;
}
+ case RID_BUILTIN_CONVERTVECTOR:
+ {
+ location_t start_loc = loc;
+ c_parser_consume_token (parser);
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ {
+ expr.set_error ();
+ break;
+ }
+ e1 = c_parser_expr_no_commas (parser, NULL);
+ mark_exp_read (e1.value);
+ if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
+ {
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ expr.set_error ();
+ break;
+ }
+ loc = c_parser_peek_token (parser)->location;
+ t1 = c_parser_type_name (parser);
+ location_t end_loc = c_parser_peek_token (parser)->get_finish ();
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+ "expected %<)%>");
+ if (t1 == NULL)
+ expr.set_error ();
+ else
+ {
+ tree type_expr = NULL_TREE;
+ expr.value = c_build_vec_convert (start_loc, e1.value, loc,
+ groktypename (t1, &type_expr,
+ NULL));
+ set_c_expr_source_range (&expr, start_loc, end_loc);
+ }
+ }
+ break;
case RID_AT_SELECTOR:
{
gcc_assert (c_dialect_objc ());