+ case RID_BUILTIN_COMPLEX:
+ {
+ VEC(c_expr_t, gc) *cexpr_list;
+ c_expr_t *e1_p, *e2_p;
+
+ c_parser_consume_token (parser);
+ if (!c_parser_get_builtin_args (parser,
+ "__builtin_complex",
+ &cexpr_list))
+ {
+ expr.value = error_mark_node;
+ break;
+ }
+
+ if (VEC_length (c_expr_t, cexpr_list) != 2)
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_complex%>");
+ expr.value = error_mark_node;
+ break;
+ }
+
+ e1_p = VEC_index (c_expr_t, cexpr_list, 0);
+ e2_p = VEC_index (c_expr_t, cexpr_list, 1);
+
+ mark_exp_read (e1_p->value);
+ if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
+ e1_p->value = convert (TREE_TYPE (e1_p->value),
+ TREE_OPERAND (e1_p->value, 0));
+ mark_exp_read (e2_p->value);
+ if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
+ e2_p->value = convert (TREE_TYPE (e2_p->value),
+ TREE_OPERAND (e2_p->value, 0));
+ if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
+ || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
+ || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
+ || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
+ {
+ error_at (loc, "%<__builtin_complex%> operand "
+ "not of real binary floating-point type");
+ expr.value = error_mark_node;
+ break;
+ }
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
+ != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
+ {
+ error_at (loc,
+ "%<__builtin_complex%> operands of different types");
+ expr.value = error_mark_node;
+ break;
+ }
+ if (!flag_isoc99)
+ pedwarn (loc, OPT_pedantic,
+ "ISO C90 does not support complex types");
+ expr.value = build2 (COMPLEX_EXPR,
+ build_complex_type
+ (TYPE_MAIN_VARIANT
+ (TREE_TYPE (e1_p->value))),
+ e1_p->value, e2_p->value);
+ break;
+ }
+ case RID_BUILTIN_SHUFFLE:
+ {
+ VEC(c_expr_t,gc) *cexpr_list;
+
+ c_parser_consume_token (parser);
+ if (!c_parser_get_builtin_args (parser,
+ "__builtin_shuffle",
+ &cexpr_list))
+ {
+ expr.value = error_mark_node;
+ break;
+ }
+
+ if (VEC_length (c_expr_t, cexpr_list) == 2)
+ expr.value =
+ c_build_vec_perm_expr
+ (loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
+ NULL_TREE, VEC_index (c_expr_t, cexpr_list, 1)->value);
+
+ else if (VEC_length (c_expr_t, cexpr_list) == 3)
+ expr.value =
+ c_build_vec_perm_expr
+ (loc, VEC_index (c_expr_t, cexpr_list, 0)->value,
+ VEC_index (c_expr_t, cexpr_list, 1)->value,
+ VEC_index (c_expr_t, cexpr_list, 2)->value);
+ else
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_shuffle%>");
+ expr.value = error_mark_node;
+ }
+ break;
+ }