%start program
-%union {long itype; tree ttype; enum tree_code code;
+%union {long itype; tree ttype; struct c_expr exprtype; enum tree_code code;
location_t location; }
/* All identifiers that are not reserved words
%type <ttype> ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
%type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF
-%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
-%type <ttype> expr_no_commas cast_expr unary_expr primary STRING
+%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT STRING FUNC_NAME
+%type <ttype> nonnull_exprlist exprlist
+%type <exprtype> expr expr_no_commas cast_expr unary_expr primary
%type <ttype> declspecs_nosc_nots_nosa_noea declspecs_nosc_nots_nosa_ea
%type <ttype> declspecs_nosc_nots_sa_noea declspecs_nosc_nots_sa_ea
%type <ttype> declspecs_nosc_ts_nosa_noea declspecs_nosc_ts_nosa_ea
{ $$ = TRUTH_NOT_EXPR; }
;
-expr: nonnull_exprlist
- { $$ = build_compound_expr ($1); }
+expr: expr_no_commas
+ | expr ',' expr_no_commas
+ { $$.value = build_compound_expr ($1.value, $3.value);
+ $$.original_code = COMPOUND_EXPR; }
;
exprlist:
nonnull_exprlist:
expr_no_commas
- { $$ = build_tree_list (NULL_TREE, $1); }
+ { $$ = build_tree_list (NULL_TREE, $1.value); }
| nonnull_exprlist ',' expr_no_commas
- { chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ { chainon ($1, build_tree_list (NULL_TREE, $3.value)); }
;
unary_expr:
primary
| '*' cast_expr %prec UNARY
- { $$ = build_indirect_ref ($2, "unary *"); }
+ { $$.value = build_indirect_ref ($2.value, "unary *");
+ $$.original_code = ERROR_MARK; }
/* __extension__ turns off -pedantic for following primary. */
| extension cast_expr %prec UNARY
{ $$ = $2;
RESTORE_EXT_FLAGS ($1); }
| unop cast_expr %prec UNARY
- { $$ = build_unary_op ($1, $2, 0);
- overflow_warning ($$); }
+ { $$.value = build_unary_op ($1, $2.value, 0);
+ overflow_warning ($$.value);
+ $$.original_code = ERROR_MARK; }
/* Refer to the address of a label as a pointer. */
| ANDAND identifier
- { $$ = finish_label_address_expr ($2); }
+ { $$.value = finish_label_address_expr ($2);
+ $$.original_code = ERROR_MARK; }
| sizeof unary_expr %prec UNARY
{ skip_evaluation--;
- if (TREE_CODE ($2) == COMPONENT_REF
- && DECL_C_BIT_FIELD (TREE_OPERAND ($2, 1)))
+ if (TREE_CODE ($2.value) == COMPONENT_REF
+ && DECL_C_BIT_FIELD (TREE_OPERAND ($2.value, 1)))
error ("`sizeof' applied to a bit-field");
- $$ = c_sizeof (TREE_TYPE ($2)); }
+ $$.value = c_sizeof (TREE_TYPE ($2.value));
+ $$.original_code = ERROR_MARK; }
| sizeof '(' typename ')' %prec HYPERUNARY
{ skip_evaluation--;
- $$ = c_sizeof (groktypename ($3)); }
+ $$.value = c_sizeof (groktypename ($3));
+ $$.original_code = ERROR_MARK; }
| alignof unary_expr %prec UNARY
{ skip_evaluation--;
- $$ = c_alignof_expr ($2); }
+ $$.value = c_alignof_expr ($2.value);
+ $$.original_code = ERROR_MARK; }
| alignof '(' typename ')' %prec HYPERUNARY
{ skip_evaluation--;
- $$ = c_alignof (groktypename ($3)); }
+ $$.value = c_alignof (groktypename ($3));
+ $$.original_code = ERROR_MARK; }
| REALPART cast_expr %prec UNARY
- { $$ = build_unary_op (REALPART_EXPR, $2, 0); }
+ { $$.value = build_unary_op (REALPART_EXPR, $2.value, 0);
+ $$.original_code = ERROR_MARK; }
| IMAGPART cast_expr %prec UNARY
- { $$ = build_unary_op (IMAGPART_EXPR, $2, 0); }
+ { $$.value = build_unary_op (IMAGPART_EXPR, $2.value, 0);
+ $$.original_code = ERROR_MARK; }
;
sizeof:
cast_expr:
unary_expr
| '(' typename ')' cast_expr %prec UNARY
- { $$ = c_cast_expr ($2, $4); }
+ { $$.value = c_cast_expr ($2, $4.value);
+ $$.original_code = ERROR_MARK; }
;
expr_no_commas:
| expr_no_commas '^' expr_no_commas
{ $$ = parser_build_binary_op ($2, $1, $3); }
| expr_no_commas ANDAND
- { $1 = lang_hooks.truthvalue_conversion
- (default_conversion ($1));
- skip_evaluation += $1 == truthvalue_false_node; }
+ { $1.value = lang_hooks.truthvalue_conversion
+ (default_conversion ($1.value));
+ skip_evaluation += $1.value == truthvalue_false_node; }
expr_no_commas
- { skip_evaluation -= $1 == truthvalue_false_node;
+ { skip_evaluation -= $1.value == truthvalue_false_node;
$$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); }
| expr_no_commas OROR
- { $1 = lang_hooks.truthvalue_conversion
- (default_conversion ($1));
- skip_evaluation += $1 == truthvalue_true_node; }
+ { $1.value = lang_hooks.truthvalue_conversion
+ (default_conversion ($1.value));
+ skip_evaluation += $1.value == truthvalue_true_node; }
expr_no_commas
- { skip_evaluation -= $1 == truthvalue_true_node;
+ { skip_evaluation -= $1.value == truthvalue_true_node;
$$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); }
| expr_no_commas '?'
- { $1 = lang_hooks.truthvalue_conversion
- (default_conversion ($1));
- skip_evaluation += $1 == truthvalue_false_node; }
+ { $1.value = lang_hooks.truthvalue_conversion
+ (default_conversion ($1.value));
+ skip_evaluation += $1.value == truthvalue_false_node; }
expr ':'
- { skip_evaluation += (($1 == truthvalue_true_node)
- - ($1 == truthvalue_false_node)); }
+ { skip_evaluation += (($1.value == truthvalue_true_node)
+ - ($1.value == truthvalue_false_node)); }
expr_no_commas
- { skip_evaluation -= $1 == truthvalue_true_node;
- $$ = build_conditional_expr ($1, $4, $7); }
+ { skip_evaluation -= $1.value == truthvalue_true_node;
+ $$.value = build_conditional_expr ($1.value, $4.value,
+ $7.value);
+ $$.original_code = ERROR_MARK; }
| expr_no_commas '?'
{ if (pedantic)
pedwarn ("ISO C forbids omitting the middle term of a ?: expression");
/* Make sure first operand is calculated only once. */
- $<ttype>2 = save_expr (default_conversion ($1));
- $1 = lang_hooks.truthvalue_conversion ($<ttype>2);
- skip_evaluation += $1 == truthvalue_true_node; }
+ $<ttype>2 = save_expr (default_conversion ($1.value));
+ $1.value = lang_hooks.truthvalue_conversion ($<ttype>2);
+ skip_evaluation += $1.value == truthvalue_true_node; }
':' expr_no_commas
- { skip_evaluation -= $1 == truthvalue_true_node;
- $$ = build_conditional_expr ($1, $<ttype>2, $5); }
+ { skip_evaluation -= $1.value == truthvalue_true_node;
+ $$.value = build_conditional_expr ($1.value, $<ttype>2,
+ $5.value);
+ $$.original_code = ERROR_MARK; }
| expr_no_commas '=' expr_no_commas
- { char class;
- $$ = build_modify_expr ($1, NOP_EXPR, $3);
- class = TREE_CODE_CLASS (TREE_CODE ($$));
- if (IS_EXPR_CODE_CLASS (class))
- C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR);
+ { $$.value = build_modify_expr ($1.value, NOP_EXPR, $3.value);
+ $$.original_code = MODIFY_EXPR;
}
| expr_no_commas ASSIGN expr_no_commas
- { char class;
- $$ = build_modify_expr ($1, $2, $3);
- /* This inhibits warnings in
- c_common_truthvalue_conversion. */
- class = TREE_CODE_CLASS (TREE_CODE ($$));
- if (IS_EXPR_CODE_CLASS (class))
- C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK);
+ { $$.value = build_modify_expr ($1.value, $2, $3.value);
+ TREE_NO_WARNING ($$.value) = 1;
+ $$.original_code = ERROR_MARK;
}
;
{
if (yychar == YYEMPTY)
yychar = YYLEX;
- $$ = build_external_ref ($1, yychar == '(');
+ $$.value = build_external_ref ($1, yychar == '(');
+ $$.original_code = ERROR_MARK;
}
| CONSTANT
+ { $$.value = $1; $$.original_code = ERROR_MARK; }
| STRING
+ { $$.value = $1; $$.original_code = ERROR_MARK; }
| FUNC_NAME
- { $$ = fname_decl (C_RID_CODE ($$), $$); }
+ { $$.value = fname_decl (C_RID_CODE ($1), $1);
+ $$.original_code = ERROR_MARK; }
| '(' typename ')' '{'
{ start_init (NULL_TREE, NULL, 0);
$2 = groktypename ($2);
if (pedantic && ! flag_isoc99)
pedwarn ("ISO C90 forbids compound literals");
- $$ = build_compound_literal (type, constructor);
+ $$.value = build_compound_literal (type, constructor);
+ $$.original_code = ERROR_MARK;
}
| '(' expr ')'
- { char class = TREE_CODE_CLASS (TREE_CODE ($2));
- if (IS_EXPR_CODE_CLASS (class))
- C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK);
- $$ = $2; }
+ { $$.value = $2.value;
+ if (TREE_CODE ($$.value) == MODIFY_EXPR)
+ TREE_NO_WARNING ($$.value) = 1;
+ $$.original_code = ERROR_MARK; }
| '(' error ')'
- { $$ = error_mark_node; }
+ { $$.value = error_mark_node; $$.original_code = ERROR_MARK; }
| compstmt_primary_start compstmt_nostart ')'
{ if (pedantic)
pedwarn ("ISO C forbids braced-groups within expressions");
- $$ = c_finish_stmt_expr ($1);
+ $$.value = c_finish_stmt_expr ($1);
+ $$.original_code = ERROR_MARK;
}
| compstmt_primary_start error ')'
{ c_finish_stmt_expr ($1);
- $$ = error_mark_node;
+ $$.value = error_mark_node;
+ $$.original_code = ERROR_MARK;
}
| primary '(' exprlist ')' %prec '.'
- { $$ = build_function_call ($1, $3); }
+ { $$.value = build_function_call ($1.value, $3);
+ $$.original_code = ERROR_MARK; }
| VA_ARG '(' expr_no_commas ',' typename ')'
- { $$ = build_va_arg ($3, groktypename ($5)); }
+ { $$.value = build_va_arg ($3.value, groktypename ($5));
+ $$.original_code = ERROR_MARK; }
| OFFSETOF '(' typename ',' offsetof_member_designator ')'
- { $$ = build_offsetof (groktypename ($3), $5); }
+ { $$.value = build_offsetof (groktypename ($3), $5);
+ $$.original_code = ERROR_MARK; }
| OFFSETOF '(' error ')'
- { $$ = error_mark_node; }
+ { $$.value = error_mark_node; $$.original_code = ERROR_MARK; }
| CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ','
expr_no_commas ')'
{
tree c;
- c = fold ($3);
+ c = fold ($3.value);
STRIP_NOPS (c);
if (TREE_CODE (c) != INTEGER_CST)
error ("first argument to __builtin_choose_expr not"
$$ = integer_zerop (c) ? $7 : $5;
}
| CHOOSE_EXPR '(' error ')'
- { $$ = error_mark_node; }
+ { $$.value = error_mark_node; $$.original_code = ERROR_MARK; }
| TYPES_COMPATIBLE_P '(' typename ',' typename ')'
{
tree e1, e2;
e1 = TYPE_MAIN_VARIANT (groktypename ($3));
e2 = TYPE_MAIN_VARIANT (groktypename ($5));
- $$ = comptypes (e1, e2)
+ $$.value = comptypes (e1, e2)
? build_int_2 (1, 0) : build_int_2 (0, 0);
+ $$.original_code = ERROR_MARK;
}
| TYPES_COMPATIBLE_P '(' error ')'
- { $$ = error_mark_node; }
+ { $$.value = error_mark_node; $$.original_code = ERROR_MARK; }
| primary '[' expr ']' %prec '.'
- { $$ = build_array_ref ($1, $3); }
+ { $$.value = build_array_ref ($1.value, $3.value);
+ $$.original_code = ERROR_MARK; }
| primary '.' identifier
- { $$ = build_component_ref ($1, $3); }
+ { $$.value = build_component_ref ($1.value, $3);
+ $$.original_code = ERROR_MARK; }
| primary POINTSAT identifier
{
- tree expr = build_indirect_ref ($1, "->");
- $$ = build_component_ref (expr, $3);
+ tree expr = build_indirect_ref ($1.value, "->");
+ $$.value = build_component_ref (expr, $3);
+ $$.original_code = ERROR_MARK;
}
| primary PLUSPLUS
- { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
+ { $$.value = build_unary_op (POSTINCREMENT_EXPR, $1.value, 0);
+ $$.original_code = ERROR_MARK; }
| primary MINUSMINUS
- { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
+ { $$.value = build_unary_op (POSTDECREMENT_EXPR, $1.value, 0);
+ $$.original_code = ERROR_MARK; }
@@ifobjc
| objcmessageexpr
- { $$ = build_message_expr ($1); }
+ { $$.value = build_message_expr ($1);
+ $$.original_code = ERROR_MARK; }
| objcselectorexpr
- { $$ = build_selector_expr ($1); }
+ { $$.value = build_selector_expr ($1);
+ $$.original_code = ERROR_MARK; }
| objcprotocolexpr
- { $$ = build_protocol_expr ($1); }
+ { $$.value = build_protocol_expr ($1);
+ $$.original_code = ERROR_MARK; }
| objcencodeexpr
- { $$ = build_encode_expr ($1); }
+ { $$.value = build_encode_expr ($1);
+ $$.original_code = ERROR_MARK; }
| OBJC_STRING
- { $$ = build_objc_string_object ($1); }
+ { $$.value = build_objc_string_object ($1);
+ $$.original_code = ERROR_MARK; }
@@end_ifobjc
;
| offsetof_member_designator '.' identifier
{ $$ = tree_cons ($3, NULL_TREE, $1); }
| offsetof_member_designator '[' expr ']'
- { $$ = tree_cons (NULL_TREE, $3, $1); }
+ { $$ = tree_cons (NULL_TREE, $3.value, $1); }
;
old_style_parm_decls:
@@end_ifobjc
| typeof '(' expr ')'
{ skip_evaluation--;
- if (TREE_CODE ($3) == COMPONENT_REF
- && DECL_C_BIT_FIELD (TREE_OPERAND ($3, 1)))
+ if (TREE_CODE ($3.value) == COMPONENT_REF
+ && DECL_C_BIT_FIELD (TREE_OPERAND ($3.value, 1)))
error ("`typeof' applied to a bit-field");
- $$ = TREE_TYPE ($3); }
+ $$ = TREE_TYPE ($3.value); }
| typeof '(' typename ')'
{ skip_evaluation--; $$ = groktypename ($3); }
;
init:
expr_no_commas
+ { $$ = $1.value; }
| '{'
{ really_start_incremental_init (NULL_TREE); }
initlist_maybe_comma '}'
initlist_maybe_comma '}'
{ process_init_element (pop_init_level (0)); }
| expr_no_commas
- { process_init_element ($1); }
+ { process_init_element ($1.value); }
| error
;
'.' identifier
{ set_init_label ($2); }
| '[' expr_no_commas ELLIPSIS expr_no_commas ']'
- { set_init_index ($2, $4);
+ { set_init_index ($2.value, $4.value);
if (pedantic)
pedwarn ("ISO C forbids specifying range of elements to initialize"); }
| '[' expr_no_commas ']'
- { set_init_index ($2, NULL_TREE); }
+ { set_init_index ($2.value, NULL_TREE); }
;
\f
nested_function:
decl_attributes (&$$,
chainon ($2, all_prefix_attributes), 0); }
| declarator ':' expr_no_commas maybe_attribute
- { $$ = grokfield ($1, current_declspecs, $3);
+ { $$ = grokfield ($1, current_declspecs, $3.value);
decl_attributes (&$$,
chainon ($4, all_prefix_attributes), 0); }
| ':' expr_no_commas maybe_attribute
- { $$ = grokfield (NULL_TREE, current_declspecs, $2);
+ { $$ = grokfield (NULL_TREE, current_declspecs, $2.value);
decl_attributes (&$$,
chainon ($3, all_prefix_attributes), 0); }
;
decl_attributes (&$$,
chainon ($2, all_prefix_attributes), 0); }
| notype_declarator ':' expr_no_commas maybe_attribute
- { $$ = grokfield ($1, current_declspecs, $3);
+ { $$ = grokfield ($1, current_declspecs, $3.value);
decl_attributes (&$$,
chainon ($4, all_prefix_attributes), 0); }
| ':' expr_no_commas maybe_attribute
- { $$ = grokfield (NULL_TREE, current_declspecs, $2);
+ { $$ = grokfield (NULL_TREE, current_declspecs, $2.value);
decl_attributes (&$$,
chainon ($3, all_prefix_attributes), 0); }
;
identifier
{ $$ = build_enumerator ($1, NULL_TREE); }
| identifier '=' expr_no_commas
- { $$ = build_enumerator ($1, $3); }
+ { $$ = build_enumerator ($1, $3.value); }
;
typename:
array_declarator:
'[' maybe_type_quals_attrs expr_no_commas ']'
- { $$ = build_array_declarator ($3, $2, 0, 0); }
+ { $$ = build_array_declarator ($3.value, $2, 0, 0); }
| '[' maybe_type_quals_attrs ']'
{ $$ = build_array_declarator (NULL_TREE, $2, 0, 0); }
| '[' maybe_type_quals_attrs '*' ']'
{ $$ = build_array_declarator (NULL_TREE, $2, 0, 1); }
| '[' STATIC maybe_type_quals_attrs expr_no_commas ']'
- { $$ = build_array_declarator ($4, $3, 1, 0); }
+ { $$ = build_array_declarator ($4.value, $3, 1, 0); }
/* declspecs_nosc_nots is a synonym for type_quals_attrs. */
| '[' declspecs_nosc_nots STATIC expr_no_commas ']'
- { $$ = build_array_declarator ($4, $2, 1, 0); }
+ { $$ = build_array_declarator ($4.value, $2, 1, 0); }
;
/* A nonempty series of declarations and statements (possibly followed by
;
condition: save_location expr
- { $$ = lang_hooks.truthvalue_conversion ($2);
+ { $$ = lang_hooks.truthvalue_conversion ($2.value);
if (EXPR_P ($$))
SET_EXPR_LOCATION ($$, $1); }
;
/* empty */
{ $$ = NULL_TREE; }
| expr
+ { $$ = $1.value; }
;
for_init_stmt:
switch_statement:
SWITCH c99_block_start '(' expr ')'
- { $<ttype>$ = c_start_case ($4); }
+ { $<ttype>$ = c_start_case ($4.value); }
start_break c99_block_lineno_labeled_stmt
{ c_finish_case ($8);
if (c_break_label)
/* Parse a single real statement, not including any labels or compounds. */
stmt_nocomp:
expr ';'
- { $$ = c_finish_expr_stmt ($1); }
+ { $$ = c_finish_expr_stmt ($1.value); }
| if_statement
{ $$ = NULL_TREE; }
| while_statement
| RETURN ';'
{ $$ = c_finish_return (NULL_TREE); }
| RETURN expr ';'
- { $$ = c_finish_return ($2); }
+ { $$ = c_finish_return ($2.value); }
| asm_stmt
| GOTO identifier ';'
{ $$ = c_finish_goto_label ($2); }
| GOTO '*' expr ';'
- { $$ = c_finish_goto_ptr ($3); }
+ { $$ = c_finish_goto_ptr ($3.value); }
| ';'
{ $$ = NULL_TREE; }
@@ifobjc
| AT_THROW expr ';'
- { $$ = objc_build_throw_stmt ($2); }
+ { $$ = objc_build_throw_stmt ($2.value); }
| AT_THROW ';'
{ $$ = objc_build_throw_stmt (NULL_TREE); }
| objc_try_catch_stmt
{ $$ = NULL_TREE; }
| AT_SYNCHRONIZED save_location '(' expr ')' compstmt
- { objc_build_synchronized ($2, $4, $6); $$ = NULL_TREE; }
+ { objc_build_synchronized ($2, $4.value, $6); $$ = NULL_TREE; }
;
objc_catch_prefix:
also at the end of a compound statement. */
label: CASE expr_no_commas ':'
- { $$ = do_case ($2, NULL_TREE); }
+ { $$ = do_case ($2.value, NULL_TREE); }
| CASE expr_no_commas ELLIPSIS expr_no_commas ':'
- { $$ = do_case ($2, $4); }
+ { $$ = do_case ($2.value, $4.value); }
| DEFAULT ':'
{ $$ = do_case (NULL_TREE, NULL_TREE); }
| identifier save_location ':' maybe_attribute
asm_operand:
STRING start_string_translation '(' expr ')' stop_string_translation
- { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $4); }
+ { $$ = build_tree_list (build_tree_list (NULL_TREE, $1),
+ $4.value); }
| '[' identifier ']' STRING start_string_translation
'(' expr ')' stop_string_translation
{ $2 = build_string (IDENTIFIER_LENGTH ($2),
IDENTIFIER_POINTER ($2));
- $$ = build_tree_list (build_tree_list ($2, $4), $7); }
+ $$ = build_tree_list (build_tree_list ($2, $4), $7.value); }
;
asm_clobbers:
{
$$ = add_instance_variable (objc_ivar_context,
objc_public_flag,
- $1, current_declspecs, $3);
+ $1, current_declspecs, $3.value);
}
| ':' expr_no_commas
{
$$ = add_instance_variable (objc_ivar_context,
objc_public_flag,
NULL_TREE,
- current_declspecs, $2);
+ current_declspecs, $2.value);
}
;
receiver:
expr
+ { $$ = $1.value; }
| CLASSNAME
{
$$ = get_class_reference ($1);
static tree lookup_field (tree, tree);
static tree convert_arguments (tree, tree, tree, tree);
static tree pointer_diff (tree, tree);
-static tree internal_build_compound_expr (tree, int);
static tree convert_for_assignment (tree, tree, const char *, tree, tree,
int);
static void warn_for_assignment (const char *, const char *, tree, int);
exp = TREE_OPERAND (exp, 0);
}
- /* Preserve the original expression code. */
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (exp))))
- C_SET_EXP_ORIGINAL_CODE (exp, C_EXP_ORIGINAL_CODE (orig_exp));
+ if (TREE_NO_WARNING (orig_exp))
+ TREE_NO_WARNING (exp) = 1;
if (code == FUNCTION_TYPE)
{
&& TREE_TYPE (TREE_OPERAND (exp, 0)) == TREE_TYPE (exp)))
exp = TREE_OPERAND (exp, 0);
- /* Preserve the original expression code. */
- if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (exp))))
- C_SET_EXP_ORIGINAL_CODE (exp, C_EXP_ORIGINAL_CODE (orig_exp));
+ if (TREE_NO_WARNING (orig_exp))
+ TREE_NO_WARNING (exp) = 1;
/* Normally convert enums to int,
but convert wide enums to something wider. */
we check for operands that were written with other binary operators
in a way that is likely to confuse the user. */
-tree
-parser_build_binary_op (enum tree_code code, tree arg1, tree arg2)
+struct c_expr
+parser_build_binary_op (enum tree_code code, struct c_expr arg1,
+ struct c_expr arg2)
{
- tree result = build_binary_op (code, arg1, arg2, 1);
+ struct c_expr result;
- char class;
- char class1 = TREE_CODE_CLASS (TREE_CODE (arg1));
- char class2 = TREE_CODE_CLASS (TREE_CODE (arg2));
- enum tree_code code1 = ERROR_MARK;
- enum tree_code code2 = ERROR_MARK;
+ enum tree_code code1 = arg1.original_code;
+ enum tree_code code2 = arg2.original_code;
- if (TREE_CODE (result) == ERROR_MARK)
- return error_mark_node;
+ result.value = build_binary_op (code, arg1.value, arg2.value, 1);
+ result.original_code = code;
- if (IS_EXPR_CODE_CLASS (class1))
- code1 = C_EXP_ORIGINAL_CODE (arg1);
- if (IS_EXPR_CODE_CLASS (class2))
- code2 = C_EXP_ORIGINAL_CODE (arg2);
+ if (TREE_CODE (result.value) == ERROR_MARK)
+ return result;
/* Check for cases such as x+y<<z which users are likely
- to misinterpret. If parens are used, C_EXP_ORIGINAL_CODE
- is cleared to prevent these warnings. */
+ to misinterpret. */
if (warn_parentheses)
{
if (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
}
- unsigned_conversion_warning (result, arg1);
- unsigned_conversion_warning (result, arg2);
- overflow_warning (result);
-
- class = TREE_CODE_CLASS (TREE_CODE (result));
-
- /* Record the code that was specified in the source,
- for the sake of warnings about confusing nesting. */
- if (IS_EXPR_CODE_CLASS (class))
- C_SET_EXP_ORIGINAL_CODE (result, code);
- else
- {
- /* We used to use NOP_EXPR rather than NON_LVALUE_EXPR
- so that convert_for_assignment wouldn't strip it.
- That way, we got warnings for things like p = (1 - 1).
- But it turns out we should not get those warnings. */
- result = build1 (NON_LVALUE_EXPR, TREE_TYPE (result), result);
- C_SET_EXP_ORIGINAL_CODE (result, code);
- }
+ unsigned_conversion_warning (result.value, arg1.value);
+ unsigned_conversion_warning (result.value, arg2.value);
+ overflow_warning (result.value);
return result;
}
return fold (build (COND_EXPR, result_type, ifexp, op1, op2));
}
\f
-/* Given a list of expressions, return a compound expression
- that performs them all and returns the value of the last of them. */
+/* Return a compound expression that performs two expressions and
+ returns the value of the second of them. */
tree
-build_compound_expr (tree list)
+build_compound_expr (tree expr1, tree expr2)
{
- return internal_build_compound_expr (list, TRUE);
-}
-
-static tree
-internal_build_compound_expr (tree list, int first_p)
-{
- tree rest;
-
- if (TREE_CHAIN (list) == 0)
- {
- /* Convert arrays and functions to pointers when there
- really is a comma operator. */
- if (!first_p)
- TREE_VALUE (list)
- = default_function_array_conversion (TREE_VALUE (list));
-
- /* Don't let (0, 0) be null pointer constant. */
- if (!first_p && integer_zerop (TREE_VALUE (list)))
- return non_lvalue (TREE_VALUE (list));
- return TREE_VALUE (list);
- }
+ /* Convert arrays and functions to pointers. */
+ expr2 = default_function_array_conversion (expr2);
- rest = internal_build_compound_expr (TREE_CHAIN (list), FALSE);
+ /* Don't let (0, 0) be null pointer constant. */
+ if (integer_zerop (expr2))
+ expr2 = non_lvalue (expr2);
- if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)))
+ if (! TREE_SIDE_EFFECTS (expr1))
{
/* The left-hand operand of a comma expression is like an expression
statement: with -Wextra or -Wunused, we should warn if it doesn't have
any side-effects, unless it was explicitly cast to (void). */
if (warn_unused_value
- && ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR
- && VOID_TYPE_P (TREE_TYPE (TREE_VALUE (list)))))
+ && ! (TREE_CODE (expr1) == CONVERT_EXPR
+ && VOID_TYPE_P (TREE_TYPE (expr1))))
warning ("left-hand operand of comma expression has no effect");
}
`foo() + bar(), baz()' the result of the `+' operator is not used,
so we should issue a warning. */
else if (warn_unused_value)
- warn_if_unused_value (TREE_VALUE (list), input_location);
+ warn_if_unused_value (expr1, input_location);
- return build (COMPOUND_EXPR, TREE_TYPE (rest), TREE_VALUE (list), rest);
+ return build (COMPOUND_EXPR, TREE_TYPE (expr2), expr1, expr2);
}
/* Build an expression representing a cast to type TYPE of expression EXPR. */