Do not truncate the existing attribute list if a __declspec has no arguments.
[cparser] / parser.c
index f128dd5..8d29162 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -546,17 +546,6 @@ static void rem_anchor_token(int token_kind)
        --token_anchor_set[token_kind];
 }
 
-/**
- * Return true if the token type of the current token is
- * in the anchor set.
- */
-static bool at_anchor(void)
-{
-       if (token.kind < 0)
-               return false;
-       return token_anchor_set[token.kind];
-}
-
 /**
  * Eat tokens until a matching token type is found.
  */
@@ -1136,11 +1125,7 @@ static attribute_argument_t *parse_attribute_arguments(void)
                anchor  = &argument->next;
        } while (next_if(','));
        expect(')', end_error);
-
-       return first;
-
 end_error:
-       /* TODO... */
        return first;
 }
 
@@ -2674,32 +2659,27 @@ static attribute_t *parse_microsoft_extended_decl_modifier(attribute_t *first)
        eat(T__declspec);
 
        expect('(', end_error);
+       if (token.kind != ')') {
+               add_anchor_token(')');
 
-       if (next_if(')'))
-               return NULL;
-
-       add_anchor_token(')');
-
-       attribute_t **anchor = &first;
-       do {
-               while (*anchor != NULL)
-                       anchor = &(*anchor)->next;
+               attribute_t **anchor = &first;
+               do {
+                       while (*anchor != NULL)
+                               anchor = &(*anchor)->next;
 
-               attribute_t *attribute
-                       = parse_microsoft_extended_decl_modifier_single();
-               if (attribute == NULL)
-                       goto end_error;
+                       attribute_t *attribute
+                               = parse_microsoft_extended_decl_modifier_single();
+                       if (attribute == NULL)
+                               break;
 
-               *anchor = attribute;
-               anchor  = &attribute->next;
-       } while (next_if(','));
+                       *anchor = attribute;
+                       anchor  = &attribute->next;
+               } while (next_if(','));
 
-       rem_anchor_token(')');
+               rem_anchor_token(')');
+       }
        expect(')', end_error);
-       return first;
-
 end_error:
-       rem_anchor_token(')');
        return first;
 }
 
@@ -9048,6 +9028,7 @@ end_of_asm:
        expect(')', end_error);
        expect(';', end_error);
 
+end_error:
        if (asm_statement->outputs == NULL) {
                /* GCC: An 'asm' instruction without any output operands will be treated
                 * identically to a volatile 'asm' instruction. */
@@ -9055,8 +9036,6 @@ end_of_asm:
        }
 
        return statement;
-end_error:
-       return create_error_statement();
 }
 
 static statement_t *parse_label_inner_statement(statement_t const *const label, char const *const label_kind)
@@ -9483,19 +9462,18 @@ static statement_t *parse_do(void)
        statement->do_while.body = parse_loop_body(statement);
        rem_anchor_token(T_while);
 
-       expect(T_while, end_error);
+       expect(T_while, end_error0);
+end_error0:;
        expression_t *const cond = parse_condition();
        statement->do_while.condition = cond;
        /* ยง6.8.5:2    The controlling expression of an iteration statement shall
         *             have scalar type. */
        semantic_condition(cond, "condition of 'do-while'-statement");
-       expect(';', end_error);
+       expect(';', end_error1);
+end_error1:
 
        POP_PARENT();
        return statement;
-end_error:
-       POP_PARENT();
-       return create_error_statement();
 }
 
 /**
@@ -9507,12 +9485,12 @@ static statement_t *parse_for(void)
 
        eat(T_for);
 
-       expect('(', end_error1);
-       add_anchor_token(')');
-
        PUSH_PARENT(statement);
        PUSH_SCOPE(&statement->fors.scope);
 
+       expect('(', end_error1);
+       add_anchor_token(')');
+
        PUSH_EXTENSION();
 
        if (next_if(';')) {
@@ -9527,7 +9505,8 @@ static statement_t *parse_for(void)
                        warningf(WARN_UNUSED_VALUE, &init->base.source_position, "initialisation of 'for'-statement has no effect");
                }
                rem_anchor_token(';');
-               expect(';', end_error2);
+               expect(';', end_error3);
+end_error3:;
        }
 
        POP_EXTENSION();
@@ -9543,6 +9522,7 @@ static statement_t *parse_for(void)
                rem_anchor_token(';');
        }
        expect(';', end_error2);
+end_error2:
        if (token.kind != ')') {
                expression_t *const step = parse_expression();
                statement->fors.step = step;
@@ -9551,22 +9531,14 @@ static statement_t *parse_for(void)
                        warningf(WARN_UNUSED_VALUE, &step->base.source_position, "step of 'for'-statement has no effect");
                }
        }
-       expect(')', end_error2);
        rem_anchor_token(')');
+       expect(')', end_error1);
+end_error1:
        statement->fors.body = parse_loop_body(statement);
 
        POP_SCOPE();
        POP_PARENT();
        return statement;
-
-end_error2:
-       POP_PARENT();
-       rem_anchor_token(')');
-       POP_SCOPE();
-       /* fallthrough */
-
-end_error1:
-       return create_error_statement();
 }
 
 /**
@@ -10181,18 +10153,10 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
 
        statement_t **anchor            = &statement->compound.statements;
        bool          only_decls_so_far = true;
-       while (token.kind != '}') {
-               if (token.kind == T_EOF) {
-                       errorf(&statement->base.source_position,
-                              "EOF while parsing compound statement");
-                       break;
-               }
+       while (token.kind != '}' && token.kind != T_EOF) {
                statement_t *sub_statement = intern_parse_statement();
                if (sub_statement->kind == STATEMENT_ERROR) {
-                       /* an error occurred. if we are at an anchor, return */
-                       if (at_anchor())
-                               goto end_error;
-                       continue;
+                       break;
                }
 
                if (sub_statement->kind != STATEMENT_DECLARATION) {
@@ -10203,13 +10167,10 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
                }
 
                *anchor = sub_statement;
-
-               while (sub_statement->base.next != NULL)
-                       sub_statement = sub_statement->base.next;
-
-               anchor = &sub_statement->base.next;
+               anchor  = &sub_statement->base.next;
        }
-       next_token();
+       expect('}', end_error);
+end_error:
 
        /* look over all statements again to produce no effect warnings */
        if (is_warn_on(WARN_UNUSED_VALUE)) {
@@ -10229,7 +10190,6 @@ static statement_t *parse_compound_statement(bool inside_expression_statement)
                }
        }
 
-end_error:
        rem_anchor_token(T_while);
        rem_anchor_token(T_wchar_t);
        rem_anchor_token(T_volatile);