X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=parser.c;h=500c1adf3faf9b6b3caa2eacb056bae956b3bccd;hb=5834e994bee47cffac93efca7bcc9551c7c3efa6;hp=be04d23e3ddca9b95f89fcaff48706f8ac0cb28f;hpb=9edec0d8ecee7c0c05638bac31349ae805b597ad;p=cparser diff --git a/parser.c b/parser.c index be04d23..500c1ad 100644 --- a/parser.c +++ b/parser.c @@ -1331,6 +1331,8 @@ static attribute_t *parse_attributes(attribute_t *first) switch (token.type) { case T___attribute__: attribute = parse_attribute_gnu(); + if (attribute == NULL) + continue; break; case T_asm: @@ -3640,25 +3642,44 @@ ptr_operator_end: ; } next_token(); break; - case '(': - /* §6.7.6:2 footnote 126: Empty parentheses in a type name are - * interpreted as ``function with no parameter specification'', rather - * than redundant parentheses around the omitted identifier. */ - if (look_ahead(1)->type != ')') { - next_token(); - add_anchor_token(')'); - inner_types = parse_inner_declarator(env); - if (inner_types != NULL) { - /* All later declarators only modify the return type */ - env->must_be_abstract = true; - } - rem_anchor_token(')'); - expect(')', end_error); - } else if (!env->may_be_abstract) { - errorf(HERE, "declarator must have a name"); - goto error_out; + + case '(': { + /* Parenthesized declarator or function declarator? */ + token_t const *const la1 = look_ahead(1); + switch (la1->type) { + case T_IDENTIFIER: + if (is_typedef_symbol(la1->symbol)) { + case ')': + /* §6.7.6:2 footnote 126: Empty parentheses in a type name are + * interpreted as ``function with no parameter specification'', rather + * than redundant parentheses around the omitted identifier. */ + default: + /* Function declarator. */ + if (!env->may_be_abstract) { + errorf(HERE, "function declarator must have a name"); + goto error_out; + } + } else { + case '(': + case '*': + case '[': + case T___attribute__: /* FIXME __attribute__ might also introduce a parameter of a function declarator. */ + /* Paranthesized declarator. */ + next_token(); + add_anchor_token(')'); + inner_types = parse_inner_declarator(env); + if (inner_types != NULL) { + /* All later declarators only modify the return type */ + env->must_be_abstract = true; + } + rem_anchor_token(')'); + expect(')', end_error); + } + break; } break; + } + default: if (env->may_be_abstract) break; @@ -6191,7 +6212,7 @@ static expression_t *parse_character_constant(void) literal->literal.value = token.literal; size_t len = literal->literal.value.size; - if (len != 1) { + if (len > 1) { if (!GNU_MODE && !(c_mode & _C99)) { errorf(HERE, "more than 1 character in character constant"); } else if (warning.multichar) { @@ -6215,7 +6236,7 @@ static expression_t *parse_wide_character_constant(void) literal->literal.value = token.literal; size_t len = wstrlen(&literal->literal.value); - if (len != 1) { + if (len > 1) { warningf(HERE, "multi-character character constant"); }