#include "vec.h"
#include "target.h"
#include "cgraph.h"
+#include "plugin.h"
\f
/* Initialization routine for this file. */
/* 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_traditional << 2)
| (flag_iso << 3)
| (warn_long_long << 4)
- | (cpp_opts->warn_long_long << 5));
+ | (warn_cxx_compat << 5));
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;
+ warn_cxx_compat = 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;
+ warn_cxx_compat = (flags >> 5) & 1;
}
/* Possibly kinds of declarator to parse. */
static struct c_expr c_parser_alignof_expression (c_parser *);
static struct c_expr c_parser_postfix_expression (c_parser *);
static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
- struct c_type_name *);
+ struct c_type_name *,
+ location_t);
static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
+ location_t loc,
struct c_expr);
static struct c_expr c_parser_expression (c_parser *);
static struct c_expr c_parser_expression_conv (c_parser *);
-static tree c_parser_expr_list (c_parser *, bool, bool);
+static VEC(tree,gc) *c_parser_expr_list (c_parser *, bool, bool,
+ VEC(tree,gc) **);
static void c_parser_omp_construct (c_parser *);
static void c_parser_omp_threadprivate (c_parser *);
static void c_parser_omp_barrier (c_parser *);
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:
{
tree d;
struct c_expr init;
+ location_t init_loc;
c_parser_consume_token (parser);
/* The declaration of the variable is in effect while
its initializer is parsed. */
if (!d)
d = error_mark_node;
start_init (d, asm_name, global_bindings_p ());
+ init_loc = c_parser_peek_token (parser)->location;
init = c_parser_initializer (parser);
finish_init ();
if (d != error_mark_node)
{
maybe_warn_string_init (TREE_TYPE (d), init);
- finish_decl (d, init.value, asm_name);
+ finish_decl (d, init_loc, init.value,
+ init.original_type, asm_name);
}
}
else
chainon (postfix_attrs,
all_prefix_attrs));
if (d)
- finish_decl (d, NULL_TREE, asm_name);
+ finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
+ NULL_TREE, asm_name);
}
if (c_parser_next_token_is (parser, CPP_COMMA))
{
add_stmt (fnbody);
finish_function ();
c_pop_function_context ();
- add_stmt (build_stmt (DECL_EXPR, decl));
+ add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
}
else
{
{
struct c_typespec t;
tree attrs;
+ location_t loc = c_parser_peek_token (parser)->location;
if (c_parser_next_token_is (parser, CPP_NAME))
{
tree value = c_parser_peek_token (parser)->value;
t.expr = NULL_TREE;
t.expr_const_operands = true;
}
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
continue;
}
if (c_parser_next_token_is (parser, CPP_LESS))
t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
t.expr = NULL_TREE;
t.expr_const_operands = true;
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
continue;
}
gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
t.spec = c_parser_peek_token (parser)->value;
t.expr = NULL_TREE;
t.expr_const_operands = true;
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
c_parser_consume_token (parser);
break;
case RID_ENUM:
attrs_ok = true;
seen_type = true;
t = c_parser_enum_specifier (parser);
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
break;
case RID_STRUCT:
case RID_UNION:
attrs_ok = true;
seen_type = true;
t = c_parser_struct_or_union_specifier (parser);
- declspecs_add_type (specs, t);
+ invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
+ declspecs_add_type (loc, specs, t);
break;
case RID_TYPEOF:
/* ??? The old parser rejected typeof after other type
attrs_ok = true;
seen_type = true;
t = c_parser_typeof_specifier (parser);
- declspecs_add_type (specs, t);
+ declspecs_add_type (loc, specs, t);
break;
case RID_CONST:
case RID_VOLATILE:
struct c_typespec ret;
tree attrs;
tree ident = NULL_TREE;
+ location_t enum_loc;
location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */
gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
+ enum_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
attrs = c_parser_attributes (parser);
+ enum_loc = c_parser_peek_token (parser)->location;
/* Set the location in case we create a decl now. */
c_parser_set_source_position_from_token (c_parser_peek_token (parser));
if (c_parser_next_token_is (parser, CPP_NAME))
{
ident = c_parser_peek_token (parser)->value;
ident_loc = c_parser_peek_token (parser)->location;
+ enum_loc = ident_loc;
c_parser_consume_token (parser);
}
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
{
/* Parse an enum definition. */
struct c_enum_contents the_enum;
- tree type = start_enum (&the_enum, ident);
+ tree type = start_enum (enum_loc, &the_enum, ident);
tree postfix_attrs;
/* We chain the enumerators in reverse order, then put them in
forward order at the end. */
}
else
enum_value = NULL_TREE;
- enum_decl = build_enumerator (&the_enum, enum_id, enum_value,
- value_loc);
+ enum_decl = build_enumerator (value_loc,
+ &the_enum, enum_id, enum_value);
TREE_CHAIN (enum_decl) = values;
values = enum_decl;
seen_comma = false;
ret.expr_const_operands = true;
return ret;
}
- ret = parser_xref_tag (ENUMERAL_TYPE, ident);
+ ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident);
/* In ISO C, enumerated types can be referred to only if already
defined. */
if (pedantic && !COMPLETE_TYPE_P (ret.spec))
{
gcc_assert (ident);
- pedwarn (ident_loc, OPT_pedantic,
+ pedwarn (enum_loc, OPT_pedantic,
"ISO C forbids forward references to %<enum%> types");
}
return ret;
struct c_typespec ret;
tree attrs;
tree ident = NULL_TREE;
+ location_t struct_loc;
+ location_t ident_loc = UNKNOWN_LOCATION;
enum tree_code code;
switch (c_parser_peek_token (parser)->keyword)
{
default:
gcc_unreachable ();
}
+ struct_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
attrs = c_parser_attributes (parser);
+
/* Set the location in case we create a decl now. */
c_parser_set_source_position_from_token (c_parser_peek_token (parser));
+
if (c_parser_next_token_is (parser, CPP_NAME))
{
ident = c_parser_peek_token (parser)->value;
+ ident_loc = c_parser_peek_token (parser)->location;
+ struct_loc = ident_loc;
c_parser_consume_token (parser);
}
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
{
/* Parse a struct or union definition. Start the scope of the
tag before parsing components. */
- tree type = start_struct (code, ident);
+ struct c_struct_parse_info *struct_info;
+ tree type = start_struct (struct_loc, code, ident, &struct_info);
tree postfix_attrs;
/* We chain the components in reverse order, then put them in
forward order at the end. Each struct-declaration may
}
}
postfix_attrs = c_parser_attributes (parser);
- ret.spec = finish_struct (type, nreverse (contents),
- chainon (attrs, postfix_attrs));
+ ret.spec = finish_struct (struct_loc, type, nreverse (contents),
+ chainon (attrs, postfix_attrs), struct_info);
ret.kind = ctsk_tagdef;
ret.expr = NULL_TREE;
ret.expr_const_operands = true;
ret.expr_const_operands = true;
return ret;
}
- ret = parser_xref_tag (code, ident);
+ ret = parser_xref_tag (ident_loc, code, ident);
return ret;
}
ret.expr_const_operands = true;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF));
c_parser_consume_token (parser);
- skip_evaluation++;
+ c_inhibit_evaluation_warnings++;
in_typeof++;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_typeof--;
return ret;
}
if (c_parser_next_token_starts_typename (parser))
{
struct c_type_name *type = c_parser_type_name (parser);
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_typeof--;
if (type != NULL)
{
bool was_vm;
location_t here = c_parser_peek_token (parser)->location;
struct c_expr expr = c_parser_expression (parser);
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_typeof--;
if (TREE_CODE (expr.value) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
/* Parse a sequence of array declarators and parameter lists. */
if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
{
+ location_t brace_loc = c_parser_peek_token (parser)->location;
struct c_declarator *declarator;
struct c_declspecs *quals_attrs = build_null_declspecs ();
bool static_seen;
"expected %<]%>");
return NULL;
}
- declarator = build_array_declarator (dimen, quals_attrs, static_seen,
- star_seen);
+ declarator = build_array_declarator (brace_loc, dimen, quals_attrs,
+ static_seen, star_seen);
if (declarator == NULL)
return NULL;
inner = set_array_declarator_inner (declarator, inner);
|| c_parser_next_token_is (parser, CPP_KEYWORD))
{
tree attr, attr_name, attr_args;
+ VEC(tree,gc) *expr_list;
if (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
attr_args = build_tree_list (NULL_TREE, arg1);
else
{
+ tree tree_list;
c_parser_consume_token (parser);
- attr_args = tree_cons (NULL_TREE, arg1,
- c_parser_expr_list (parser, false,
- true));
+ expr_list = c_parser_expr_list (parser, false, true, NULL);
+ tree_list = build_tree_list_vec (expr_list);
+ attr_args = tree_cons (NULL_TREE, arg1, tree_list);
+ release_tree_vector (expr_list);
}
}
else
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
attr_args = NULL_TREE;
else
- attr_args = c_parser_expr_list (parser, false, true);
+ {
+ expr_list = c_parser_expr_list (parser, false, true, NULL);
+ attr_args = build_tree_list_vec (expr_list);
+ release_tree_vector (expr_list);
+ }
}
attr = build_tree_list (attr_name, attr_args);
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
else
{
struct c_expr ret;
+ location_t loc = c_parser_peek_token (parser)->location;
ret = c_parser_expr_no_commas (parser, NULL);
if (TREE_CODE (ret.value) != STRING_CST
&& TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR)
- ret = default_function_array_conversion (ret);
+ ret = default_function_array_conversion (loc, ret);
return ret;
}
}
struct c_expr ret;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, "expected %<}%>");
pop_init_level (0);
return ret;
struct c_expr init;
init.value = error_mark_node;
init.original_code = ERROR_MARK;
+ init.original_type = NULL;
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
process_init_element (init, false);
while (c_parser_next_token_is (parser, CPP_COMMA))
{
struct c_expr next;
+ location_t comma_loc, exp_loc;
+ comma_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
next = c_parser_expr_no_commas (parser, NULL);
- next = default_function_array_conversion (next);
- rec = build_compound_expr (rec, next.value);
+ next = default_function_array_conversion (exp_loc, next);
+ rec = build_compound_expr (comma_loc, rec, next.value);
}
parse_message_args:
/* Now parse the objc-message-args. */
mexpr.value
= objc_build_message_expr (build_tree_list (rec, args));
mexpr.original_code = ERROR_MARK;
+ mexpr.original_type = NULL;
/* Now parse and process the remainder of the
initializer, starting with this message
expression as a primary-expression. */
struct c_expr init;
init.value = error_mark_node;
init.original_code = ERROR_MARK;
+ init.original_type = NULL;
c_parser_error (parser, "expected %<=%>");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
process_init_element (init, false);
init = c_parser_braced_init (parser, NULL_TREE, true);
else
{
+ location_t loc = c_parser_peek_token (parser)->location;
init = c_parser_expr_no_commas (parser, after);
if (init.value != NULL_TREE
&& TREE_CODE (init.value) != STRING_CST
&& TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
- init = default_function_array_conversion (init);
+ init = default_function_array_conversion (loc, init);
}
process_init_element (init, false);
}
c_parser_compound_statement (c_parser *parser)
{
tree stmt;
+ location_t brace_loc;
+ brace_loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
{
/* Ensure a scope is entered and left anyway to avoid confusion
if we have just prepared to enter a function body. */
stmt = c_begin_compound_stmt (true);
- c_end_compound_stmt (stmt, true);
+ c_end_compound_stmt (brace_loc, stmt, true);
return error_mark_node;
}
stmt = c_begin_compound_stmt (true);
c_parser_compound_statement_nostart (parser);
- return c_end_compound_stmt (stmt, true);
+ return c_end_compound_stmt (brace_loc, stmt, true);
}
/* Parse a compound statement except for the opening brace. This is
{
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))
{
+ label_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
/* Any identifiers, including those declared as type names,
are OK here. */
label
= declare_label (c_parser_peek_token (parser)->value);
C_DECLARED_LABEL_FLAG (label) = 1;
- add_stmt (build_stmt (DECL_EXPR, label));
+ add_stmt (build_stmt (label_loc, DECL_EXPR, label));
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_COMMA))
c_parser_consume_token (parser);
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
- pedwarn (err_loc, OPT_pedantic, "ISO C forbids label declarations");
+ pedwarn (label_loc, OPT_pedantic, "ISO C forbids label declarations");
}
/* 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).
if (c_parser_next_token_is (parser, CPP_COLON))
{
c_parser_consume_token (parser);
- label = do_case (exp1, NULL_TREE);
+ label = do_case (loc1, exp1, NULL_TREE);
}
else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
{
c_parser_consume_token (parser);
exp2 = c_parser_expr_no_commas (parser, NULL).value;
if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
- label = do_case (exp1, exp2);
+ label = do_case (loc1, exp1, exp2);
}
else
c_parser_error (parser, "expected %<:%> or %<...%>");
{
c_parser_consume_token (parser);
if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
- label = do_case (NULL_TREE, NULL_TREE);
+ label = do_case (loc1, NULL_TREE, NULL_TREE);
}
else
{
if (tlab)
{
decl_attributes (&tlab, attrs, 0);
- label = add_stmt (build_stmt (LABEL_EXPR, tlab));
+ label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
}
}
if (label)
{
- SET_EXPR_LOCATION (label, loc1);
if (c_parser_next_token_starts_declspecs (parser)
&& !(c_parser_next_token_is (parser, CPP_NAME)
&& c_parser_peek_2nd_token (parser)->type == CPP_COLON))
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_NAME))
{
- stmt = c_finish_goto_label (c_parser_peek_token (parser)->value);
+ stmt = c_finish_goto_label (loc,
+ c_parser_peek_token (parser)->value);
c_parser_consume_token (parser);
}
else if (c_parser_next_token_is (parser, CPP_MULT))
{
c_parser_consume_token (parser);
- stmt = c_finish_goto_ptr (c_parser_expression (parser).value);
+ stmt = c_finish_goto_ptr (loc,
+ c_parser_expression (parser).value);
}
else
c_parser_error (parser, "expected identifier or %<*%>");
goto expect_semicolon;
case RID_CONTINUE:
c_parser_consume_token (parser);
- stmt = c_finish_bc_stmt (&c_cont_label, false);
+ stmt = c_finish_bc_stmt (loc, &c_cont_label, false);
goto expect_semicolon;
case RID_BREAK:
c_parser_consume_token (parser);
- stmt = c_finish_bc_stmt (&c_break_label, true);
+ stmt = c_finish_bc_stmt (loc, &c_break_label, true);
goto expect_semicolon;
case RID_RETURN:
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- stmt = c_finish_return (NULL_TREE);
+ stmt = c_finish_return (loc, NULL_TREE, NULL_TREE);
c_parser_consume_token (parser);
}
else
{
- stmt = c_finish_return (c_parser_expression_conv (parser).value);
+ struct c_expr expr = c_parser_expression_conv (parser);
+ stmt = c_finish_return (loc, expr.value, expr.original_type);
goto expect_semicolon;
}
break;
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- stmt = objc_build_throw_stmt (NULL_TREE);
+ stmt = objc_build_throw_stmt (loc, NULL_TREE);
c_parser_consume_token (parser);
}
else
{
tree expr = c_parser_expression (parser).value;
expr = c_fully_fold (expr, false, NULL);
- stmt = objc_build_throw_stmt (expr);
+ stmt = objc_build_throw_stmt (loc, expr);
goto expect_semicolon;
}
break;
break;
default:
expr_stmt:
- stmt = c_finish_expr_stmt (c_parser_expression_conv (parser).value);
+ stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
expect_semicolon:
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
break;
(recursively) all of the component statements should already have
line numbers assigned. ??? Can we discard no-op statements
earlier? */
- protected_set_expr_location (stmt, loc);
+ if (CAN_HAVE_LOCATION_P (stmt)
+ && EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
+ SET_EXPR_LOCATION (stmt, loc);
parser->in_if_block = in_if_block;
}
static tree
c_parser_condition (c_parser *parser)
{
- location_t loc;
+ location_t loc = c_parser_peek_token (parser)->location;
tree cond;
- loc = c_parser_peek_token (parser)->location;
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_c99_block_statement (c_parser *parser)
{
tree block = c_begin_compound_stmt (flag_isoc99);
+ location_t loc = c_parser_peek_token (parser)->location;
c_parser_statement (parser);
- return c_end_compound_stmt (block, flag_isoc99);
+ return c_end_compound_stmt (loc, block, flag_isoc99);
}
/* Parse the body of an if statement. This is just parsing a
c_parser_if_body (c_parser *parser, bool *if_p)
{
tree block = c_begin_compound_stmt (flag_isoc99);
+ location_t body_loc = c_parser_peek_token (parser)->location;
while (c_parser_next_token_is_keyword (parser, RID_CASE)
|| c_parser_next_token_is_keyword (parser, RID_DEFAULT)
|| (c_parser_next_token_is (parser, CPP_NAME)
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
location_t loc = c_parser_peek_token (parser)->location;
- add_stmt (build_empty_stmt ());
+ add_stmt (build_empty_stmt (loc));
c_parser_consume_token (parser);
if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
warning_at (loc, OPT_Wempty_body,
add_stmt (c_parser_compound_statement (parser));
else
c_parser_statement_after_labels (parser);
- return c_end_compound_stmt (block, flag_isoc99);
+ return c_end_compound_stmt (body_loc, block, flag_isoc99);
}
/* Parse the else body of an if statement. This is just parsing a
static tree
c_parser_else_body (c_parser *parser)
{
+ location_t else_loc = c_parser_peek_token (parser)->location;
tree block = c_begin_compound_stmt (flag_isoc99);
while (c_parser_next_token_is_keyword (parser, RID_CASE)
|| c_parser_next_token_is_keyword (parser, RID_DEFAULT)
c_parser_label (parser);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- warning_at (c_parser_peek_token (parser)->location,
+ location_t loc = c_parser_peek_token (parser)->location;
+ warning_at (loc,
OPT_Wempty_body,
"suggest braces around empty body in an %<else%> statement");
- add_stmt (build_empty_stmt ());
+ add_stmt (build_empty_stmt (loc));
c_parser_consume_token (parser);
}
else
c_parser_statement_after_labels (parser);
- return c_end_compound_stmt (block, flag_isoc99);
+ return c_end_compound_stmt (else_loc, block, flag_isoc99);
}
/* Parse an if statement (C90 6.6.4, C99 6.8.4).
else
second_body = NULL_TREE;
c_finish_if_stmt (loc, cond, first_body, second_body, first_if);
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
}
/* Parse a switch statement (C90 6.6.4, C99 6.8.4).
c_parser_switch_statement (c_parser *parser)
{
tree block, expr, body, save_break;
+ location_t switch_loc = c_parser_peek_token (parser)->location;
+ location_t switch_cond_loc;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
c_parser_consume_token (parser);
block = c_begin_compound_stmt (flag_isoc99);
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
+ switch_cond_loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser).value;
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
else
- expr = error_mark_node;
- c_start_case (expr);
+ {
+ switch_cond_loc = UNKNOWN_LOCATION;
+ expr = error_mark_node;
+ }
+ c_start_case (switch_loc, switch_cond_loc, expr);
save_break = c_break_label;
c_break_label = NULL_TREE;
body = c_parser_c99_block_statement (parser);
c_finish_case (body);
if (c_break_label)
- add_stmt (build1 (LABEL_EXPR, void_type_node, c_break_label));
+ {
+ location_t here = c_parser_peek_token (parser)->location;
+ tree t = build1 (LABEL_EXPR, void_type_node, c_break_label);
+ SET_EXPR_LOCATION (t, here);
+ add_stmt (t);
+ }
c_break_label = save_break;
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
}
/* Parse a while statement (C90 6.6.5, C99 6.8.5).
c_cont_label = NULL_TREE;
body = c_parser_c99_block_statement (parser);
c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
c_break_label = save_break;
c_cont_label = save_cont;
}
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
c_parser_skip_to_end_of_block_or_statement (parser);
c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
}
/* Parse a for statement (C90 6.6.5, C99 6.8.5).
c_parser_for_statement (c_parser *parser)
{
tree block, cond, incr, save_break, save_cont, body;
- location_t loc;
+ location_t loc = c_parser_peek_token (parser)->location;
+ location_t for_loc = c_parser_peek_token (parser)->location;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
- loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
block = c_begin_compound_stmt (flag_isoc99);
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
c_parser_consume_token (parser);
- c_finish_expr_stmt (NULL_TREE);
+ c_finish_expr_stmt (loc, NULL_TREE);
}
else if (c_parser_next_token_starts_declspecs (parser))
{
c_parser_declaration_or_fndef (parser, true, true, true, true);
- check_for_loop_decls ();
+ check_for_loop_decls (for_loc);
}
else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
{
c_parser_consume_token (parser);
c_parser_declaration_or_fndef (parser, true, true, true, true);
restore_extension_diagnostics (ext);
- check_for_loop_decls ();
+ check_for_loop_decls (for_loc);
}
else
goto init_expr;
else
{
init_expr:
- c_finish_expr_stmt (c_parser_expression (parser).value);
+ c_finish_expr_stmt (loc, c_parser_expression (parser).value);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
/* Parse the loop condition. */
}
/* Parse the increment expression. */
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- incr = c_process_expr_stmt (NULL_TREE);
+ incr = c_process_expr_stmt (loc, NULL_TREE);
else
- incr = c_process_expr_stmt (c_parser_expression (parser).value);
+ incr = c_process_expr_stmt (loc, c_parser_expression (parser).value);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
else
c_cont_label = NULL_TREE;
body = c_parser_c99_block_statement (parser);
c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true);
- add_stmt (c_end_compound_stmt (block, flag_isoc99));
+ add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
c_break_label = save_break;
c_cont_label = save_cont;
}
{
tree quals, str, outputs, inputs, clobbers, ret;
bool simple;
+ location_t asm_loc = c_parser_peek_token (parser)->location;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
c_parser_consume_token (parser);
if (c_parser_next_token_is_keyword (parser, RID_VOLATILE))
return NULL_TREE;
}
str = c_parser_asm_string_literal (parser);
+ if (str == NULL_TREE)
+ {
+ parser->lex_untranslated_string = false;
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ return NULL_TREE;
+ }
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
{
simple = true;
}
if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
c_parser_skip_to_end_of_block_or_statement (parser);
- ret = build_asm_stmt (quals, build_asm_expr (str, outputs, inputs,
+ ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs,
clobbers, simple));
return ret;
}
c_parser_asm_operands (c_parser *parser, bool convert_p)
{
tree list = NULL_TREE;
+ location_t loc;
while (true)
{
tree name, str;
parser->lex_untranslated_string = true;
return NULL_TREE;
}
+ loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser);
if (convert_p)
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (loc, expr);
expr.value = c_fully_fold (expr.value, false, NULL);
parser->lex_untranslated_string = true;
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
{
struct c_expr lhs, rhs, ret;
enum tree_code code;
- location_t op_location;
+ location_t op_location, exp_location;
gcc_assert (!after || c_dialect_objc ());
lhs = c_parser_conditional_expression (parser, after);
op_location = c_parser_peek_token (parser)->location;
return lhs;
}
c_parser_consume_token (parser);
+ exp_location = c_parser_peek_token (parser)->location;
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 = default_function_array_conversion (exp_location, rhs);
+ ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
+ code, exp_location, rhs.value,
+ rhs.original_type);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
TREE_NO_WARNING (ret.value) = 1;
ret.original_code = ERROR_MARK;
}
+ ret.original_type = NULL;
return ret;
}
c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
{
struct c_expr cond, exp1, exp2, ret;
- location_t cond_loc;
+ location_t cond_loc, colon_loc;
gcc_assert (!after || c_dialect_objc ());
- 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;
- cond = default_function_array_conversion (cond);
+ cond_loc = c_parser_peek_token (parser)->location;
+ cond = default_function_array_conversion (cond_loc, cond);
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_COLON))
{
exp1.value = c_save_expr (default_conversion (cond.value));
if (eptype)
exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
+ exp1.original_type = NULL;
cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
- skip_evaluation += cond.value == truthvalue_true_node;
+ c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
}
else
{
cond.value
= c_objc_common_truthvalue_conversion
(cond_loc, default_conversion (cond.value));
- skip_evaluation += cond.value == truthvalue_false_node;
+ c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
exp1 = c_parser_expression_conv (parser);
- skip_evaluation += ((cond.value == truthvalue_true_node)
- - (cond.value == truthvalue_false_node));
+ c_inhibit_evaluation_warnings +=
+ ((cond.value == truthvalue_true_node)
+ - (cond.value == truthvalue_false_node));
}
+
+ colon_loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
{
- skip_evaluation -= cond.value == truthvalue_true_node;
+ c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
- exp2 = c_parser_conditional_expression (parser, NULL);
- exp2 = default_function_array_conversion (exp2);
- skip_evaluation -= cond.value == truthvalue_true_node;
- ret.value = build_conditional_expr (cond.value,
+ {
+ location_t exp2_loc = c_parser_peek_token (parser)->location;
+ exp2 = c_parser_conditional_expression (parser, NULL);
+ exp2 = default_function_array_conversion (exp2_loc, exp2);
+ }
+ c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
+ ret.value = build_conditional_expr (colon_loc, cond.value,
cond.original_code == C_MAYBE_CONST_EXPR,
- exp1.value, exp2.value);
+ exp1.value, exp1.original_type,
+ exp2.value, exp2.original_type);
ret.original_code = ERROR_MARK;
+ if (exp1.value == error_mark_node || exp2.value == error_mark_node)
+ ret.original_type = NULL;
+ else
+ {
+ tree t1, t2;
+
+ /* If both sides are enum type, the default conversion will have
+ made the type of the result be an integer type. We want to
+ remember the enum types we started with. */
+ t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
+ t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
+ ret.original_type = ((t1 != error_mark_node
+ && t2 != error_mark_node
+ && (TYPE_MAIN_VARIANT (t1)
+ == TYPE_MAIN_VARIANT (t2)))
+ ? t1
+ : NULL);
+ }
return ret;
}
the stack has lower precedence than the new operator or there is
only one element on the stack; then the top expression is the LHS
of the new operator. In the case of logical AND and OR
- expressions, we also need to adjust skip_evaluation as
- appropriate when the operators are pushed and popped. */
+ expressions, we also need to adjust c_inhibit_evaluation_warnings
+ as appropriate when the operators are pushed and popped. */
/* The precedence levels, where 0 is a dummy lowest level used for
the bottom of the stack. */
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. */
switch (stack[sp].op) \
{ \
case TRUTH_ANDIF_EXPR: \
- skip_evaluation -= stack[sp - 1].expr.value == truthvalue_false_node; \
+ c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
+ == truthvalue_false_node); \
break; \
case TRUTH_ORIF_EXPR: \
- skip_evaluation -= stack[sp - 1].expr.value == truthvalue_true_node; \
+ c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \
+ == truthvalue_true_node); \
break; \
default: \
break; \
} \
stack[sp - 1].expr \
- = default_function_array_conversion (stack[sp - 1].expr); \
+ = default_function_array_conversion (stack[sp - 1].loc, \
+ stack[sp - 1].expr); \
stack[sp].expr \
- = default_function_array_conversion (stack[sp].expr); \
- stack[sp - 1].expr = parser_build_binary_op (binary_loc, \
+ = default_function_array_conversion (stack[sp].loc, stack[sp].expr); \
+ 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;
{
case TRUTH_ANDIF_EXPR:
stack[sp].expr
- = default_function_array_conversion (stack[sp].expr);
+ = default_function_array_conversion (stack[sp].loc,
+ stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
- (binary_loc, default_conversion (stack[sp].expr.value));
- skip_evaluation += stack[sp].expr.value == truthvalue_false_node;
+ (stack[sp].loc, default_conversion (stack[sp].expr.value));
+ c_inhibit_evaluation_warnings += (stack[sp].expr.value
+ == truthvalue_false_node);
break;
case TRUTH_ORIF_EXPR:
stack[sp].expr
- = default_function_array_conversion (stack[sp].expr);
+ = default_function_array_conversion (stack[sp].loc,
+ stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
- (binary_loc, default_conversion (stack[sp].expr.value));
- skip_evaluation += stack[sp].expr.value == truthvalue_true_node;
+ (stack[sp].loc, default_conversion (stack[sp].expr.value));
+ c_inhibit_evaluation_warnings += (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;
+ stack[sp].loc = binary_loc;
}
out:
while (sp > 0)
static struct c_expr
c_parser_cast_expression (c_parser *parser, struct c_expr *after)
{
+ location_t cast_loc = c_parser_peek_token (parser)->location;
gcc_assert (!after || c_dialect_objc ());
if (after)
- return c_parser_postfix_expression_after_primary (parser, *after);
+ return c_parser_postfix_expression_after_primary (parser,
+ cast_loc, *after);
/* If the expression begins with a parenthesized type name, it may
be either a cast or a compound literal; we need to see whether
the next character is '{' to tell the difference. If not, it is
{
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
used_types_insert (type_name->specs->type);
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
- return c_parser_postfix_expression_after_paren_type (parser,
- type_name);
- expr = c_parser_cast_expression (parser, NULL);
- expr = default_function_array_conversion (expr);
- ret.value = c_cast_expr (type_name, expr.value);
+ return c_parser_postfix_expression_after_paren_type (parser, type_name,
+ cast_loc);
+ {
+ location_t expr_loc = c_parser_peek_token (parser)->location;
+ expr = c_parser_cast_expression (parser, NULL);
+ expr = default_function_array_conversion (expr_loc, expr);
+ }
+ ret.value = c_cast_expr (cast_loc, type_name, expr.value);
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
else
{
int ext;
struct c_expr ret, op;
- location_t loc = c_parser_peek_token (parser)->location;
+ location_t op_loc = c_parser_peek_token (parser)->location;
+ location_t exp_loc;
+ ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
switch (c_parser_peek_token (parser)->type)
{
case CPP_PLUS_PLUS:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (PREINCREMENT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
case CPP_MINUS_MINUS:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (PREDECREMENT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
case CPP_AND:
c_parser_consume_token (parser);
- return parser_build_unary_op (ADDR_EXPR,
- c_parser_cast_expression (parser, NULL),
- loc);
+ return parser_build_unary_op (op_loc, ADDR_EXPR,
+ c_parser_cast_expression (parser, NULL));
case CPP_MULT:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- ret.value = build_indirect_ref (loc, op.value, "unary *");
- ret.original_code = ERROR_MARK;
+ op = default_function_array_conversion (exp_loc, op);
+ ret.value = build_indirect_ref (op_loc, op.value, "unary *");
return ret;
case CPP_PLUS:
if (!c_dialect_objc () && !in_system_header)
- warning_at (c_parser_peek_token (parser)->location,
+ warning_at (op_loc,
OPT_Wtraditional,
"traditional C rejects the unary plus operator");
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (CONVERT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
case CPP_MINUS:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (NEGATE_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
case CPP_COMPL:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (BIT_NOT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
case CPP_NOT:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (TRUTH_NOT_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
case CPP_AND_AND:
/* Refer to the address of a label as a pointer. */
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_NAME))
{
ret.value = finish_label_address_expr
- (c_parser_peek_token (parser)->value, loc);
+ (c_parser_peek_token (parser)->value, op_loc);
c_parser_consume_token (parser);
}
else
c_parser_error (parser, "expected identifier");
ret.value = error_mark_node;
}
- ret.original_code = ERROR_MARK;
return ret;
case CPP_KEYWORD:
switch (c_parser_peek_token (parser)->keyword)
return ret;
case RID_REALPART:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (REALPART_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, REALPART_EXPR, op);
case RID_IMAGPART:
c_parser_consume_token (parser);
+ exp_loc = c_parser_peek_token (parser)->location;
op = c_parser_cast_expression (parser, NULL);
- op = default_function_array_conversion (op);
- return parser_build_unary_op (IMAGPART_EXPR, op, loc);
+ op = default_function_array_conversion (exp_loc, op);
+ return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
default:
return c_parser_postfix_expression (parser);
}
location_t expr_loc;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF));
c_parser_consume_token (parser);
- skip_evaluation++;
+ c_inhibit_evaluation_warnings++;
in_sizeof++;
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
&& c_token_starts_typename (c_parser_peek_2nd_token (parser)))
if (type_name == NULL)
{
struct c_expr ret;
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_sizeof--;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
{
expr = c_parser_postfix_expression_after_paren_type (parser,
- type_name);
+ type_name,
+ expr_loc);
goto sizeof_expr;
}
/* sizeof ( type-name ). */
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_sizeof--;
- return c_expr_sizeof_type (type_name);
+ return c_expr_sizeof_type (expr_loc, type_name);
}
else
{
expr_loc = c_parser_peek_token (parser)->location;
expr = c_parser_unary_expression (parser);
sizeof_expr:
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_sizeof--;
if (TREE_CODE (expr.value) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
error_at (expr_loc, "%<sizeof%> applied to a bit-field");
- return c_expr_sizeof_expr (expr);
+ return c_expr_sizeof_expr (expr_loc, expr);
}
}
c_parser_alignof_expression (c_parser *parser)
{
struct c_expr expr;
+ location_t loc = c_parser_peek_token (parser)->location;
gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
c_parser_consume_token (parser);
- skip_evaluation++;
+ c_inhibit_evaluation_warnings++;
in_alignof++;
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
&& c_token_starts_typename (c_parser_peek_2nd_token (parser)))
{
/* Either __alignof__ ( type-name ) or __alignof__
unary-expression starting with a compound literal. */
+ location_t loc;
struct c_type_name *type_name;
struct c_expr ret;
c_parser_consume_token (parser);
+ loc = c_parser_peek_token (parser)->location;
type_name = c_parser_type_name (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
if (type_name == NULL)
{
struct c_expr ret;
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_alignof--;
ret.value = error_mark_node;
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
{
expr = c_parser_postfix_expression_after_paren_type (parser,
- type_name);
+ type_name,
+ loc);
goto alignof_expr;
}
/* alignof ( type-name ). */
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_alignof--;
- ret.value = c_alignof (groktypename (type_name, NULL, NULL));
+ ret.value = c_alignof (loc, groktypename (type_name, NULL, NULL));
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
else
struct c_expr ret;
expr = c_parser_unary_expression (parser);
alignof_expr:
- skip_evaluation--;
+ c_inhibit_evaluation_warnings--;
in_alignof--;
- ret.value = c_alignof_expr (expr.value);
+ ret.value = c_alignof_expr (loc, expr.value);
ret.original_code = ERROR_MARK;
+ ret.original_type = NULL;
return ret;
}
}
{
struct c_expr expr, e1, e2, e3;
struct c_type_name *t1, *t2;
- location_t loc;
+ location_t loc = c_parser_peek_token (parser)->location;;
+ expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
switch (c_parser_peek_token (parser)->type)
{
case CPP_NUMBER:
expr.value = c_parser_peek_token (parser)->value;
- expr.original_code = ERROR_MARK;
loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
if (TREE_CODE (expr.value) == FIXED_CST
case CPP_CHAR32:
case CPP_WCHAR:
expr.value = c_parser_peek_token (parser)->value;
- expr.original_code = ERROR_MARK;
c_parser_consume_token (parser);
break;
case CPP_STRING:
gcc_assert (c_dialect_objc ());
expr.value
= objc_build_string_object (c_parser_peek_token (parser)->value);
- expr.original_code = ERROR_MARK;
c_parser_consume_token (parser);
break;
case CPP_NAME:
{
c_parser_error (parser, "expected expression");
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
{
tree id = c_parser_peek_token (parser)->value;
- location_t loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
- expr.value = build_external_ref (id,
+ expr.value = build_external_ref (loc, id,
(c_parser_peek_token (parser)->type
- == CPP_OPEN_PAREN), loc);
- expr.original_code = ERROR_MARK;
+ == CPP_OPEN_PAREN),
+ &expr.original_type);
}
break;
case CPP_OPEN_PAREN:
{
/* A statement expression. */
tree stmt;
- location_t here = c_parser_peek_token (parser)->location;
+ location_t brace_loc;
c_parser_consume_token (parser);
+ brace_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
if (cur_stmt_list == NULL)
{
- error_at (here, "braced-group within expression allowed "
+ error_at (loc, "braced-group within expression allowed "
"only inside a function");
parser->error = true;
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
stmt = c_begin_stmt_expr ();
c_parser_compound_statement_nostart (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- pedwarn (here, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids braced-groups within expressions");
- expr.value = c_finish_stmt_expr (stmt);
- expr.original_code = ERROR_MARK;
+ expr.value = c_finish_stmt_expr (brace_loc, stmt);
}
else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
{
than going directly to
c_parser_postfix_expression_after_paren_type from
elsewhere? */
+ location_t loc;
struct c_type_name *type_name;
c_parser_consume_token (parser);
+ loc = c_parser_peek_token (parser)->location;
type_name = c_parser_type_name (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
if (type_name == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
}
else
expr = c_parser_postfix_expression_after_paren_type (parser,
- type_name);
+ type_name,
+ loc);
}
else
{
TREE_NO_WARNING (expr.value) = 1;
if (expr.original_code != C_MAYBE_CONST_EXPR)
expr.original_code = ERROR_MARK;
+ /* Don't change EXPR.ORIGINAL_TYPE. */
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
}
case RID_FUNCTION_NAME:
case RID_PRETTY_FUNCTION_NAME:
case RID_C99_FUNCTION_NAME:
- expr.value = fname_decl (c_parser_peek_token (parser)->location,
+ expr.value = fname_decl (loc,
c_parser_peek_token (parser)->keyword,
c_parser_peek_token (parser)->value);
- expr.original_code = ERROR_MARK;
c_parser_consume_token (parser);
break;
case RID_VA_ARG:
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
e1 = c_parser_expr_no_commas (parser, NULL);
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
+ loc = c_parser_peek_token (parser)->location;
t1 = c_parser_type_name (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
if (t1 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
}
else
{
tree type_expr = NULL_TREE;
- expr.value = build_va_arg (e1.value, groktypename (t1,
- &type_expr,
- NULL));
+ expr.value = c_build_va_arg (loc, e1.value,
+ groktypename (t1, &type_expr, NULL));
if (type_expr)
{
expr.value = build2 (C_MAYBE_CONST_EXPR,
expr.value);
C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true;
}
- expr.original_code = ERROR_MARK;
}
break;
case RID_OFFSETOF:
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
{
if (type == error_mark_node)
offsetof_ref = error_mark_node;
else
- offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
+ {
+ offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
+ SET_EXPR_LOCATION (offsetof_ref, loc);
+ }
/* Parse the second argument to __builtin_offsetof. We
must have one identifier, and beyond that we want to
accept sub structure and sub array references. */
if (c_parser_next_token_is (parser, CPP_NAME))
{
offsetof_ref = build_component_ref
- (offsetof_ref, c_parser_peek_token (parser)->value);
+ (loc, offsetof_ref, c_parser_peek_token (parser)->value);
c_parser_consume_token (parser);
while (c_parser_next_token_is (parser, CPP_DOT)
|| c_parser_next_token_is (parser,
if (c_parser_next_token_is (parser, CPP_DEREF))
{
loc = c_parser_peek_token (parser)->location;
- offsetof_ref = build_array_ref (offsetof_ref,
- integer_zero_node,
- loc);
+ offsetof_ref = build_array_ref (loc,
+ offsetof_ref,
+ integer_zero_node);
goto do_dot;
}
else if (c_parser_next_token_is (parser, CPP_DOT))
break;
}
offsetof_ref = build_component_ref
- (offsetof_ref,
+ (loc, offsetof_ref,
c_parser_peek_token (parser)->value);
c_parser_consume_token (parser);
}
idx = c_fully_fold (idx, false, NULL);
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
"expected %<]%>");
- offsetof_ref = build_array_ref (offsetof_ref, idx, loc);
+ offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
}
}
}
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
expr.value = fold_offsetof (offsetof_ref, NULL_TREE);
- expr.original_code = ERROR_MARK;
}
break;
case RID_CHOOSE_EXPR:
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
loc = c_parser_peek_token (parser)->location;
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
e2 = c_parser_expr_no_commas (parser, NULL);
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
e3 = c_parser_expr_no_commas (parser, NULL);
{
tree c;
- c = fold (e1.value);
+ c = e1.value;
if (TREE_CODE (c) != INTEGER_CST
|| !INTEGRAL_TYPE_P (TREE_TYPE (c)))
error_at (loc,
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t2 = c_parser_type_name (parser);
if (t2 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
expr.value = comptypes (e1, e2)
? build_int_cst (NULL_TREE, 1)
: build_int_cst (NULL_TREE, 0);
- expr.original_code = ERROR_MARK;
}
break;
case RID_AT_SELECTOR:
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
{
tree sel = c_parser_objc_selector_arg (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- expr.value = objc_build_selector_expr (sel);
- expr.original_code = ERROR_MARK;
+ expr.value = objc_build_selector_expr (loc, sel);
}
break;
case RID_AT_PROTOCOL:
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
if (c_parser_next_token_is_not (parser, CPP_NAME))
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
expr.value = objc_build_protocol_expr (id);
- expr.original_code = ERROR_MARK;
}
break;
case RID_AT_ENCODE:
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
break;
}
{
tree type = groktypename (t1, NULL, NULL);
expr.value = objc_build_encode_expr (type);
- expr.original_code = ERROR_MARK;
}
break;
default:
c_parser_error (parser, "expected expression");
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
break;
"expected %<]%>");
expr.value = objc_build_message_expr (build_tree_list (receiver,
args));
- expr.original_code = ERROR_MARK;
break;
}
/* Else fall through to report error. */
default:
c_parser_error (parser, "expected expression");
expr.value = error_mark_node;
- expr.original_code = ERROR_MARK;
break;
}
- return c_parser_postfix_expression_after_primary (parser, expr);
+ return c_parser_postfix_expression_after_primary (parser, loc, expr);
}
/* Parse a postfix expression after a parenthesized type name: the
possible to tell until after the type name whether a cast
expression has a cast or a compound literal, or whether the operand
of sizeof is a parenthesized type name or starts with a compound
- literal. */
+ literal. TYPE_LOC is the location where TYPE_NAME starts--the
+ location of the first token after the parentheses around the type
+ name. */
static struct c_expr
c_parser_postfix_expression_after_paren_type (c_parser *parser,
- struct c_type_name *type_name)
+ struct c_type_name *type_name,
+ location_t type_loc)
{
tree type;
struct c_expr init;
location_t start_loc;
tree type_expr = NULL_TREE;
bool type_expr_const = true;
+ check_compound_literal_type (type_loc, type_name);
start_init (NULL_TREE, NULL, 0);
type = groktypename (type_name, &type_expr, &type_expr_const);
start_loc = c_parser_peek_token (parser)->location;
if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
{
- error_at (start_loc, "compound literal has variable size");
+ error_at (type_loc, "compound literal has variable size");
type = error_mark_node;
}
init = c_parser_braced_init (parser, type, false);
? CONSTRUCTOR_NON_CONST (init.value)
: init.original_code == C_MAYBE_CONST_EXPR);
non_const |= !type_expr_const;
- expr.value = build_compound_literal (type, init.value, non_const);
+ expr.value = build_compound_literal (start_loc, type, init.value, non_const);
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
if (type_expr)
{
if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
type_expr, expr.value);
}
}
- return c_parser_postfix_expression_after_primary (parser, expr);
+ return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
}
/* Parse a postfix expression after the initial primary or compound
- literal; that is, parse a series of postfix operators. */
+ literal; that is, parse a series of postfix operators.
+
+ EXPR_LOC is the location of the primary expression. */
static struct c_expr
c_parser_postfix_expression_after_primary (c_parser *parser,
+ location_t expr_loc,
struct c_expr expr)
{
struct c_expr orig_expr;
- tree ident, idx, exprlist;
- location_t loc = c_parser_peek_token (parser)->location;
+ tree ident, idx;
+ VEC(tree,gc) *exprlist;
+ VEC(tree,gc) *origtypes;
while (true)
{
+ location_t op_loc = c_parser_peek_token (parser)->location;
switch (c_parser_peek_token (parser)->type)
{
case CPP_OPEN_SQUARE:
/* Array reference. */
- loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
idx = c_parser_expression (parser).value;
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
"expected %<]%>");
- expr.value = build_array_ref (expr.value, idx, loc);
+ expr.value = build_array_ref (op_loc, expr.value, idx);
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
break;
case CPP_OPEN_PAREN:
/* Function call. */
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- exprlist = NULL_TREE;
+ exprlist = NULL;
else
- exprlist = c_parser_expr_list (parser, true, false);
+ exprlist = c_parser_expr_list (parser, true, false, &origtypes);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
orig_expr = expr;
- expr.value = build_function_call (expr.value, exprlist);
+ /* FIXME diagnostics: Ideally we want the FUNCNAME, not the
+ "(" after the FUNCNAME, which is what we have now. */
+ expr.value = build_function_call_vec (op_loc, expr.value, exprlist,
+ origtypes);
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) == INTEGER_CST
&& TREE_CODE (orig_expr.value) == FUNCTION_DECL
&& DECL_BUILT_IN_CLASS (orig_expr.value) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (orig_expr.value) == BUILT_IN_CONSTANT_P)
expr.original_code = C_MAYBE_CONST_EXPR;
+ expr.original_type = NULL;
+ if (exprlist != NULL)
+ {
+ release_tree_vector (exprlist);
+ release_tree_vector (origtypes);
+ }
break;
case CPP_DOT:
/* Structure element reference. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (expr_loc, expr);
if (c_parser_next_token_is (parser, CPP_NAME))
ident = c_parser_peek_token (parser)->value;
else
c_parser_error (parser, "expected identifier");
expr.value = error_mark_node;
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
return expr;
}
c_parser_consume_token (parser);
- expr.value = build_component_ref (expr.value, ident);
+ expr.value = build_component_ref (op_loc, expr.value, ident);
expr.original_code = ERROR_MARK;
+ if (TREE_CODE (expr.value) != COMPONENT_REF)
+ expr.original_type = NULL;
+ else
+ {
+ /* Remember the original type of a bitfield. */
+ tree field = TREE_OPERAND (expr.value, 1);
+ if (TREE_CODE (field) != FIELD_DECL)
+ expr.original_type = NULL;
+ else
+ expr.original_type = DECL_BIT_FIELD_TYPE (field);
+ }
break;
case CPP_DEREF:
/* Structure element reference. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (expr_loc, expr);
if (c_parser_next_token_is (parser, CPP_NAME))
ident = c_parser_peek_token (parser)->value;
else
c_parser_error (parser, "expected identifier");
expr.value = error_mark_node;
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
return expr;
}
c_parser_consume_token (parser);
- expr.value = build_component_ref (build_indirect_ref (loc,
+ expr.value = build_component_ref (op_loc,
+ build_indirect_ref (op_loc,
expr.value,
"->"),
ident);
expr.original_code = ERROR_MARK;
+ if (TREE_CODE (expr.value) != COMPONENT_REF)
+ expr.original_type = NULL;
+ else
+ {
+ /* Remember the original type of a bitfield. */
+ tree field = TREE_OPERAND (expr.value, 1);
+ if (TREE_CODE (field) != FIELD_DECL)
+ expr.original_type = NULL;
+ else
+ expr.original_type = DECL_BIT_FIELD_TYPE (field);
+ }
break;
case CPP_PLUS_PLUS:
/* Postincrement. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr);
- expr.value = build_unary_op (loc,
+ expr = default_function_array_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
POSTINCREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
break;
case CPP_MINUS_MINUS:
/* Postdecrement. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr);
- expr.value = build_unary_op (loc,
+ expr = default_function_array_conversion (expr_loc, expr);
+ expr.value = build_unary_op (op_loc,
POSTDECREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
+ expr.original_type = NULL;
break;
default:
return expr;
while (c_parser_next_token_is (parser, CPP_COMMA))
{
struct c_expr next;
+ location_t loc = c_parser_peek_token (parser)->location;
+ location_t expr_loc;
c_parser_consume_token (parser);
+ expr_loc = c_parser_peek_token (parser)->location;
next = c_parser_expr_no_commas (parser, NULL);
- next = default_function_array_conversion (next);
- expr.value = build_compound_expr (expr.value, next.value);
+ next = default_function_array_conversion (expr_loc, next);
+ expr.value = build_compound_expr (loc, expr.value, next.value);
expr.original_code = COMPOUND_EXPR;
+ expr.original_type = next.original_type;
}
return expr;
}
c_parser_expression_conv (c_parser *parser)
{
struct c_expr expr;
+ location_t loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser);
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (loc, expr);
return expr;
}
nonempty-expr-list , assignment-expression
*/
-static tree
-c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p)
+static VEC(tree,gc) *
+c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
+ VEC(tree,gc) **p_orig_types)
{
+ VEC(tree,gc) *ret;
+ VEC(tree,gc) *orig_types;
struct c_expr expr;
- tree ret, cur;
+ location_t loc = c_parser_peek_token (parser)->location;
+
+ ret = make_tree_vector ();
+ if (p_orig_types == NULL)
+ orig_types = NULL;
+ else
+ orig_types = make_tree_vector ();
+
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (loc, expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
- ret = cur = build_tree_list (NULL_TREE, expr.value);
+ VEC_quick_push (tree, ret, expr.value);
+ if (orig_types != NULL)
+ VEC_quick_push (tree, orig_types, expr.original_type);
while (c_parser_next_token_is (parser, CPP_COMMA))
{
c_parser_consume_token (parser);
+ loc = c_parser_peek_token (parser)->location;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
- expr = default_function_array_conversion (expr);
+ expr = default_function_array_conversion (loc, expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
- cur = TREE_CHAIN (cur) = build_tree_list (NULL_TREE, expr.value);
+ VEC_safe_push (tree, gc, ret, expr.value);
+ if (orig_types != NULL)
+ VEC_safe_push (tree, gc, orig_types, expr.original_type);
}
+ if (orig_types != NULL)
+ *p_orig_types = orig_types;
return ret;
}
-
\f
/* Parse Objective-C-specific constructs. */
{
tree keywordexpr;
if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
- return list;
+ return error_mark_node;
keywordexpr = c_parser_objc_keywordexpr (parser);
list = chainon (list, build_tree_list (sel, keywordexpr));
sel = c_parser_objc_selector (parser);
static tree
c_parser_objc_keywordexpr (c_parser *parser)
{
- tree list = c_parser_expr_list (parser, true, true);
- if (TREE_CHAIN (list) == NULL_TREE)
+ tree ret;
+ VEC(tree,gc) *expr_list = c_parser_expr_list (parser, true, true, NULL);
+ if (VEC_length (tree, expr_list) == 1)
{
/* Just return the expression, remove a level of
indirection. */
- return TREE_VALUE (list);
+ ret = VEC_index (tree, expr_list, 0);
}
else
{
/* We have a comma expression, we will collapse later. */
- return list;
+ ret = build_tree_list_vec (expr_list);
}
+ release_tree_vector (expr_list);
+ return ret;
}
\f
for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == code)
{
- error ("too many %qs clauses", name);
+ location_t loc = OMP_CLAUSE_LOCATION (c);
+ error_at (loc, "too many %qs clauses", name);
break;
}
}
identifier
variable-list , identifier
- If KIND is nonzero, create the appropriate node and install the decl
- in OMP_CLAUSE_DECL and add the node to the head of the list.
+ If KIND is nonzero, create the appropriate node and install the
+ decl in OMP_CLAUSE_DECL and add the node to the head of the list.
+ If KIND is nonzero, CLAUSE_LOC is the location of the clause.
If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
return the list created. */
static tree
-c_parser_omp_variable_list (c_parser *parser, enum omp_clause_code kind,
+c_parser_omp_variable_list (c_parser *parser,
+ location_t clause_loc,
+ enum omp_clause_code kind,
tree list)
{
if (c_parser_next_token_is_not (parser, CPP_NAME)
tree t = lookup_name (c_parser_peek_token (parser)->value);
if (t == NULL_TREE)
- undeclared_variable (c_parser_peek_token (parser)->value,
- c_parser_peek_token (parser)->location);
+ undeclared_variable (c_parser_peek_token (parser)->location,
+ c_parser_peek_token (parser)->value);
else if (t == error_mark_node)
;
else if (kind != 0)
{
- tree u = build_omp_clause (kind);
+ tree u = build_omp_clause (clause_loc, kind);
OMP_CLAUSE_DECL (u) = t;
OMP_CLAUSE_CHAIN (u) = list;
list = u;
c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
tree list)
{
+ /* The clauses location. */
+ location_t loc = c_parser_peek_token (parser)->location;
+
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- list = c_parser_omp_variable_list (parser, kind, list);
+ list = c_parser_omp_variable_list (parser, loc, kind, list);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
}
return list;
"collapse argument needs positive constant integer expression");
return list;
}
- c = build_omp_clause (OMP_CLAUSE_COLLAPSE);
+ c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
OMP_CLAUSE_CHAIN (c) = list;
return c;
c_parser_omp_clause_default (c_parser *parser, tree list)
{
enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
+ location_t loc = c_parser_peek_token (parser)->location;
tree c;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
return list;
check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
- c = build_omp_clause (OMP_CLAUSE_DEFAULT);
+ c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_DEFAULT_KIND (c) = kind;
static tree
c_parser_omp_clause_if (c_parser *parser, tree list)
{
+ location_t loc = c_parser_peek_token (parser)->location;
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
tree t = c_parser_paren_condition (parser);
check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
- c = build_omp_clause (OMP_CLAUSE_IF);
+ c = build_omp_clause (loc, OMP_CLAUSE_IF);
OMP_CLAUSE_IF_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
list = c;
c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
{
tree c;
+ location_t loc = c_parser_peek_token (parser)->location;
check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
- c = build_omp_clause (OMP_CLAUSE_NOWAIT);
+ c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
static tree
c_parser_omp_clause_num_threads (c_parser *parser, tree list)
{
+ location_t num_threads_loc = c_parser_peek_token (parser)->location;
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
location_t expr_loc = c_parser_peek_token (parser)->location;
/* Attempt to statically determine when the number isn't positive. */
c = fold_build2 (LE_EXPR, boolean_type_node, t,
build_int_cst (TREE_TYPE (t), 0));
+ if (CAN_HAVE_LOCATION_P (c))
+ SET_EXPR_LOCATION (c, expr_loc);
if (c == boolean_true_node)
{
warning_at (expr_loc, 0,
check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
- c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
+ c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
list = c;
ordered */
static tree
-c_parser_omp_clause_ordered (c_parser *parser ATTRIBUTE_UNUSED, tree list)
+c_parser_omp_clause_ordered (c_parser *parser, tree list)
{
tree c;
check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
- c = build_omp_clause (OMP_CLAUSE_ORDERED);
+ c = build_omp_clause (c_parser_peek_token (parser)->location,
+ OMP_CLAUSE_ORDERED);
OMP_CLAUSE_CHAIN (c) = list;
+
return c;
}
static tree
c_parser_omp_clause_reduction (c_parser *parser, tree list)
{
+ location_t clause_loc = c_parser_peek_token (parser)->location;
if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
enum tree_code code;
{
tree nl, c;
- nl = c_parser_omp_variable_list (parser, OMP_CLAUSE_REDUCTION, list);
+ nl = c_parser_omp_variable_list (parser, clause_loc,
+ OMP_CLAUSE_REDUCTION, list);
for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
OMP_CLAUSE_REDUCTION_CODE (c) = code;
c_parser_omp_clause_schedule (c_parser *parser, tree list)
{
tree c, t;
+ location_t loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
return list;
- c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
+ c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
if (c_parser_next_token_is (parser, CPP_NAME))
{
/* FIXME: Should we allow duplicates? */
check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
- c = build_omp_clause (OMP_CLAUSE_UNTIED);
+ c = build_omp_clause (c_parser_peek_token (parser)->location,
+ OMP_CLAUSE_UNTIED);
OMP_CLAUSE_CHAIN (c) = list;
+
return c;
}
binop:
+, *, -, /, &, ^, |, <<, >>
- where x is an lvalue expression with scalar type. */
+ where x is an lvalue expression with scalar type.
+
+ LOC is the location of the #pragma token. */
static void
-c_parser_omp_atomic (c_parser *parser)
+c_parser_omp_atomic (location_t loc, c_parser *parser)
{
tree lhs, rhs;
tree stmt;
}
c_parser_consume_token (parser);
- rhs_expr = c_parser_expression (parser);
- rhs_expr = default_function_array_conversion (rhs_expr);
+ {
+ location_t rhs_loc = c_parser_peek_token (parser)->location;
+ rhs_expr = c_parser_expression (parser);
+ rhs_expr = default_function_array_conversion (rhs_loc, rhs_expr);
+ }
rhs = rhs_expr.value;
rhs = c_fully_fold (rhs, false, NULL);
break;
}
- stmt = c_finish_omp_atomic (code, lhs, rhs);
+ stmt = c_finish_omp_atomic (loc, code, lhs, rhs);
if (stmt != error_mark_node)
add_stmt (stmt);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
static void
c_parser_omp_barrier (c_parser *parser)
{
+ location_t loc = c_parser_peek_token (parser)->location;
c_parser_consume_pragma (parser);
c_parser_skip_to_pragma_eol (parser);
- c_finish_omp_barrier ();
+ c_finish_omp_barrier (loc);
}
/* OpenMP 2.5:
# pragma omp critical [(name)] new-line
structured-block
-*/
+
+ LOC is the location of the #pragma itself. */
static tree
-c_parser_omp_critical (c_parser *parser)
+c_parser_omp_critical (location_t loc, c_parser *parser)
{
tree stmt, name = NULL;
c_parser_skip_to_pragma_eol (parser);
stmt = c_parser_omp_structured_block (parser);
- return c_finish_omp_critical (stmt, name);
+ return c_finish_omp_critical (loc, stmt, name);
}
/* OpenMP 2.5:
static void
c_parser_omp_flush (c_parser *parser)
{
+ location_t loc = c_parser_peek_token (parser)->location;
c_parser_consume_pragma (parser);
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
c_parser_error (parser, "expected %<(%> or end of line");
c_parser_skip_to_pragma_eol (parser);
- c_finish_omp_flush ();
+ c_finish_omp_flush (loc);
}
/* Parse the restricted form of the for statement allowed by OpenMP.
The real trick here is to determine the loop control variable early
- so that we can push a new decl if necessary to make it private. */
+ so that we can push a new decl if necessary to make it private.
+ LOC is the location of the OMP in "#pragma omp". */
static tree
-c_parser_omp_for_loop (c_parser *parser, tree clauses, tree *par_clauses)
+c_parser_omp_for_loop (location_t loc,
+ c_parser *parser, tree clauses, tree *par_clauses)
{
tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl;
tree declv, condv, incrv, initv, for_block = NULL, ret = NULL;
- location_t loc;
bool fail = false, open_brace_parsed = false;
int i, collapse = 1, nbraces = 0;
+ location_t for_loc;
for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
c_parser_error (parser, "for statement expected");
return NULL;
}
- loc = c_parser_peek_token (parser)->location;
+ for_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
for (i = 0; i < collapse; i++)
for_block
= tree_cons (NULL, c_begin_compound_stmt (true), for_block);
c_parser_declaration_or_fndef (parser, true, true, true, true);
- decl = check_for_loop_decls ();
+ decl = check_for_loop_decls (for_loc);
if (decl == NULL)
goto error_init;
if (DECL_INITIAL (decl) == error_mark_node)
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_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 = c_process_expr_stmt (init);
+ init_exp = default_function_array_conversion (init_loc, init_exp);
+ init = build_modify_expr (init_loc, decl, decl_exp.original_type,
+ NOP_EXPR, init_loc, init_exp.value,
+ init_exp.original_type);
+ init = c_process_expr_stmt (init_loc, init);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
{
location_t incr_loc = c_parser_peek_token (parser)->location;
- incr = c_process_expr_stmt (c_parser_expression (parser).value);
- protected_set_expr_location (incr, incr_loc);
+ incr = c_process_expr_stmt (incr_loc,
+ c_parser_expression (parser).value);
}
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
if (open_brace_parsed)
{
+ location_t here = c_parser_peek_token (parser)->location;
stmt = c_begin_compound_stmt (true);
c_parser_compound_statement_nostart (parser);
- add_stmt (c_end_compound_stmt (stmt, true));
+ add_stmt (c_end_compound_stmt (here, stmt, true));
}
else
add_stmt (c_parser_c99_block_statement (parser));
if (c_cont_label)
- add_stmt (build1 (LABEL_EXPR, void_type_node, c_cont_label));
+ {
+ tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label);
+ SET_EXPR_LOCATION (t, loc);
+ add_stmt (t);
+ }
body = pop_stmt_list (body);
c_break_label = save_break;
c_parser_error (parser, "collapsed loops not perfectly nested");
while (nbraces)
{
+ location_t here = c_parser_peek_token (parser)->location;
stmt = c_begin_compound_stmt (true);
add_stmt (body);
c_parser_compound_statement_nostart (parser);
- body = c_end_compound_stmt (stmt, true);
+ body = c_end_compound_stmt (here, stmt, true);
nbraces--;
}
goto pop_scopes;
/* Copy lastprivate (decl) clause to OMP_FOR_CLAUSES,
change it to shared (decl) in
OMP_PARALLEL_CLAUSES. */
- tree l = build_omp_clause (OMP_CLAUSE_LASTPRIVATE);
+ tree l = build_omp_clause (OMP_CLAUSE_LOCATION (*c),
+ OMP_CLAUSE_LASTPRIVATE);
OMP_CLAUSE_DECL (l) = OMP_CLAUSE_DECL (*c);
OMP_CLAUSE_CHAIN (l) = clauses;
clauses = l;
pop_scopes:
while (for_block)
{
- stmt = c_end_compound_stmt (TREE_VALUE (for_block), true);
+ /* FIXME diagnostics: LOC below should be the actual location of
+ this particular for block. We need to build a list of
+ locations to go along with FOR_BLOCK. */
+ stmt = c_end_compound_stmt (loc, TREE_VALUE (for_block), true);
add_stmt (stmt);
for_block = TREE_CHAIN (for_block);
}
/* OpenMP 2.5:
#pragma omp for for-clause[optseq] new-line
for-loop
+
+ LOC is the location of the #pragma token.
*/
#define OMP_FOR_CLAUSE_MASK \
| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
static tree
-c_parser_omp_for (c_parser *parser)
+c_parser_omp_for (location_t loc, c_parser *parser)
{
tree block, clauses, ret;
"#pragma omp for");
block = c_begin_compound_stmt (true);
- ret = c_parser_omp_for_loop (parser, clauses, NULL);
- block = c_end_compound_stmt (block, true);
+ ret = c_parser_omp_for_loop (loc, parser, clauses, NULL);
+ block = c_end_compound_stmt (loc, block, true);
add_stmt (block);
return ret;
/* OpenMP 2.5:
# pragma omp master new-line
structured-block
+
+ LOC is the location of the #pragma token.
*/
static tree
-c_parser_omp_master (c_parser *parser)
+c_parser_omp_master (location_t loc, c_parser *parser)
{
c_parser_skip_to_pragma_eol (parser);
- return c_finish_omp_master (c_parser_omp_structured_block (parser));
+ return c_finish_omp_master (loc, c_parser_omp_structured_block (parser));
}
/* OpenMP 2.5:
# pragma omp ordered new-line
structured-block
+
+ LOC is the location of the #pragma itself.
*/
static tree
-c_parser_omp_ordered (c_parser *parser)
+c_parser_omp_ordered (location_t loc, c_parser *parser)
{
c_parser_skip_to_pragma_eol (parser);
- return c_finish_omp_ordered (c_parser_omp_structured_block (parser));
+ return c_finish_omp_ordered (loc, c_parser_omp_structured_block (parser));
}
/* OpenMP 2.5:
section-sequence:
section-directive[opt] structured-block
- section-sequence section-directive structured-block */
+ section-sequence section-directive structured-block
+
+ SECTIONS_LOC is the location of the #pragma omp sections. */
static tree
-c_parser_omp_sections_scope (c_parser *parser)
+c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
{
tree stmt, substmt;
bool error_suppress = false;
location_t loc;
+ loc = c_parser_peek_token (parser)->location;
if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
{
/* Avoid skipping until the end of the block. */
stmt = push_stmt_list ();
- loc = c_parser_peek_token (parser)->location;
if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION)
{
substmt = push_stmt_list ();
substmt = pop_stmt_list (stmt);
stmt = make_node (OMP_SECTIONS);
+ SET_EXPR_LOCATION (stmt, sections_loc);
TREE_TYPE (stmt) = void_type_node;
OMP_SECTIONS_BODY (stmt) = substmt;
/* OpenMP 2.5:
# pragma omp sections sections-clause[optseq] newline
sections-scope
+
+ LOC is the location of the #pragma token.
*/
#define OMP_SECTIONS_CLAUSE_MASK \
| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
static tree
-c_parser_omp_sections (c_parser *parser)
+c_parser_omp_sections (location_t loc, c_parser *parser)
{
tree block, clauses, ret;
"#pragma omp sections");
block = c_begin_compound_stmt (true);
- ret = c_parser_omp_sections_scope (parser);
+ ret = c_parser_omp_sections_scope (loc, parser);
if (ret)
OMP_SECTIONS_CLAUSES (ret) = clauses;
- block = c_end_compound_stmt (block, true);
+ block = c_end_compound_stmt (loc, block, true);
add_stmt (block);
return ret;
# pragma parallel parallel-clause new-line
# pragma parallel for parallel-for-clause new-line
# pragma parallel sections parallel-sections-clause new-line
+
+ LOC is the location of the #pragma token.
*/
#define OMP_PARALLEL_CLAUSE_MASK \
| (1u << PRAGMA_OMP_CLAUSE_NUM_THREADS))
static tree
-c_parser_omp_parallel (c_parser *parser)
+c_parser_omp_parallel (location_t loc, c_parser *parser)
{
enum pragma_kind p_kind = PRAGMA_OMP_PARALLEL;
const char *p_name = "#pragma omp parallel";
case PRAGMA_OMP_PARALLEL:
block = c_begin_omp_parallel ();
c_parser_statement (parser);
- stmt = c_finish_omp_parallel (clauses, block);
+ stmt = c_finish_omp_parallel (loc, clauses, block);
break;
case PRAGMA_OMP_PARALLEL_FOR:
block = c_begin_omp_parallel ();
- c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
- c_parser_omp_for_loop (parser, ws_clause, &par_clause);
- stmt = c_finish_omp_parallel (par_clause, block);
+ c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
+ c_parser_omp_for_loop (loc, parser, ws_clause, &par_clause);
+ stmt = c_finish_omp_parallel (loc, par_clause, block);
OMP_PARALLEL_COMBINED (stmt) = 1;
break;
case PRAGMA_OMP_PARALLEL_SECTIONS:
block = c_begin_omp_parallel ();
- c_split_parallel_clauses (clauses, &par_clause, &ws_clause);
- stmt = c_parser_omp_sections_scope (parser);
+ c_split_parallel_clauses (loc, clauses, &par_clause, &ws_clause);
+ stmt = c_parser_omp_sections_scope (loc, parser);
if (stmt)
OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
- stmt = c_finish_omp_parallel (par_clause, block);
+ stmt = c_finish_omp_parallel (loc, par_clause, block);
OMP_PARALLEL_COMBINED (stmt) = 1;
break;
/* OpenMP 2.5:
# pragma omp single single-clause[optseq] new-line
structured-block
+
+ LOC is the location of the #pragma.
*/
#define OMP_SINGLE_CLAUSE_MASK \
| (1u << PRAGMA_OMP_CLAUSE_NOWAIT))
static tree
-c_parser_omp_single (c_parser *parser)
+c_parser_omp_single (location_t loc, c_parser *parser)
{
tree stmt = make_node (OMP_SINGLE);
+ SET_EXPR_LOCATION (stmt, loc);
TREE_TYPE (stmt) = void_type_node;
OMP_SINGLE_CLAUSES (stmt)
/* OpenMP 3.0:
# pragma omp task task-clause[optseq] new-line
+
+ LOC is the location of the #pragma.
*/
#define OMP_TASK_CLAUSE_MASK \
| (1u << PRAGMA_OMP_CLAUSE_SHARED))
static tree
-c_parser_omp_task (c_parser *parser)
+c_parser_omp_task (location_t loc, c_parser *parser)
{
tree clauses, block;
block = c_begin_omp_task ();
c_parser_statement (parser);
- return c_finish_omp_task (clauses, block);
+ return c_finish_omp_task (loc, clauses, block);
}
/* OpenMP 3.0:
static void
c_parser_omp_taskwait (c_parser *parser)
{
+ location_t loc = c_parser_peek_token (parser)->location;
c_parser_consume_pragma (parser);
c_parser_skip_to_pragma_eol (parser);
- c_finish_omp_taskwait ();
+ c_finish_omp_taskwait (loc);
}
/* Main entry point to parsing most OpenMP pragmas. */
switch (p_kind)
{
case PRAGMA_OMP_ATOMIC:
- c_parser_omp_atomic (parser);
+ c_parser_omp_atomic (loc, parser);
return;
case PRAGMA_OMP_CRITICAL:
- stmt = c_parser_omp_critical (parser);
+ stmt = c_parser_omp_critical (loc, parser);
break;
case PRAGMA_OMP_FOR:
- stmt = c_parser_omp_for (parser);
+ stmt = c_parser_omp_for (loc, parser);
break;
case PRAGMA_OMP_MASTER:
- stmt = c_parser_omp_master (parser);
+ stmt = c_parser_omp_master (loc, parser);
break;
case PRAGMA_OMP_ORDERED:
- stmt = c_parser_omp_ordered (parser);
+ stmt = c_parser_omp_ordered (loc, parser);
break;
case PRAGMA_OMP_PARALLEL:
- stmt = c_parser_omp_parallel (parser);
+ stmt = c_parser_omp_parallel (loc, parser);
break;
case PRAGMA_OMP_SECTIONS:
- stmt = c_parser_omp_sections (parser);
+ stmt = c_parser_omp_sections (loc, parser);
break;
case PRAGMA_OMP_SINGLE:
- stmt = c_parser_omp_single (parser);
+ stmt = c_parser_omp_single (loc, parser);
break;
case PRAGMA_OMP_TASK:
- stmt = c_parser_omp_task (parser);
+ stmt = c_parser_omp_task (loc, parser);
break;
default:
gcc_unreachable ();
}
if (stmt)
- SET_EXPR_LOCATION (stmt, loc);
+ gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
}
c_parser_omp_threadprivate (c_parser *parser)
{
tree vars, t;
+ location_t loc;
c_parser_consume_pragma (parser);
+ loc = c_parser_peek_token (parser)->location;
vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
/* Mark every variable in VARS to be assigned thread local storage. */
{
tree v = TREE_PURPOSE (t);
+ /* FIXME diagnostics: Ideally we should keep individual
+ locations for all the variables in the var list to make the
+ following errors more precise. Perhaps
+ c_parser_omp_var_list_parens() should construct a list of
+ locations to go along with the var list. */
+
/* If V had already been marked threadprivate, it doesn't matter
whether it had been used prior to this point. */
if (TREE_CODE (v) != VAR_DECL)
- error ("%qD is not a variable", v);
+ error_at (loc, "%qD is not a variable", v);
else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
- error ("%qE declared %<threadprivate%> after first use", v);
+ error_at (loc, "%qE declared %<threadprivate%> after first use", v);
else if (! TREE_STATIC (v) && ! DECL_EXTERNAL (v))
- error ("automatic variable %qE cannot be %<threadprivate%>", v);
+ error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
else if (TREE_TYPE (v) == error_mark_node)
;
else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
- error ("%<threadprivate%> %qE has incomplete type", v);
+ error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
else
{
if (! DECL_THREAD_LOCAL_P (v))