Provide the specific error message about a label at the end of a compound statement...
authorChristoph Mallon <christoph.mallon@gmx.de>
Sat, 5 Feb 2011 09:03:51 +0000 (09:03 +0000)
committerChristoph Mallon <christoph.mallon@gmx.de>
Sat, 5 Feb 2011 09:03:51 +0000 (09:03 +0000)
[r28304]

parser.c

index 8b14bbf..7dca240 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -9271,6 +9271,36 @@ end_error:
        return create_invalid_statement();
 }
 
+static statement_t *parse_label_inner_statement(char const *const label, bool const eat_empty_stmt)
+{
+       statement_t *inner_stmt;
+       switch (token.type) {
+               case '}':
+                       errorf(HERE, "%s at end of compound statement", label);
+                       inner_stmt = create_invalid_statement();
+                       break;
+
+               case ';':
+                       if (eat_empty_stmt) {
+                               /* Eat an empty statement here, to avoid the warning about an empty
+                                * statement after a label.  label:; is commonly used to have a label
+                                * before a closing brace. */
+                               inner_stmt = create_empty_statement();
+                               next_token();
+                               break;
+                       }
+                       /* FALLTHROUGH */
+
+               default:
+                       inner_stmt = parse_statement();
+                       if (inner_stmt->kind == STATEMENT_DECLARATION) {
+                               errorf(&inner_stmt->base.source_position, "declaration after %s", label);
+                       }
+                       break;
+       }
+       return inner_stmt;
+}
+
 /**
  * Parse a case statement.
  */
@@ -9353,11 +9383,7 @@ end_error:
                errorf(pos, "case label not within a switch statement");
        }
 
-       statement_t *const inner_stmt = parse_statement();
-       statement->case_label.statement = inner_stmt;
-       if (inner_stmt->kind == STATEMENT_DECLARATION) {
-               errorf(&inner_stmt->base.source_position, "declaration after case label");
-       }
+       statement->case_label.statement = parse_label_inner_statement("case label", false);
 
        POP_PARENT;
        return statement;
@@ -9398,11 +9424,7 @@ end_error:
                        "'default' label not within a switch statement");
        }
 
-       statement_t *const inner_stmt = parse_statement();
-       statement->case_label.statement = inner_stmt;
-       if (inner_stmt->kind == STATEMENT_DECLARATION) {
-               errorf(&inner_stmt->base.source_position, "declaration after default label");
-       }
+       statement->case_label.statement = parse_label_inner_statement("default label", false);
 
        POP_PARENT;
        return statement;
@@ -9437,22 +9459,7 @@ static statement_t *parse_label_statement(void)
 
        eat(':');
 
-       if (token.type == '}') {
-               errorf(HERE, "label at end of compound statement");
-               statement->label.statement = create_invalid_statement();
-       } else if (token.type == ';') {
-               /* Eat an empty statement here, to avoid the warning about an empty
-                * statement after a label.  label:; is commonly used to have a label
-                * before a closing brace. */
-               statement->label.statement = create_empty_statement();
-               next_token();
-       } else {
-               statement_t *const inner_stmt = parse_statement();
-               statement->label.statement = inner_stmt;
-               if (inner_stmt->kind == STATEMENT_DECLARATION) {
-                       errorf(&inner_stmt->base.source_position, "declaration after label");
-               }
-       }
+       statement->label.statement = parse_label_inner_statement("label", true);
 
        /* remember the labels in a list for later checking */
        *label_anchor = &statement->label;