#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
+#include "tm.h" /* For rtl.h: needs enum reg_class. */
#include "tree.h"
-#include "rtl.h"
#include "langhooks.h"
#include "input.h"
#include "cpplib.h"
#include "timevar.h"
-#include "c-pragma.h"
+#include "c-family/c-pragma.h"
#include "c-tree.h"
#include "flags.h"
#include "output.h"
#include "toplev.h"
#include "ggc.h"
-#include "c-common.h"
+#include "c-family/c-common.h"
#include "vec.h"
#include "target.h"
#include "cgraph.h"
#include "plugin.h"
-#include "except.h"
\f
/* Initialization routine for this file. */
if (!c_dialect_objc ())
mask |= D_OBJC | D_CXX_OBJC;
- ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
+ ridpointers = ggc_alloc_cleared_vec_tree ((int) RID_MAX);
for (i = 0; i < num_c_common_reswords; i++)
{
/* If a keyword is disabled, do not enter it into the table
/* If this token is a CPP_PRAGMA, this indicates the pragma that
was seen. Otherwise it is PRAGMA_NONE. */
ENUM_BITFIELD (pragma_kind) pragma_kind : 8;
- /* The value associated with this token, if any. */
- tree value;
/* The location at which this token was found. */
location_t location;
+ /* The value associated with this token, if any. */
+ tree value;
} c_token;
/* A parser structure recording information about the state and
{
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
case RID_THREAD:
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
}
}
+
+/* Return true if TOKEN can start declaration specifiers or a static
+ assertion, false otherwise. */
+static bool
+c_token_starts_declaration (c_token *token)
+{
+ if (c_token_starts_declspecs (token)
+ || token->keyword == RID_STATIC_ASSERT)
+ return true;
+ else
+ return false;
+}
+
/* Return true if the next token from PARSER can start declaration
specifiers, false otherwise. */
static inline bool
return c_token_starts_declspecs (token);
}
+/* Return true if the next token from PARSER can start declaration
+ specifiers or a static assertion, false otherwise. */
+static inline bool
+c_parser_next_token_starts_declaration (c_parser *parser)
+{
+ c_token *token = c_parser_peek_token (parser);
+ return c_token_starts_declaration (token);
+}
+
/* Return a pointer to the next-but-one token from PARSER, reading it
in if necessary. The next token is already read in. */
static void c_parser_external_declaration (c_parser *);
static void c_parser_asm_definition (c_parser *);
-static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, bool);
+static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
+ bool, bool);
+static void c_parser_static_assert_declaration_no_semi (c_parser *);
+static void c_parser_static_assert_declaration (c_parser *);
static void c_parser_declspecs (c_parser *, struct c_declspecs *, bool, bool,
bool);
static struct c_typespec c_parser_enum_specifier (c_parser *);
static struct c_type_name *c_parser_type_name (c_parser *);
static struct c_expr c_parser_initializer (c_parser *);
static struct c_expr c_parser_braced_init (c_parser *, tree, bool);
-static void c_parser_initelt (c_parser *);
-static void c_parser_initval (c_parser *, struct c_expr *);
+static void c_parser_initelt (c_parser *, struct obstack *);
+static void c_parser_initval (c_parser *, struct c_expr *,
+ struct obstack *);
static tree c_parser_compound_statement (c_parser *);
static void c_parser_compound_statement_nostart (c_parser *);
static void c_parser_label (c_parser *);
/* A declaration or a function definition. We can only tell
which after parsing the declaration specifiers, if any, and
the first declarator. */
- c_parser_declaration_or_fndef (parser, true, true, false, true);
+ c_parser_declaration_or_fndef (parser, true, true, true, false, true);
break;
}
}
/* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
6.7, 6.9.1). If FNDEF_OK is true, a function definition is
accepted; otherwise (old-style parameter declarations) only other
- declarations are accepted. If NESTED is true, we are inside a
- function or parsing old-style parameter declarations; any functions
- encountered are nested functions and declaration specifiers are
- required; otherwise we are at top level and functions are normal
- functions and declaration specifiers may be optional. If EMPTY_OK
- is true, empty declarations are OK (subject to all other
- constraints); otherwise (old-style parameter declarations) they are
- diagnosed. If START_ATTR_OK is true, the declaration specifiers
- may start with attributes; otherwise they may not.
+ declarations are accepted. If STATIC_ASSERT_OK is true, a static
+ assertion is accepted; otherwise (old-style parameter declarations)
+ it is not. If NESTED is true, we are inside a function or parsing
+ old-style parameter declarations; any functions encountered are
+ nested functions and declaration specifiers are required; otherwise
+ we are at top level and functions are normal functions and
+ declaration specifiers may be optional. If EMPTY_OK is true, empty
+ declarations are OK (subject to all other constraints); otherwise
+ (old-style parameter declarations) they are diagnosed. If
+ START_ATTR_OK is true, the declaration specifiers may start with
+ attributes; otherwise they may not.
declaration:
declaration-specifiers init-declarator-list[opt] ;
+ static_assert-declaration
function-definition:
declaration-specifiers[opt] declarator declaration-list[opt]
threadprivate-directive */
static void
-c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, bool empty_ok,
+c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
+ bool static_assert_ok, bool empty_ok,
bool nested, bool start_attr_ok)
{
struct c_declspecs *specs;
bool diagnosed_no_specs = false;
location_t here = c_parser_peek_token (parser)->location;
+ if (static_assert_ok
+ && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
+ {
+ c_parser_static_assert_declaration (parser);
+ return;
+ }
specs = build_null_declspecs ();
c_parser_declspecs (parser, specs, true, true, start_attr_ok);
if (parser->error)
function definitions either. */
while (c_parser_next_token_is_not (parser, CPP_EOF)
&& c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
- c_parser_declaration_or_fndef (parser, false, false, true, false);
+ c_parser_declaration_or_fndef (parser, false, false, false,
+ true, false);
store_parm_decls ();
DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
= c_parser_peek_token (parser)->location;
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
+/* Parse a static assertion (C1X N1425 6.7.10).
+
+ static_assert-declaration:
+ static_assert-declaration-no-semi ;
+*/
+
+static void
+c_parser_static_assert_declaration (c_parser *parser)
+{
+ c_parser_static_assert_declaration_no_semi (parser);
+ if (parser->error
+ || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
+ c_parser_skip_to_end_of_block_or_statement (parser);
+}
+
+/* Parse a static assertion (C1X N1425 6.7.10), without the trailing
+ semicolon.
+
+ static_assert-declaration-no-semi:
+ _Static_assert ( constant-expression , string-literal )
+*/
+
+static void
+c_parser_static_assert_declaration_no_semi (c_parser *parser)
+{
+ location_t assert_loc, value_loc;
+ tree value;
+ tree string;
+
+ gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
+ assert_loc = c_parser_peek_token (parser)->location;
+ if (!flag_isoc1x)
+ {
+ if (flag_isoc99)
+ pedwarn (assert_loc, OPT_pedantic,
+ "ISO C99 does not support %<_Static_assert%>");
+ else
+ pedwarn (assert_loc, OPT_pedantic,
+ "ISO C90 does not support %<_Static_assert%>");
+ }
+ c_parser_consume_token (parser);
+ if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+ return;
+ value_loc = c_parser_peek_token (parser)->location;
+ value = c_parser_expr_no_commas (parser, NULL).value;
+ parser->lex_untranslated_string = true;
+ if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
+ {
+ parser->lex_untranslated_string = false;
+ return;
+ }
+ switch (c_parser_peek_token (parser)->type)
+ {
+ case CPP_STRING:
+ case CPP_STRING16:
+ case CPP_STRING32:
+ case CPP_WSTRING:
+ case CPP_UTF8STRING:
+ string = c_parser_peek_token (parser)->value;
+ c_parser_consume_token (parser);
+ parser->lex_untranslated_string = false;
+ break;
+ default:
+ c_parser_error (parser, "expected string literal");
+ parser->lex_untranslated_string = false;
+ return;
+ }
+ c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
+ {
+ error_at (value_loc, "expression in static assertion is not an integer");
+ return;
+ }
+ if (TREE_CODE (value) != INTEGER_CST)
+ {
+ value = c_fully_fold (value, false, NULL);
+ if (TREE_CODE (value) == INTEGER_CST)
+ pedwarn (value_loc, OPT_pedantic, "expression in static assertion "
+ "is not an integer constant expression");
+ }
+ if (TREE_CODE (value) != INTEGER_CST)
+ {
+ error_at (value_loc, "expression in static assertion is not constant");
+ return;
+ }
+ constant_expression_warning (value);
+ if (integer_zerop (value))
+ error_at (assert_loc, "static assertion failed: %E", string);
+}
+
/* Parse some declaration specifiers (possibly none) (C90 6.5, C99
6.7), adding them to SPECS (which may already include some).
Storage class specifiers are accepted iff SCSPEC_OK; type
type-specifier:
typeof-specifier
+ __int128
_Decimal32
_Decimal64
_Decimal128
break;
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT128:
case RID_SHORT:
case RID_SIGNED:
case RID_COMPLEX:
struct-declaration:
specifier-qualifier-list struct-declarator-list
+ static_assert-declaration-no-semi
specifier-qualifier-list:
type-specifier specifier-qualifier-list[opt]
restore_extension_diagnostics (ext);
return decl;
}
+ if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
+ {
+ c_parser_static_assert_declaration_no_semi (parser);
+ return NULL_TREE;
+ }
specs = build_null_declspecs ();
decl_loc = c_parser_peek_token (parser)->location;
c_parser_declspecs (parser, specs, false, true, true);
declarator, specs, width, &all_prefix_attrs);
decl_attributes (&d, chainon (postfix_attrs,
all_prefix_attrs), 0);
- TREE_CHAIN (d) = decls;
+ DECL_CHAIN (d) = decls;
decls = d;
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
all_prefix_attrs = chainon (c_parser_attributes (parser),
"expected %<]%>");
return NULL;
}
+ if (dimen)
+ mark_exp_read (dimen);
declarator = build_array_declarator (brace_loc, dimen, quals_attrs,
static_seen, star_seen);
if (declarator == NULL)
static struct c_arg_info *
c_parser_parms_list_declarator (c_parser *parser, tree attrs)
{
- bool good_parm = false;
+ bool bad_parm = false;
/* ??? Following the old parser, forward parameter declarations may
use abstract declarators, and if no real parameter declarations
follow the forward declarations then this is not diagnosed. Also
/* Parse a parameter. */
struct c_parm *parm = c_parser_parameter_declaration (parser, attrs);
attrs = NULL_TREE;
- if (parm != NULL)
- {
- good_parm = true;
- push_parm_decl (parm);
- }
+ if (parm == NULL)
+ bad_parm = true;
+ else
+ push_parm_decl (parm);
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
tree new_attrs;
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
{
c_parser_consume_token (parser);
- if (good_parm)
- return get_parm_info (false);
- else
+ if (bad_parm)
{
- struct c_arg_info *ret
- = XOBNEW (&parser_obstack, struct c_arg_info);
- ret->parms = 0;
- ret->tags = 0;
- ret->types = 0;
- ret->others = 0;
- ret->pending_sizes = 0;
- ret->had_vla_unspec = 0;
- return ret;
+ get_pending_sizes ();
+ return NULL;
}
+ else
+ return get_parm_info (false);
}
if (!c_parser_require (parser, CPP_COMMA,
"expected %<;%>, %<,%> or %<)%>"))
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
{
c_parser_consume_token (parser);
- if (good_parm)
- return get_parm_info (true);
- else
+ if (bad_parm)
{
- struct c_arg_info *ret
- = XOBNEW (&parser_obstack, struct c_arg_info);
- ret->parms = 0;
- ret->tags = 0;
- ret->types = 0;
- ret->others = 0;
- ret->pending_sizes = 0;
- ret->had_vla_unspec = 0;
- return ret;
+ get_pending_sizes ();
+ return NULL;
}
+ else
+ return get_parm_info (true);
}
else
{
bool dummy = false;
if (!c_parser_next_token_starts_declspecs (parser))
{
+ c_token *token = c_parser_peek_token (parser);
+ if (parser->error)
+ return NULL;
+ c_parser_set_source_position_from_token (token);
+ if (token->type == CPP_NAME
+ && c_parser_peek_2nd_token (parser)->type != CPP_COMMA
+ && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN)
+ {
+ error ("unknown type name %qE", token->value);
+ parser->error = true;
+ }
/* ??? In some Objective-C cases '...' isn't applicable so there
should be a different message. */
- c_parser_error (parser,
- "expected declaration specifiers or %<...%>");
+ else
+ c_parser_error (parser,
+ "expected declaration specifiers or %<...%>");
c_parser_skip_to_end_of_parameter (parser);
return NULL;
}
case RID_STATIC:
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT128:
case RID_CONST:
case RID_EXTERN:
case RID_REGISTER:
static struct c_expr
c_parser_braced_init (c_parser *parser, tree type, bool nested_p)
{
+ struct c_expr ret;
+ struct obstack braced_init_obstack;
location_t brace_loc = c_parser_peek_token (parser)->location;
+ gcc_obstack_init (&braced_init_obstack);
gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
c_parser_consume_token (parser);
if (nested_p)
- push_init_level (0);
+ push_init_level (0, &braced_init_obstack);
else
really_start_incremental_init (type);
if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
comma. */
while (true)
{
- c_parser_initelt (parser);
+ c_parser_initelt (parser, &braced_init_obstack);
if (parser->error)
break;
if (c_parser_next_token_is (parser, CPP_COMMA))
}
if (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
{
- 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);
+ pop_init_level (0, &braced_init_obstack);
+ obstack_free (&braced_init_obstack, NULL);
return ret;
}
c_parser_consume_token (parser);
- return pop_init_level (0);
+ ret = pop_init_level (0, &braced_init_obstack);
+ obstack_free (&braced_init_obstack, NULL);
+ return ret;
}
/* Parse a nested initializer, including designators. */
static void
-c_parser_initelt (c_parser *parser)
+c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
{
/* Parse any designator or designator list. A single array
designator may have the subsequent "=" omitted in GNU C, but a
&& c_parser_peek_2nd_token (parser)->type == CPP_COLON)
{
/* Old-style structure member designator. */
- set_init_label (c_parser_peek_token (parser)->value);
+ set_init_label (c_parser_peek_token (parser)->value,
+ braced_init_obstack);
/* Use the colon as the error location. */
pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_pedantic,
"obsolete use of designated initializer with %<:%>");
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_NAME))
{
- set_init_label (c_parser_peek_token (parser)->value);
+ set_init_label (c_parser_peek_token (parser)->value,
+ braced_init_obstack);
c_parser_consume_token (parser);
}
else
init.original_type = NULL;
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- process_init_element (init, false);
+ process_init_element (init, false, braced_init_obstack);
return;
}
}
/* Now parse and process the remainder of the
initializer, starting with this message
expression as a primary-expression. */
- c_parser_initval (parser, &mexpr);
+ c_parser_initval (parser, &mexpr, braced_init_obstack);
return;
}
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
{
c_parser_consume_token (parser);
- set_init_index (first, second);
+ set_init_index (first, second, braced_init_obstack);
if (second)
pedwarn (ellipsis_loc, OPT_pedantic,
"ISO C forbids specifying range of elements to initialize");
init.original_type = NULL;
c_parser_error (parser, "expected %<=%>");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- process_init_element (init, false);
+ process_init_element (init, false, braced_init_obstack);
return;
}
}
}
}
- c_parser_initval (parser, NULL);
+ c_parser_initval (parser, NULL, braced_init_obstack);
}
/* Parse a nested initializer; as c_parser_initializer but parses
initializer. */
static void
-c_parser_initval (c_parser *parser, struct c_expr *after)
+c_parser_initval (c_parser *parser, struct c_expr *after,
+ struct obstack * braced_init_obstack)
{
struct c_expr init;
gcc_assert (!after || c_dialect_objc ());
&& TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
init = default_function_array_read_conversion (loc, init);
}
- process_init_element (init, false);
+ process_init_element (init, false, braced_init_obstack);
}
/* Parse a compound statement (possibly a function body) (C90 6.6.2,
c_parser_label (parser);
}
else if (!last_label
- && c_parser_next_token_starts_declspecs (parser))
+ && c_parser_next_token_starts_declaration (parser))
{
last_label = false;
mark_valid_location_for_stdc_pragma (false);
- c_parser_declaration_or_fndef (parser, true, true, true, true);
+ c_parser_declaration_or_fndef (parser, true, true, true, true, true);
if (last_stmt)
pedwarn_c90 (loc,
(pedantic && !flag_isoc99)
&& (c_parser_peek_2nd_token (parser)->keyword
== RID_EXTENSION))
c_parser_consume_token (parser);
- if (c_token_starts_declspecs (c_parser_peek_2nd_token (parser)))
+ if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
{
int ext;
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);
+ c_parser_declaration_or_fndef (parser, true, true, true, true,
+ true);
/* Following the old parser, __extension__ does not
disable this diagnostic. */
restore_extension_diagnostics (ext);
}
if (label)
{
- if (c_parser_next_token_starts_declspecs (parser)
+ if (c_parser_next_token_starts_declaration (parser)
&& !(c_parser_next_token_is (parser, CPP_NAME)
&& c_parser_peek_2nd_token (parser)->type == CPP_COLON))
{
"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,
+ /*static_assert_ok*/ true,
/*nested*/ true, /*empty_ok*/ false,
/*start_attr_ok*/ true);
}
c_parser_consume_token (parser);
c_finish_expr_stmt (loc, NULL_TREE);
}
- else if (c_parser_next_token_starts_declspecs (parser))
+ else if (c_parser_next_token_starts_declaration (parser))
{
- c_parser_declaration_or_fndef (parser, true, true, true, true);
+ c_parser_declaration_or_fndef (parser, true, true, true, true, true);
check_for_loop_decls (for_loc);
}
else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
&& (c_parser_peek_2nd_token (parser)->keyword
== RID_EXTENSION))
c_parser_consume_token (parser);
- if (c_token_starts_declspecs (c_parser_peek_2nd_token (parser)))
+ if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)))
{
int ext;
ext = disable_extension_diagnostics ();
c_parser_consume_token (parser);
- c_parser_declaration_or_fndef (parser, true, true, true, true);
+ c_parser_declaration_or_fndef (parser, true, true, true, true,
+ true);
restore_extension_diagnostics (ext);
check_for_loop_decls (for_loc);
}
c_parser_conditional_expression (c_parser *parser, struct c_expr *after)
{
struct c_expr cond, exp1, exp2, ret;
- location_t cond_loc, colon_loc;
+ location_t cond_loc, colon_loc, middle_loc;
gcc_assert (!after || c_dialect_objc ());
if (c_parser_next_token_is (parser, CPP_COLON))
{
tree eptype = NULL_TREE;
- pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
+
+ middle_loc = c_parser_peek_token (parser)->location;
+ pedwarn (middle_loc, OPT_pedantic,
"ISO C forbids omitting the middle term of a ?: expression");
+ warn_for_omitted_condop (middle_loc, cond.value);
if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
{
eptype = TREE_TYPE (cond.value);
pedwarn (loc, OPT_pedantic,
"ISO C forbids braced-groups within expressions");
expr.value = c_finish_stmt_expr (brace_loc, stmt);
+ mark_exp_read (expr.value);
}
else if (c_token_starts_typename (c_parser_peek_2nd_token (parser)))
{
while (c_parser_next_token_is (parser, CPP_COMMA))
{
struct c_expr next;
+ tree lhsval;
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;
+ lhsval = expr.value;
+ while (TREE_CODE (lhsval) == COMPOUND_EXPR)
+ lhsval = TREE_OPERAND (lhsval, 1);
+ if (DECL_P (lhsval) || handled_component_p (lhsval))
+ mark_exp_read (lhsval);
next = c_parser_expr_no_commas (parser, NULL);
next = default_function_array_conversion (expr_loc, next);
expr.value = build_compound_expr (loc, expr.value, next.value);
/* Comma-separated instance variables are chained together in
reverse order; add them one by one. */
tree ivar = nreverse (decls);
- for (; ivar; ivar = TREE_CHAIN (ivar))
+ for (; ivar; ivar = DECL_CHAIN (ivar))
objc_add_instance_variable (copy_node (ivar));
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
default:
if (c_parser_next_token_is_keyword (parser, RID_AT_END))
return;
- c_parser_declaration_or_fndef (parser, false, true, false, true);
+ c_parser_declaration_or_fndef (parser, false, false, true,
+ false, true);
break;
}
}
case RID_ALIGNOF:
case RID_UNSIGNED:
case RID_LONG:
+ case RID_INT128:
case RID_CONST:
case RID_SHORT:
case RID_VOLATILE:
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;
+ tree declv, condv, incrv, initv, ret = NULL;
bool fail = false, open_brace_parsed = false;
int i, collapse = 1, nbraces = 0;
location_t for_loc;
+ VEC(tree,gc) *for_block = make_tree_vector ();
for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
goto pop_scopes;
/* Parse the initialization declaration or expression. */
- if (c_parser_next_token_starts_declspecs (parser))
+ if (c_parser_next_token_starts_declaration (parser))
{
if (i > 0)
- for_block
- = tree_cons (NULL, c_begin_compound_stmt (true), for_block);
- c_parser_declaration_or_fndef (parser, true, true, true, true);
+ VEC_safe_push (tree, gc, for_block, c_begin_compound_stmt (true));
+ c_parser_declaration_or_fndef (parser, true, true, true, true, true);
decl = check_for_loop_decls (for_loc);
if (decl == NULL)
goto error_init;
ret = stmt;
}
pop_scopes:
- while (for_block)
+ while (!VEC_empty (tree, for_block))
{
/* 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);
+ stmt = c_end_compound_stmt (loc, VEC_pop (tree, for_block), true);
add_stmt (stmt);
- for_block = TREE_CHAIN (for_block);
}
+ release_tree_vector (for_block);
return ret;
}
if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
c_parser_pragma_pch_preprocess (&tparser);
- the_parser = GGC_NEW (c_parser);
+ the_parser = ggc_alloc_c_parser ();
*the_parser = tparser;
/* Initialize EH, if we've been told to do so. */