if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
{
struct c_arg_info *ret = build_arg_info ();
- /* Suppress -Wold-style-definition for this case. */
- ret->types = error_mark_node;
- error_at (c_parser_peek_token (parser)->location,
- "ISO C requires a named argument before %<...%>");
+
+ if (flag_allow_parameterless_variadic_functions)
+ {
+ /* F (...) is allowed. */
+ ret->types = NULL_TREE;
+ }
+ else
+ {
+ /* Suppress -Wold-style-definition for this case. */
+ ret->types = error_mark_node;
+ error_at (c_parser_peek_token (parser)->location,
+ "ISO C requires a named argument before %<...%>");
+ }
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
{
}
}
+/* Helper function to read arguments of builtins which are interfaces
+ for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
+ others. The name of the builtin is passed using BNAME parameter.
+ Function returns true if there were no errors while parsing and
+ stores the arguments in CEXPR_LIST. */
+static bool
+c_parser_get_builtin_args (c_parser *parser, const char *bname,
+ VEC(c_expr_t,gc) **ret_cexpr_list)
+{
+ location_t loc = c_parser_peek_token (parser)->location;
+ VEC (c_expr_t,gc) *cexpr_list;
+ c_expr_t expr;
+
+ *ret_cexpr_list = NULL;
+ if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
+ {
+ error_at (loc, "cannot take address of %qs", bname);
+ return false;
+ }
+
+ c_parser_consume_token (parser);
+
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ {
+ c_parser_consume_token (parser);
+ return true;
+ }
+
+ expr = c_parser_expr_no_commas (parser, NULL);
+ cexpr_list = VEC_alloc (c_expr_t, gc, 1);
+ C_EXPR_APPEND (cexpr_list, expr);
+ while (c_parser_next_token_is (parser, CPP_COMMA))
+ {
+ c_parser_consume_token (parser);
+ expr = c_parser_expr_no_commas (parser, NULL);
+ C_EXPR_APPEND (cexpr_list, expr);
+ }
+
+ if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+ return false;
+
+ *ret_cexpr_list = cexpr_list;
+ return true;
+}
+
+
/* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2).
postfix-expression:
assignment-expression )
__builtin_types_compatible_p ( type-name , type-name )
__builtin_complex ( assignment-expression , assignment-expression )
+ __builtin_shuffle ( assignment-expression , assignment-expression )
+ __builtin_shuffle ( assignment-expression ,
+ assignment-expression ,
+ assignment-expression, )
offsetof-member-designator:
identifier
static struct c_expr
c_parser_postfix_expression (c_parser *parser)
{
- struct c_expr expr, e1, e2, e3;
+ struct c_expr expr, e1;
struct c_type_name *t1, *t2;
location_t loc = c_parser_peek_token (parser)->location;;
expr.original_code = ERROR_MARK;
}
break;
case RID_CHOOSE_EXPR:
- c_parser_consume_token (parser);
- if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
- {
- expr.value = error_mark_node;
- break;
- }
- loc = c_parser_peek_token (parser)->location;
- e1 = c_parser_expr_no_commas (parser, NULL);
- if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
- {
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
- break;
- }
- e2 = c_parser_expr_no_commas (parser, NULL);
- if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
- {
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
- break;
- }
- e3 = c_parser_expr_no_commas (parser, NULL);
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
- "expected %<)%>");
{
+ VEC (c_expr_t, gc) *cexpr_list;
+ c_expr_t *e1_p, *e2_p, *e3_p;
tree c;
- c = e1.value;
- mark_exp_read (e2.value);
- mark_exp_read (e3.value);
+ c_parser_consume_token (parser);
+ if (!c_parser_get_builtin_args (parser,
+ "__builtin_choose_expr",
+ &cexpr_list))
+ {
+ expr.value = error_mark_node;
+ break;
+ }
+
+ if (VEC_length (c_expr_t, cexpr_list) != 3)
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_choose_expr%>");
+ 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);
+ e3_p = VEC_index (c_expr_t, cexpr_list, 2);
+
+ c = e1_p->value;
+ mark_exp_read (e2_p->value);
+ mark_exp_read (e3_p->value);
if (TREE_CODE (c) != INTEGER_CST
|| !INTEGRAL_TYPE_P (TREE_TYPE (c)))
error_at (loc,
"first argument to %<__builtin_choose_expr%> not"
" a constant");
constant_expression_warning (c);
- expr = integer_zerop (c) ? e3 : e2;
+ expr = integer_zerop (c) ? *e3_p : *e2_p;
+ break;
}
- break;
case RID_TYPES_COMPATIBLE_P:
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
}
break;
case RID_BUILTIN_COMPLEX:
- c_parser_consume_token (parser);
- if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
- {
- expr.value = error_mark_node;
- break;
- }
- loc = c_parser_peek_token (parser)->location;
- e1 = c_parser_expr_no_commas (parser, NULL);
- if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
- {
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
- break;
- }
- e2 = c_parser_expr_no_commas (parser, NULL);
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
- "expected %<)%>");
- mark_exp_read (e1.value);
- mark_exp_read (e2.value);
- if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1.value))
- || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1.value))
- || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2.value))
- || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2.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.value))
- != TYPE_MAIN_VARIANT (TREE_TYPE (e2.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.value))),
- e1.value, e2.value);
- break;
+ {
+ 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;
+ }
case RID_AT_SELECTOR:
gcc_assert (c_dialect_objc ());
c_parser_consume_token (parser);