/* Parser for C and Objective-C.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Parser actions based on the old Bison parser; structure somewhat
tree id;
int mask = 0;
+ /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
+ the c_token structure. */
+ gcc_assert (RID_MAX <= 255);
+
mask |= D_CXXONLY;
if (!flag_isoc99)
mask |= D_C99;
C_ID_TYPENAME,
/* An identifier declared as an Objective-C class name. */
C_ID_CLASSNAME,
+ /* An address space identifier. */
+ C_ID_ADDRSPACE,
/* Not an identifier. */
C_ID_NONE
} c_id_kind;
"identifier %qE conflicts with C++ keyword",
token->value);
}
+ else if (rid_code >= RID_FIRST_ADDR_SPACE
+ && rid_code <= RID_LAST_ADDR_SPACE)
+ {
+ token->id_kind = C_ID_ADDRSPACE;
+ token->keyword = rid_code;
+ break;
+ }
else if (c_dialect_objc ())
{
if (!objc_is_reserved_word (token->value)
{
case C_ID_ID:
return false;
+ case C_ID_ADDRSPACE:
+ return true;
case C_ID_TYPENAME:
return true;
case C_ID_CLASSNAME:
{
case C_ID_ID:
return false;
+ case C_ID_ADDRSPACE:
+ return true;
case C_ID_TYPENAME:
return true;
case C_ID_CLASSNAME:
{
if (c_parser_next_token_is (parser, CPP_EOF))
{
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"ISO C forbids an empty translation unit");
}
else
}
break;
case CPP_SEMICOLON:
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"ISO C does not allow extra %<;%> outside of a function");
c_parser_consume_token (parser);
break;
C we also allow but diagnose declarations without declaration
specifiers, but only at top level (elsewhere they conflict with
other syntax).
-
+
OpenMP:
-
+
declaration:
threadprivate-directive */
const
restrict
volatile
+ address-space-qualifier
(restrict is new in C99.)
declaration-specifiers:
attributes declaration-specifiers[opt]
+ type-qualifier:
+ address-space
+
+ address-space:
+ identifier recognized by the target
+
storage-class-specifier:
__thread
{
tree value = c_parser_peek_token (parser)->value;
c_id_kind kind = c_parser_peek_token (parser)->id_kind;
+
+ if (kind == C_ID_ADDRSPACE)
+ {
+ addr_space_t as
+ = c_parser_peek_token (parser)->keyword - RID_FIRST_ADDR_SPACE;
+ declspecs_add_addrspace (specs, as);
+ c_parser_consume_token (parser);
+ attrs_ok = true;
+ continue;
+ }
+
/* This finishes the specifiers unless a type name is OK, it
is declared as a type name and a type name hasn't yet
been seen. */
/* Parse any stray semicolon. */
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"extra semicolon in struct or union specified");
c_parser_consume_token (parser);
continue;
else
{
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
- pedwarn (c_parser_peek_token (parser)->location, 0,
+ pedwarn (c_parser_peek_token (parser)->location, 0,
"no semicolon at end of struct or union");
else
{
tree ret;
if (!specs->type_seen_p)
{
- pedwarn (decl_loc, OPT_pedantic,
+ pedwarn (decl_loc, OPT_pedantic,
"ISO C forbids member declarations with no members");
shadow_tag_warned (specs, pedantic);
ret = NULL_TREE;
if (TREE_CODE (expr.value) == COMPONENT_REF
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
error_at (here, "%<typeof%> applied to a bit-field");
+ mark_exp_read (expr.value);
ret.spec = TREE_TYPE (expr.value);
was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
/* This is returned with the type so that when the type is
/* 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;
+ 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;
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 (loc, ret);
+ ret = default_function_array_read_conversion (loc, ret);
return ret;
}
}
/* Old-style structure member designator. */
set_init_label (c_parser_peek_token (parser)->value);
/* Use the colon as the error location. */
- pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic,
"obsolete use of designated initializer with %<:%>");
c_parser_consume_token (parser);
c_parser_consume_token (parser);
goto parse_message_args;
}
first = c_parser_expr_no_commas (parser, NULL).value;
+ mark_exp_read (first);
if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
|| c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
goto array_desig_after_first;
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 (exp_loc, next);
+ next = default_function_array_read_conversion (exp_loc,
+ next);
rec = build_compound_expr (comma_loc, rec, next.value);
}
parse_message_args:
}
c_parser_consume_token (parser);
first = c_parser_expr_no_commas (parser, NULL).value;
+ mark_exp_read (first);
array_desig_after_first:
if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
{
ellipsis_loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
second = c_parser_expr_no_commas (parser, NULL).value;
+ mark_exp_read (second);
}
else
second = NULL_TREE;
c_parser_consume_token (parser);
set_init_index (first, second);
if (second)
- pedwarn (ellipsis_loc, OPT_pedantic,
+ pedwarn (ellipsis_loc, OPT_pedantic,
"ISO C forbids specifying range of elements to initialize");
}
else
if (c_parser_next_token_is (parser, CPP_EQ))
{
if (!flag_isoc99)
- pedwarn (des_loc, OPT_pedantic,
+ pedwarn (des_loc, OPT_pedantic,
"ISO C90 forbids specifying subobject to initialize");
c_parser_consume_token (parser);
}
else
{
if (des_seen == 1)
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"obsolete use of designated initializer without %<=%>");
else
{
if (init.value != NULL_TREE
&& TREE_CODE (init.value) != STRING_CST
&& TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
- init = default_function_array_conversion (loc, init);
+ init = default_function_array_read_conversion (loc, init);
}
process_init_element (init, false);
}
old parser in requiring something after label declarations.
Although they are erroneous if the labels declared aren't defined,
is it useful for the syntax to be this way?
-
+
OpenMP:
-
+
block-item:
openmp-directive
mark_valid_location_for_stdc_pragma (false);
c_parser_declaration_or_fndef (parser, true, true, true, true);
if (last_stmt)
- pedwarn_c90 (loc,
+ pedwarn_c90 (loc,
(pedantic && !flag_isoc99)
? OPT_pedantic
: OPT_Wdeclaration_after_statement,
}
else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
{
- if (parser->in_if_block)
+ if (parser->in_if_block)
{
mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
error_at (loc, """expected %<}%> before %<else%>");
return;
}
- else
+ else
{
error_at (loc, "%<else%> without a previous %<if%>");
c_parser_consume_token (parser);
error_at (c_parser_peek_token (parser)->location,
"a label can only be part of a statement and "
"a declaration is not a statement");
- c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
+ c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false,
/*nested*/ true, /*empty_ok*/ false,
/*start_attr_ok*/ true);
}
else
{
struct c_expr expr = c_parser_expression_conv (parser);
+ mark_exp_read (expr.value);
stmt = c_finish_return (loc, expr.value, expr.original_type);
goto expect_semicolon;
}
add_stmt (build_empty_stmt (loc));
c_parser_consume_token (parser);
}
- else
+ else
c_parser_statement_after_labels (parser);
return c_end_compound_stmt (else_loc, block, flag_isoc99);
}
}
loc = c_parser_peek_token (parser)->location;
expr = c_parser_expression (parser);
+ mark_exp_read (expr.value);
if (convert_p)
expr = default_function_array_conversion (loc, expr);
expr.value = c_fully_fold (expr.value, false, NULL);
}
/* Parse asm goto labels, a GNU extension.
-
+
asm-goto-operands:
identifier
asm-goto-operands , identifier
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 (exp_location, rhs);
+ rhs = default_function_array_read_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 (c_parser_next_token_is_not (parser, CPP_QUERY))
return cond;
cond_loc = c_parser_peek_token (parser)->location;
- cond = default_function_array_conversion (cond_loc, cond);
+ cond = default_function_array_read_conversion (cond_loc, cond);
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_COLON))
{
tree eptype = NULL_TREE;
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"ISO C forbids omitting the middle term of a ?: expression");
if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
{
(cond_loc, default_conversion (cond.value));
c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
exp1 = c_parser_expression_conv (parser);
+ mark_exp_read (exp1.value);
c_inhibit_evaluation_warnings +=
((cond.value == truthvalue_true_node)
- (cond.value == truthvalue_false_node));
{
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);
+ exp2 = default_function_array_read_conversion (exp2_loc, exp2);
}
c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
ret.value = build_conditional_expr (colon_loc, cond.value,
break; \
} \
stack[sp - 1].expr \
- = default_function_array_conversion (stack[sp - 1].loc, \
- stack[sp - 1].expr); \
+ = default_function_array_read_conversion (stack[sp - 1].loc, \
+ stack[sp - 1].expr); \
stack[sp].expr \
- = default_function_array_conversion (stack[sp].loc, stack[sp].expr); \
+ = default_function_array_read_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, \
{
case TRUTH_ANDIF_EXPR:
stack[sp].expr
- = default_function_array_conversion (stack[sp].loc,
- stack[sp].expr);
+ = default_function_array_read_conversion (stack[sp].loc,
+ stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
(stack[sp].loc, default_conversion (stack[sp].expr.value));
c_inhibit_evaluation_warnings += (stack[sp].expr.value
break;
case TRUTH_ORIF_EXPR:
stack[sp].expr
- = default_function_array_conversion (stack[sp].loc,
- stack[sp].expr);
+ = default_function_array_read_conversion (stack[sp].loc,
+ stack[sp].expr);
stack[sp].expr.value = c_objc_common_truthvalue_conversion
(stack[sp].loc, default_conversion (stack[sp].expr.value));
c_inhibit_evaluation_warnings += (stack[sp].expr.value
{
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);
+ expr = default_function_array_read_conversion (expr_loc, expr);
}
ret.value = c_cast_expr (cast_loc, type_name, expr.value);
ret.original_code = ERROR_MARK;
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 (exp_loc, op);
+ op = default_function_array_read_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 (exp_loc, op);
+ op = default_function_array_read_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 (op_loc, ADDR_EXPR,
- c_parser_cast_expression (parser, NULL));
+ op = c_parser_cast_expression (parser, NULL);
+ mark_exp_read (op.value);
+ return parser_build_unary_op (op_loc, ADDR_EXPR, op);
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 (exp_loc, op);
- ret.value = build_indirect_ref (op_loc, op.value, "unary *");
+ op = default_function_array_read_conversion (exp_loc, op);
+ ret.value = build_indirect_ref (op_loc, op.value, RO_UNARY_STAR);
return ret;
case CPP_PLUS:
if (!c_dialect_objc () && !in_system_header)
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 (exp_loc, op);
+ op = default_function_array_read_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 (exp_loc, op);
+ op = default_function_array_read_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 (exp_loc, op);
+ op = default_function_array_read_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 (exp_loc, op);
+ op = default_function_array_read_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. */
sizeof_expr:
c_inhibit_evaluation_warnings--;
in_sizeof--;
+ mark_exp_read (expr.value);
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");
struct c_expr ret;
expr = c_parser_unary_expression (parser);
alignof_expr:
+ mark_exp_read (expr.value);
c_inhibit_evaluation_warnings--;
in_alignof--;
ret.value = c_alignof_expr (loc, expr.value);
case CPP_STRING16:
case CPP_STRING32:
case CPP_WSTRING:
+ case CPP_UTF8STRING:
expr.value = c_parser_peek_token (parser)->value;
expr.original_code = STRING_CST;
c_parser_consume_token (parser);
c_parser_compound_statement_nostart (parser);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- pedwarn (loc, OPT_pedantic,
+ pedwarn (loc, OPT_pedantic,
"ISO C forbids braced-groups within expressions");
expr.value = c_finish_stmt_expr (brace_loc, stmt);
}
break;
}
e1 = c_parser_expr_no_commas (parser, NULL);
+ mark_exp_read (e1.value);
e1.value = c_fully_fold (e1.value, false, NULL);
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
tree c;
c = e1.value;
+ mark_exp_read (e2.value);
+ mark_exp_read (e3.value);
if (TREE_CODE (c) != INTEGER_CST
|| !INTEGRAL_TYPE_P (TREE_TYPE (c)))
error_at (loc,
finish_init ();
maybe_warn_string_init (type, init);
+ if (type != error_mark_node
+ && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
+ && current_function_decl)
+ {
+ error ("compound literal qualified by address-space qualifier");
+ type = error_mark_node;
+ }
+
if (!flag_isoc99)
pedwarn (start_loc, OPT_pedantic, "ISO C90 forbids compound literals");
non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
orig_expr = expr;
+ mark_exp_read (expr.value);
/* 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,
expr.value = build_component_ref (op_loc,
build_indirect_ref (op_loc,
expr.value,
- "->"),
+ RO_ARROW),
ident);
expr.original_code = ERROR_MARK;
if (TREE_CODE (expr.value) != COMPONENT_REF)
case CPP_PLUS_PLUS:
/* Postincrement. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr_loc, expr);
+ expr = default_function_array_read_conversion (expr_loc, expr);
expr.value = build_unary_op (op_loc,
POSTINCREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
case CPP_MINUS_MINUS:
/* Postdecrement. */
c_parser_consume_token (parser);
- expr = default_function_array_conversion (expr_loc, expr);
+ expr = default_function_array_read_conversion (expr_loc, expr);
expr.value = build_unary_op (op_loc,
POSTDECREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
- expr = default_function_array_conversion (loc, expr);
+ expr = default_function_array_read_conversion (loc, expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
VEC_quick_push (tree, ret, expr.value);
loc = c_parser_peek_token (parser)->location;
expr = c_parser_expr_no_commas (parser, NULL);
if (convert_p)
- expr = default_function_array_conversion (loc, expr);
+ expr = default_function_array_read_conversion (loc, expr);
if (fold_p)
expr.value = c_fully_fold (expr.value, false, NULL);
VEC_safe_push (tree, gc, ret, expr.value);
/* Parse any stray semicolon. */
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"extra semicolon in struct or union specified");
c_parser_consume_token (parser);
continue;
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
c_parser_consume_token (parser);
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"extra semicolon in method definition specified");
}
if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
switch (c_parser_peek_token (parser)->type)
{
case CPP_SEMICOLON:
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+ pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"ISO C does not allow extra %<;%> outside of a function");
c_parser_consume_token (parser);
break;
c_parser_consume_pragma (parser);
c_invoke_pragma_handler (id);
- /* Skip to EOL, but suppress any error message. Those will have been
+ /* Skip to EOL, but suppress any error message. Those will have been
generated by the handler routine through calling error, as opposed
to calling c_parser_error. */
parser->error = true;
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. */
{
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_expr = default_function_array_read_conversion (rhs_loc, rhs_expr);
}
rhs = rhs_expr.value;
rhs = c_fully_fold (rhs, false, NULL);
init_loc = c_parser_peek_token (parser)->location;
init_exp = c_parser_expr_no_commas (parser, NULL);
- init_exp = default_function_array_conversion (init_loc, init_exp);
+ init_exp = default_function_array_read_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);
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. */