/* A single C token after string literal concatenation and conversion
of preprocessing tokens to tokens. */
-typedef struct c_token GTY (())
-{
+typedef struct GTY (()) c_token {
/* The kind of token. */
ENUM_BITFIELD (cpp_ttype) type : 8;
/* If this token is a CPP_NAME, this value indicates whether also
/* A parser structure recording information about the state and
context of parsing. Includes lexer information with up to two
tokens of look-ahead; more are not needed for C. */
-typedef struct c_parser GTY(())
-{
+typedef struct GTY(()) c_parser {
/* The look-ahead tokens. */
c_token tokens[2];
/* How many look-ahead tokens are available (0, 1 or 2). */
{
warning_at (token->location,
OPT_Wc___compat,
- "identifier %qs conflicts with C++ keyword",
- IDENTIFIER_POINTER (token->value));
+ "identifier %qE conflicts with C++ keyword",
+ token->value);
}
else if (c_dialect_objc ())
{
CPP_KEYWORD, keywords are treated like
identifiers. */
(token->type == CPP_KEYWORD ? CPP_NAME : token->type),
- token->value);
+ /* ??? The C parser does not save the cpp flags of a
+ token, we need to pass 0 here and we will not get
+ the source spelling of some tokens but rather the
+ canonical spelling. */
+ token->value, /*flags=*/0);
}
/* If the next token is of the indicated TYPE, consume it. Otherwise,
| (warn_pointer_arith << 1)
| (warn_traditional << 2)
| (flag_iso << 3)
- | (warn_long_long << 4)
- | (cpp_opts->warn_long_long << 5));
+ | (warn_long_long << 4));
cpp_opts->pedantic = pedantic = 0;
warn_pointer_arith = 0;
cpp_opts->warn_traditional = warn_traditional = 0;
flag_iso = 0;
- warn_long_long = 0;
- cpp_opts->warn_long_long = 0;
+ cpp_opts->warn_long_long = warn_long_long = 0;
return ret;
}
warn_pointer_arith = (flags >> 1) & 1;
cpp_opts->warn_traditional = warn_traditional = (flags >> 2) & 1;
flag_iso = (flags >> 3) & 1;
- warn_long_long = (flags >> 4) & 1;
- cpp_opts->warn_long_long = (flags >> 5) & 1;
+ cpp_opts->warn_long_long = warn_long_long = (flags >> 4) & 1;
}
/* Possibly kinds of declarator to parse. */
else
{
void *obstack_position = obstack_alloc (&parser_obstack, 0);
+ mark_valid_location_for_stdc_pragma (false);
do
{
ggc_collect ();
c_parser_consume_token (parser);
break;
case CPP_PRAGMA:
+ mark_valid_location_for_stdc_pragma (true);
c_parser_pragma (parser, pragma_external);
+ mark_valid_location_for_stdc_pragma (false);
break;
case CPP_PLUS:
case CPP_MINUS:
{
bool last_stmt = false;
bool last_label = false;
+ bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
c_parser_consume_token (parser);
return;
}
+ mark_valid_location_for_stdc_pragma (true);
if (c_parser_next_token_is_keyword (parser, RID_LABEL))
{
location_t err_loc = c_parser_peek_token (parser)->location;
/* Read zero or more forward-declarations for labels that nested
functions can jump to. */
+ mark_valid_location_for_stdc_pragma (false);
while (c_parser_next_token_is_keyword (parser, RID_LABEL))
{
c_parser_consume_token (parser);
/* We must now have at least one statement, label or declaration. */
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
{
+ mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
c_parser_error (parser, "expected declaration or statement");
c_parser_consume_token (parser);
return;
label_loc = c_parser_peek_token (parser)->location;
last_label = true;
last_stmt = false;
+ mark_valid_location_for_stdc_pragma (false);
c_parser_label (parser);
}
else if (!last_label
&& c_parser_next_token_starts_declspecs (parser))
{
last_label = false;
+ mark_valid_location_for_stdc_pragma (false);
c_parser_declaration_or_fndef (parser, true, true, true, true);
if (last_stmt)
pedwarn_c90 (loc,
ext = disable_extension_diagnostics ();
c_parser_consume_token (parser);
last_label = false;
+ mark_valid_location_for_stdc_pragma (false);
c_parser_declaration_or_fndef (parser, true, true, true, true);
/* Following the old parser, __extension__ does not
disable this diagnostic. */
}
else if (c_parser_next_token_is (parser, CPP_EOF))
{
+ mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
c_parser_error (parser, "expected declaration or statement");
return;
}
{
if (parser->in_if_block)
{
+ mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
error_at (loc, """expected %<}%> before %<else%>");
return;
}
statement:
last_label = false;
last_stmt = true;
+ mark_valid_location_for_stdc_pragma (false);
c_parser_statement_after_labels (parser);
}
if (last_label)
error_at (label_loc, "label at end of compound statement");
c_parser_consume_token (parser);
+ /* Restore the value we started with. */
+ mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
}
/* Parse a label (C90 6.6.1, C99 6.8.1).
cond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (loc, cond);
cond = c_fully_fold (cond, false, NULL);
- protected_set_expr_location (cond, loc);
if (warn_sequence_point)
verify_sequence_points (cond);
return cond;
c_parser_consume_token (parser);
rhs = c_parser_expr_no_commas (parser, NULL);
rhs = default_function_array_conversion (rhs);
- ret.value = build_modify_expr (op_location, lhs.value, code, rhs.value,
- rhs.original_type);
+ ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
+ code, rhs.value, rhs.original_type);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
cond_loc = c_parser_peek_token (parser)->location;
cond = c_parser_binary_expression (parser, after);
- protected_set_expr_location (cond.value, cond_loc);
if (c_parser_next_token_is_not (parser, CPP_QUERY))
return cond;
enum prec prec;
/* The operation on its left. */
enum tree_code op;
+ /* The source location of this operation. */
+ location_t loc;
} stack[NUM_PRECS];
int sp;
/* Location of the binary operator. */
= default_function_array_conversion (stack[sp - 1].expr); \
stack[sp].expr \
= default_function_array_conversion (stack[sp].expr); \
- stack[sp - 1].expr = parser_build_binary_op (binary_loc, \
+ stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \
stack[sp].op, \
stack[sp - 1].expr, \
stack[sp].expr); \
sp--; \
} while (0)
gcc_assert (!after || c_dialect_objc ());
+ stack[0].loc = c_parser_peek_token (parser)->location;
stack[0].expr = c_parser_cast_expression (parser, after);
stack[0].prec = PREC_NONE;
sp = 0;
stack[sp].expr
= default_function_array_conversion (stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
- (binary_loc, default_conversion (stack[sp].expr.value));
+ (stack[sp].loc, default_conversion (stack[sp].expr.value));
skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
break;
case TRUTH_ORIF_EXPR:
stack[sp].expr
= default_function_array_conversion (stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
- (binary_loc, default_conversion (stack[sp].expr.value));
+ (stack[sp].loc, default_conversion (stack[sp].expr.value));
skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
break;
default:
break;
}
sp++;
+ stack[sp].loc = binary_loc;
stack[sp].expr = c_parser_cast_expression (parser, NULL);
stack[sp].prec = oprec;
stack[sp].op = ocode;
next = default_function_array_conversion (next);
expr.value = build_compound_expr (expr.value, next.value);
expr.original_code = COMPOUND_EXPR;
- expr.original_type = NULL;
+ expr.original_type = next.original_type;
}
return expr;
}
else if (c_parser_next_token_is (parser, CPP_NAME)
&& c_parser_peek_2nd_token (parser)->type == CPP_EQ)
{
+ struct c_expr decl_exp;
struct c_expr init_exp;
location_t init_loc;
- decl = c_parser_postfix_expression (parser).value;
+ decl_exp = c_parser_postfix_expression (parser);
+ decl = decl_exp.value;
c_parser_require (parser, CPP_EQ, "expected %<=%>");
init_loc = c_parser_peek_token (parser)->location;
init_exp = c_parser_expr_no_commas (parser, NULL);
init_exp = default_function_array_conversion (init_exp);
- init = build_modify_expr (init_loc,
- decl, NOP_EXPR, init_exp.value,
+ init = build_modify_expr (init_loc, decl, decl_exp.original_type,
+ NOP_EXPR, init_exp.value,
init_exp.original_type);
init = c_process_expr_stmt (init);