===================================================================
@@ -1030,9 +1030,9 @@ restore_extension_diagnostics (int flags
/* Possibly kinds of declarator to parse. */
typedef enum c_dtr_syn {
/* A normal declarator with an identifier. */
- C_DTR_NORMAL,
+ C_DTR_NORMAL = 1,
/* An abstract declarator (maybe empty). */
- C_DTR_ABSTRACT,
+ C_DTR_ABSTRACT = 2,
/* A parameter declarator: may be either, but after a type name does
not redeclare a typedef name as an identifier if it can
alternatively be interpreted as a typedef name; see DR#009,
@@ -1043,7 +1043,7 @@ typedef enum c_dtr_syn {
abstract declarators rather than involving redundant parentheses;
the same applies with attributes inside the parentheses before
"T". */
- C_DTR_PARM
+ C_DTR_PARM = 4
} c_dtr_syn;
static void c_parser_external_declaration (c_parser *);
@@ -1058,10 +1058,10 @@ static struct c_typespec c_parser_enum_s
static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
static tree c_parser_struct_declaration (c_parser *);
static struct c_typespec c_parser_typeof_specifier (c_parser *);
-static struct c_declarator *c_parser_declarator (c_parser *, bool, c_dtr_syn,
+static struct c_declarator *c_parser_declarator (c_parser *, bool, int,
bool *);
static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
- c_dtr_syn, bool *);
+ int, bool *);
static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
bool,
struct c_declarator *);
@@ -2516,8 +2516,6 @@ c_parser_struct_declaration (c_parser *p
parser->error = false;
return NULL_TREE;
}
- if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
- return NULL_TREE;
pending_xref_error ();
prefix_attrs = specs->attrs;
@@ -2526,7 +2524,9 @@ c_parser_struct_declaration (c_parser *p
decls = NULL_TREE;
while (true)
{
- /* Declaring one or more declarators or un-named bit-fields. */
+ /* Declaring one or more declarators or un-named bit-fields. The
+ identifier in a declarator is optional, since we could have an
+ unnamed struct. */
struct c_declarator *declarator;
bool dummy = false;
if (c_parser_next_token_is (parser, CPP_COLON))
@@ -2534,7 +2534,7 @@ c_parser_struct_declaration (c_parser *p
else
declarator = c_parser_declarator (parser,
specs->typespec_kind != ctsk_none,
- C_DTR_NORMAL, &dummy);
+ C_DTR_NORMAL|C_DTR_ABSTRACT, &dummy);
if (declarator == NULL)
{
c_parser_skip_to_end_of_block_or_statement (parser);
@@ -2558,10 +2558,13 @@ c_parser_struct_declaration (c_parser *p
postfix_attrs = c_parser_attributes (parser);
d = grokfield (c_parser_peek_token (parser)->location,
declarator, specs, width, &all_prefix_attrs);
- decl_attributes (&d, chainon (postfix_attrs,
- all_prefix_attrs), 0);
- DECL_CHAIN (d) = decls;
- decls = d;
+ if (d)
+ {
+ decl_attributes (&d, chainon (postfix_attrs,
+ all_prefix_attrs), 0);
+ DECL_CHAIN (d) = decls;
+ decls = d;
+ }
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
all_prefix_attrs = chainon (c_parser_attributes (parser),
prefix_attrs);
@@ -2734,7 +2737,7 @@ c_parser_typeof_specifier (c_parser *par
an abstract declarator, although not part of the formal syntax. */
static struct c_declarator *
-c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
+c_parser_declarator (c_parser *parser, bool type_seen_p, int kind,
bool *seen_id)
{
/* Parse any initial pointer part. */
@@ -2759,7 +2762,7 @@ c_parser_declarator (c_parser *parser, b
as c_parser_declarator. */
static struct c_declarator *
-c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
+c_parser_direct_declarator (c_parser *parser, bool type_seen_p, int kind,
bool *seen_id)
{
/* The direct declarator must start with an identifier (possibly
@@ -2796,7 +2799,7 @@ c_parser_direct_declarator (c_parser *pa
??? Also following the old parser, typedef names may be
redeclared in declarators, but not Objective-C class names. */
- if (kind != C_DTR_ABSTRACT
+ if ((kind & ~C_DTR_ABSTRACT)
&& c_parser_next_token_is (parser, CPP_NAME)
&& ((type_seen_p
&& (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
@@ -2811,7 +2814,7 @@ c_parser_direct_declarator (c_parser *pa
return c_parser_direct_declarator_inner (parser, *seen_id, inner);
}
- if (kind != C_DTR_NORMAL
+ if ((kind & ~C_DTR_NORMAL)
&& c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
{
struct c_declarator *inner = build_id_declarator (NULL_TREE);
@@ -2827,13 +2830,12 @@ c_parser_direct_declarator (c_parser *pa
struct c_declarator *inner;
c_parser_consume_token (parser);
attrs = c_parser_attributes (parser);
- if (kind != C_DTR_NORMAL
+ if ((kind & ~C_DTR_NORMAL)
&& (c_parser_next_token_starts_declspecs (parser)
|| c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
{
struct c_arg_info *args
- = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
- attrs);
+ = c_parser_parms_declarator (parser, false, attrs);
if (args == NULL)
return NULL;
else
@@ -2866,13 +2868,13 @@ c_parser_direct_declarator (c_parser *pa
}
else
{
- if (kind == C_DTR_NORMAL)
+ if (kind & ~C_DTR_NORMAL)
+ return build_id_declarator (NULL_TREE);
+ else
{
c_parser_error (parser, "expected identifier or %<(%>");
return NULL;
}
- else
- return build_id_declarator (NULL_TREE);
}
}