/* 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
#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 "rtl.h" /* For decl_default_tls_model. */
#include "langhooks.h"
#include "input.h"
#include "cpplib.h"
#include "target.h"
#include "cgraph.h"
#include "plugin.h"
-#include "except.h"
\f
/* Initialization routine for this file. */
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;
/* 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
"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:
}
}
+
+/* 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 *);
static void c_parser_for_statement (c_parser *);
static tree c_parser_asm_statement (c_parser *);
static tree c_parser_asm_operands (c_parser *, bool);
+static tree c_parser_asm_goto_operands (c_parser *);
static tree c_parser_asm_clobbers (c_parser *);
static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *);
static struct c_expr c_parser_conditional_expression (c_parser *,
{
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;
/* 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]
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 */
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;
if (nested)
{
tree decl = current_function_decl;
+ /* Mark nested functions as needing static-chain initially.
+ lower_nested_functions will recompute it but the
+ DECL_STATIC_CHAIN flag is also used before that happens,
+ by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */
+ DECL_STATIC_CHAIN (decl) = 1;
add_stmt (fnbody);
finish_function ();
c_pop_function_context ();
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
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
{
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);
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;
"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)
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;
}
}
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,
+ 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);
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;
}
}
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:
/* 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);
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;
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,
+ 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
{
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 ());
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);
+ process_init_element (init, false, braced_init_obstack);
}
/* Parse a compound statement (possibly a function body) (C90 6.6.2,
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
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,
+ pedwarn_c90 (loc,
(pedantic && !flag_isoc99)
? OPT_pedantic
: OPT_Wdeclaration_after_statement,
&& (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);
}
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);
}
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))
{
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,
+ /*static_assert_ok*/ true,
/*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);
}
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);
}
asm-statement:
asm type-qualifier[opt] ( asm-argument ) ;
+ asm type-qualifier[opt] goto ( asm-goto-argument ) ;
asm-argument:
asm-string-literal
asm-string-literal : asm-operands[opt]
asm-string-literal : asm-operands[opt] : asm-operands[opt]
- asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers
+ asm-string-literal : asm-operands[opt] : asm-operands[opt] : asm-clobbers[opt]
+
+ asm-goto-argument:
+ asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
+ : asm-goto-operands
Qualifiers other than volatile are accepted in the syntax but
warned for. */
static tree
c_parser_asm_statement (c_parser *parser)
{
- tree quals, str, outputs, inputs, clobbers, ret;
- bool simple;
+ tree quals, str, outputs, inputs, clobbers, labels, ret;
+ bool simple, is_goto;
location_t asm_loc = c_parser_peek_token (parser)->location;
+ int section, nsections;
+
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))
}
else
quals = NULL_TREE;
+
+ is_goto = false;
+ if (c_parser_next_token_is_keyword (parser, RID_GOTO))
+ {
+ c_parser_consume_token (parser);
+ is_goto = true;
+ }
+
/* ??? Follow the C++ parser rather than using the
lex_untranslated_string kludge. */
parser->lex_untranslated_string = true;
+ ret = NULL;
+
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
- {
- parser->lex_untranslated_string = false;
- return NULL_TREE;
- }
+ goto error;
+
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;
- outputs = NULL_TREE;
- inputs = NULL_TREE;
- clobbers = NULL_TREE;
- goto done_asm;
- }
- if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
- {
- parser->lex_untranslated_string = false;
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
- }
- simple = false;
- /* Parse outputs. */
- if (c_parser_next_token_is (parser, CPP_COLON)
- || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- outputs = NULL_TREE;
- else
- outputs = c_parser_asm_operands (parser, false);
- if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- {
- inputs = NULL_TREE;
- clobbers = NULL_TREE;
- goto done_asm;
- }
- if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
- {
- parser->lex_untranslated_string = false;
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
- }
- /* Parse inputs. */
- if (c_parser_next_token_is (parser, CPP_COLON)
- || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- inputs = NULL_TREE;
- else
- inputs = c_parser_asm_operands (parser, true);
- if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- {
- clobbers = NULL_TREE;
- goto done_asm;
- }
- if (!c_parser_require (parser, CPP_COLON, "expected %<:%> or %<)%>"))
- {
- parser->lex_untranslated_string = false;
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
+ goto error_close_paren;
+
+ simple = true;
+ outputs = NULL_TREE;
+ inputs = NULL_TREE;
+ clobbers = NULL_TREE;
+ labels = NULL_TREE;
+
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
+ goto done_asm;
+
+ /* Parse each colon-delimited section of operands. */
+ nsections = 3 + is_goto;
+ for (section = 0; section < nsections; ++section)
+ {
+ if (!c_parser_require (parser, CPP_COLON,
+ is_goto
+ ? "expected %<:%>"
+ : "expected %<:%> or %<)%>"))
+ goto error_close_paren;
+
+ /* Once past any colon, we're no longer a simple asm. */
+ simple = false;
+
+ if ((!c_parser_next_token_is (parser, CPP_COLON)
+ && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+ || section == 3)
+ switch (section)
+ {
+ case 0:
+ /* For asm goto, we don't allow output operands, but reserve
+ the slot for a future extension that does allow them. */
+ if (!is_goto)
+ outputs = c_parser_asm_operands (parser, false);
+ break;
+ case 1:
+ inputs = c_parser_asm_operands (parser, true);
+ break;
+ case 2:
+ clobbers = c_parser_asm_clobbers (parser);
+ break;
+ case 3:
+ labels = c_parser_asm_goto_operands (parser);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
+ goto done_asm;
}
- /* Parse clobbers. */
- clobbers = c_parser_asm_clobbers (parser);
+
done_asm:
- parser->lex_untranslated_string = false;
if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- return NULL_TREE;
+ goto error;
}
+
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 (asm_loc, str, outputs, inputs,
- clobbers, simple));
+ clobbers, labels, simple));
+
+ error:
+ parser->lex_untranslated_string = false;
return ret;
+
+ error_close_paren:
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+ goto error;
}
/* Parse asm operands, a GNU extension. If CONVERT_P (for inputs but
}
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);
return list;
}
+/* Parse asm goto labels, a GNU extension.
+
+ asm-goto-operands:
+ identifier
+ asm-goto-operands , identifier
+*/
+
+static tree
+c_parser_asm_goto_operands (c_parser *parser)
+{
+ tree list = NULL_TREE;
+ while (true)
+ {
+ tree name, label;
+
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ {
+ c_token *tok = c_parser_peek_token (parser);
+ name = tok->value;
+ label = lookup_label_for_goto (tok->location, name);
+ c_parser_consume_token (parser);
+ TREE_USED (label) = 1;
+ }
+ else
+ {
+ c_parser_error (parser, "expected identifier");
+ return NULL_TREE;
+ }
+
+ name = build_string (IDENTIFIER_LENGTH (name),
+ IDENTIFIER_POINTER (name));
+ list = tree_cons (name, label, list);
+ if (c_parser_next_token_is (parser, CPP_COMMA))
+ c_parser_consume_token (parser);
+ else
+ return nreverse (list);
+ }
+}
+
/* Parse an expression other than a compound expression; that is, an
assignment expression (C90 6.3.16, C99 6.5.16). If AFTER is not
NULL then it is an Objective-C message expression which is the
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;
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);
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;
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;
}
}
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);
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);
+ c_parser_declaration_or_fndef (parser, true, true, true, true, true);
decl = check_for_loop_decls (for_loc);
if (decl == NULL)
goto error_init;
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. */
/* Initialize EH, if we've been told to do so. */
if (flag_exceptions)
- {
- default_init_unwind_resume_libfunc ();
- using_eh_for_cleanups ();
- }
+ using_eh_for_cleanups ();
c_parser_translation_unit (the_parser);
the_parser = NULL;