#include "cgraph.h"
\f
-/* Miscellaneous data and functions needed for the parser. */
-
-int yydebug;
-
/* Objective-C specific parser/lexer information. */
static int objc_pq_context = 0;
};
#define N_reswords (sizeof reswords / sizeof (struct resword))
-/* All OpenMP clauses. OpenMP 2.5. */
-typedef enum pragma_omp_clause {
- PRAGMA_OMP_CLAUSE_NONE = 0,
-
- PRAGMA_OMP_CLAUSE_COPYIN,
- PRAGMA_OMP_CLAUSE_COPYPRIVATE,
- PRAGMA_OMP_CLAUSE_DEFAULT,
- PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
- PRAGMA_OMP_CLAUSE_IF,
- PRAGMA_OMP_CLAUSE_LASTPRIVATE,
- PRAGMA_OMP_CLAUSE_NOWAIT,
- PRAGMA_OMP_CLAUSE_NUM_THREADS,
- PRAGMA_OMP_CLAUSE_ORDERED,
- PRAGMA_OMP_CLAUSE_PRIVATE,
- PRAGMA_OMP_CLAUSE_REDUCTION,
- PRAGMA_OMP_CLAUSE_SCHEDULE,
- PRAGMA_OMP_CLAUSE_SHARED
-} pragma_omp_clause;
-
-
/* Initialization routine for this file. */
void
parser->error = false;
}
-/* Skip tokens until we have consumed an entire block, or until we
- have consumed a non-nested ';'. */
-
-static void
-c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
-{
- unsigned nesting_depth = 0;
-
- while (true)
- {
- c_token *token;
-
- /* Peek at the next token. */
- token = c_parser_peek_token (parser);
- /* If we've run out of tokens, stop. */
- if (token->type == CPP_EOF)
- return;
- if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
- return;
- /* If the next token is a ';', we have reached the end of the
- statement. */
- if (token->type == CPP_SEMICOLON && !nesting_depth)
- {
- /* Consume the ';'. */
- c_parser_consume_token (parser);
- break;
- }
- /* If the next token is a non-nested '}', then we have reached
- the end of the current block. */
- if (token->type == CPP_CLOSE_BRACE
- && (nesting_depth == 0 || --nesting_depth == 0))
- {
- c_parser_consume_token (parser);
- break;
- }
- /* If it the next token is a '{', then we are entering a new
- block. Consume the entire block. */
- if (token->type == CPP_OPEN_BRACE)
- ++nesting_depth;
- c_parser_consume_token (parser);
- }
- parser->error = false;
-}
-
/* Expect to be at the end of the pragma directive and consume an
end of line marker. */
parser->error = false;
}
+/* Skip tokens until we have consumed an entire block, or until we
+ have consumed a non-nested ';'. */
+
+static void
+c_parser_skip_to_end_of_block_or_statement (c_parser *parser)
+{
+ unsigned nesting_depth = 0;
+ bool save_error = parser->error;
+
+ while (true)
+ {
+ c_token *token;
+
+ /* Peek at the next token. */
+ token = c_parser_peek_token (parser);
+
+ switch (token->type)
+ {
+ case CPP_EOF:
+ return;
+
+ case CPP_PRAGMA_EOL:
+ if (parser->in_pragma)
+ return;
+ break;
+
+ case CPP_SEMICOLON:
+ /* If the next token is a ';', we have reached the
+ end of the statement. */
+ if (!nesting_depth)
+ {
+ /* Consume the ';'. */
+ c_parser_consume_token (parser);
+ goto finished;
+ }
+ break;
+
+ case CPP_CLOSE_BRACE:
+ /* If the next token is a non-nested '}', then we have
+ reached the end of the current block. */
+ if (nesting_depth == 0 || --nesting_depth == 0)
+ {
+ c_parser_consume_token (parser);
+ goto finished;
+ }
+ break;
+
+ case CPP_OPEN_BRACE:
+ /* If it the next token is a '{', then we are entering a new
+ block. Consume the entire block. */
+ ++nesting_depth;
+ break;
+
+ case CPP_PRAGMA:
+ /* If we see a pragma, consume the whole thing at once. We
+ have some safeguards against consuming pragmas willy-nilly.
+ Normally, we'd expect to be here with parser->error set,
+ which disables these safeguards. But it's possible to get
+ here for secondary error recovery, after parser->error has
+ been cleared. */
+ c_parser_consume_pragma (parser);
+ c_parser_skip_to_pragma_eol (parser);
+ parser->error = save_error;
+ continue;
+
+ default:
+ break;
+ }
+
+ c_parser_consume_token (parser);
+ }
+
+ finished:
+ parser->error = false;
+}
+
/* Save the warning flags which are controlled by __extension__. */
static inline int
}
else
{
+ bool was_vm;
struct c_expr expr = c_parser_expression (parser);
skip_evaluation--;
in_typeof--;
&& DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
error ("%<typeof%> applied to a bit-field");
ret.spec = TREE_TYPE (expr.value);
- pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE));
+ was_vm = variably_modified_type_p (ret.spec, NULL_TREE);
+ /* This should be returned with the type so that when the type
+ is evaluated, this can be evaluated. For now, we avoid
+ evaluation when the context might. */
+ if (!skip_evaluation && was_vm)
+ {
+ tree e = expr.value;
+
+ /* If the expression is not of a type to which we cannot assign a line
+ number, wrap the thing in a no-op NOP_EXPR. */
+ if (DECL_P (e) || CONSTANT_CLASS_P (e))
+ e = build1 (NOP_EXPR, void_type_node, e);
+
+ if (CAN_HAVE_LOCATION_P (e))
+ SET_EXPR_LOCATION (e, input_location);
+
+ add_stmt (e);
+ }
+ pop_maybe_used (was_vm);
}
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
return ret;
parameter-type-list[opt] )
direct-abstract-declarator:
- direct-abstract-declarator[opt] ( parameter-forward-declarations
+ direct-abstract-declarator[opt] ( parameter-forward-declarations
parameter-type-list[opt] )
parameter-forward-declarations:
}
declarator = build_array_declarator (dimen, quals_attrs, static_seen,
star_seen);
+ if (declarator == NULL)
+ return NULL;
inner = set_array_declarator_inner (declarator, inner, !id_present);
return c_parser_direct_declarator_inner (parser, id_present, inner);
}
ret->tags = 0;
ret->types = list;
ret->others = 0;
+ ret->pending_sizes = 0;
+ ret->had_vla_unspec = 0;
c_parser_consume_token (parser);
pop_scope ();
return ret;
ret->tags = 0;
ret->types = 0;
ret->others = 0;
+ ret->pending_sizes = 0;
+ ret->had_vla_unspec = 0;
c_parser_consume_token (parser);
return ret;
}
ret->parms = 0;
ret->tags = 0;
ret->others = 0;
+ ret->pending_sizes = 0;
+ ret->had_vla_unspec = 0;
/* Suppress -Wold-style-definition for this case. */
ret->types = error_mark_node;
error ("ISO C requires a named argument before %<...%>");
ret->tags = 0;
ret->types = 0;
ret->others = 0;
+ ret->pending_sizes = 0;
+ ret->had_vla_unspec = 0;
return ret;
}
}
ret->tags = 0;
ret->types = 0;
ret->others = 0;
+ ret->pending_sizes = 0;
+ ret->had_vla_unspec = 0;
return ret;
}
}
last_stmt = true;
c_parser_statement_after_labels (parser);
}
+
+ parser->error = false;
}
if (last_label)
error ("label at end of compound statement");
(recursively) all of the component statements should already have
line numbers assigned. ??? Can we discard no-op statements
earlier? */
- if (stmt && EXPR_P (stmt))
+ if (stmt && CAN_HAVE_LOCATION_P (stmt))
SET_EXPR_LOCATION (stmt, loc);
}
loc = c_parser_peek_token (parser)->location;
cond = c_objc_common_truthvalue_conversion
(c_parser_expression_conv (parser).value);
- if (EXPR_P (cond))
+ if (CAN_HAVE_LOCATION_P (cond))
SET_EXPR_LOCATION (cond, loc);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
return cond;
is just parsing a statement but (a) it is a block in C99, (b) we
track whether the body is an if statement for the sake of
-Wparentheses warnings, (c) we handle an empty body specially for
- the sake of -Wextra warnings. */
+ the sake of -Wempty-body warnings. */
static tree
c_parser_if_body (c_parser *parser, bool *if_p)
&& c_parser_peek_2nd_token (parser)->type == CPP_COLON))
c_parser_label (parser);
*if_p = c_parser_next_token_is_keyword (parser, RID_IF);
- if (extra_warnings && c_parser_next_token_is (parser, CPP_SEMICOLON))
+ if (warn_empty_body && c_parser_next_token_is (parser, CPP_SEMICOLON))
add_stmt (build_empty_stmt ());
c_parser_statement_after_labels (parser);
return c_end_compound_stmt (block, flag_isoc99);
{
tree ocond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (ocond);
- if (EXPR_P (cond))
+ if (CAN_HAVE_LOCATION_P (cond))
SET_EXPR_LOCATION (cond, loc);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
ret.original_code = ERROR_MARK;
return ret;
}
+
+ /* Save casted types in the function's used types hash table. */
+ 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);
/* sizeof ( type-name ). */
skip_evaluation--;
in_sizeof--;
+ if (type_name->declarator->kind == cdk_array
+ && type_name->declarator->u.array.vla_unspec_p)
+ {
+ /* C99 6.7.5.2p4 */
+ error ("%<[*]%> not allowed in other than a declaration");
+ }
return c_expr_sizeof_type (type_name);
}
else
if (type == error_mark_node)
offsetof_ref = error_mark_node;
else
- offsetof_ref = build1 (INDIRECT_REF, type, NULL);
+ offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
/* 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. */
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
- expr.value = fold_offsetof (offsetof_ref);
+ expr.value = fold_offsetof (offsetof_ref, NULL_TREE);
expr.original_code = ERROR_MARK;
}
break;
struct c_expr expr;
start_init (NULL_TREE, NULL, 0);
type = groktypename (type_name);
- if (C_TYPE_VARIABLE_SIZE (type))
+ if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
{
error ("compound literal has variable size");
type = error_mark_node;
tree c;
for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
- if (TREE_CODE (c) == code)
+ if (OMP_CLAUSE_CODE (c) == code)
{
error ("too many %qs clauses", name);
break;
return the list created. */
static tree
-c_parser_omp_variable_list (c_parser *parser, enum tree_code kind, tree list)
+c_parser_omp_variable_list (c_parser *parser, enum omp_clause_code kind,
+ tree list)
{
if (c_parser_next_token_is_not (parser, CPP_NAME)
|| c_parser_peek_token (parser)->id_kind != C_ID_ID)
;
else if (kind != 0)
{
- tree u = make_node (kind);
+ tree u = build_omp_clause (kind);
OMP_CLAUSE_DECL (u) = t;
OMP_CLAUSE_CHAIN (u) = list;
list = u;
return list;
check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
- c = make_node (OMP_CLAUSE_DEFAULT);
+ c = build_omp_clause (OMP_CLAUSE_DEFAULT);
OMP_CLAUSE_CHAIN (c) = list;
OMP_CLAUSE_DEFAULT_KIND (c) = kind;
check_no_duplicate_clause (list, OMP_CLAUSE_IF, "if");
- c = make_node (OMP_CLAUSE_IF);
+ c = build_omp_clause (OMP_CLAUSE_IF);
OMP_CLAUSE_IF_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
list = c;
check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
- c = make_node (OMP_CLAUSE_NOWAIT);
+ c = build_omp_clause (OMP_CLAUSE_NOWAIT);
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
- c = make_node (OMP_CLAUSE_NUM_THREADS);
+ c = build_omp_clause (OMP_CLAUSE_NUM_THREADS);
OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
OMP_CLAUSE_CHAIN (c) = list;
list = c;
check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
- c = make_node (OMP_CLAUSE_ORDERED);
+ c = build_omp_clause (OMP_CLAUSE_ORDERED);
OMP_CLAUSE_CHAIN (c) = list;
return c;
}
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
return list;
- c = make_node (OMP_CLAUSE_SCHEDULE);
+ c = build_omp_clause (OMP_CLAUSE_SCHEDULE);
if (c_parser_next_token_is (parser, CPP_NAME))
{
c_parser_omp_atomic (c_parser *parser)
{
tree lhs, rhs;
+ tree stmt;
enum tree_code code;
c_parser_skip_to_pragma_eol (parser);
rhs = c_parser_expression (parser).value;
break;
}
- c_finish_omp_atomic (code, lhs, rhs);
+ stmt = c_finish_omp_atomic (code, lhs, rhs);
+ if (stmt != error_mark_node)
+ add_stmt (stmt);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
{
cond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (cond);
- if (EXPR_P (cond))
+ if (CAN_HAVE_LOCATION_P (cond))
SET_EXPR_LOCATION (cond, input_location);
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
/* Only bother calling c_finish_omp_for if we havn't already generated
an error from the initialization parsing. */
- if (decl != NULL)
+ if (decl != NULL && decl != error_mark_node && init != error_mark_node)
return c_finish_omp_for (loc, decl, init, cond, incr, body, NULL);
return NULL;
if (stmt)
OMP_FOR_CLAUSES (stmt) = ws_clause;
stmt = c_finish_omp_parallel (par_clause, block);
+ OMP_PARALLEL_COMBINED (stmt) = 1;
break;
case PRAGMA_OMP_PARALLEL_SECTIONS:
if (stmt)
OMP_SECTIONS_CLAUSES (stmt) = ws_clause;
stmt = c_finish_omp_parallel (par_clause, block);
+ OMP_PARALLEL_COMBINED (stmt) = 1;
break;
default:
p_kind = c_parser_peek_token (parser)->pragma_kind;
c_parser_consume_pragma (parser);
+ /* For all constructs below except #pragma omp atomic
+ MUST_NOT_THROW catch handlers are needed when exceptions
+ are enabled. */
+ if (p_kind != PRAGMA_OMP_ATOMIC)
+ c_maybe_initialize_eh ();
+
switch (p_kind)
{
case PRAGMA_OMP_ATOMIC: