diff options
-rw-r--r-- | evaluate.c | 8 | ||||
-rw-r--r-- | parse.c | 23 | ||||
-rw-r--r-- | parse.h | 1 |
3 files changed, 32 insertions, 0 deletions
@@ -3151,6 +3151,7 @@ static void verify_input_constraint(struct expression *expr, const char *constra static void evaluate_asm_statement(struct statement *stmt) { struct expression *expr; + struct symbol *sym; int state; expr = stmt->asm_string; @@ -3227,6 +3228,13 @@ static void evaluate_asm_statement(struct statement *stmt) continue; expression_error(expr, "asm clobber is not a string"); } END_FOR_EACH_PTR(expr); + + FOR_EACH_PTR(stmt->asm_labels, sym) { + if (!sym || sym->type != SYM_LABEL) { + sparse_error(stmt->pos, "bad asm label"); + return; + } + } END_FOR_EACH_PTR(sym); } static void evaluate_case_statement(struct statement *stmt) @@ -1891,12 +1891,33 @@ static struct token *parse_asm_clobbers(struct token *token, struct statement *s return token; } +static struct token *parse_asm_labels(struct token *token, struct statement *stmt, + struct symbol_list **labels) +{ + struct symbol *label; + + do { + token = token->next; /* skip ':' and ',' */ + if (token_type(token) != TOKEN_IDENT) + return token; + label = label_symbol(token); + add_symbol(labels, label); + token = token->next; + } while (match_op(token, ',')); + return token; +} + static struct token *parse_asm_statement(struct token *token, struct statement *stmt) { + int is_goto = 0; + token = token->next; stmt->type = STMT_ASM; if (match_idents(token, &__volatile___ident, &__volatile_ident, &volatile_ident, NULL)) { token = token->next; + } else if (match_idents(token, &goto_ident, NULL)) { + is_goto = 1; + token = token->next; } token = expect(token, '(', "after asm"); token = parse_expression(token, &stmt->asm_string); @@ -1906,6 +1927,8 @@ static struct token *parse_asm_statement(struct token *token, struct statement * token = parse_asm_operands(token, stmt, &stmt->asm_inputs); if (match_op(token, ':')) token = parse_asm_clobbers(token, stmt, &stmt->asm_clobbers); + if (is_goto && match_op(token, ':')) + token = parse_asm_labels(token, stmt, &stmt->asm_labels); token = expect(token, ')', "after asm"); return expect(token, ';', "at end of asm-statement"); } @@ -106,6 +106,7 @@ struct statement { struct expression_list *asm_outputs; struct expression_list *asm_inputs; struct expression_list *asm_clobbers; + struct symbol_list *asm_labels; }; struct /* range */ { struct expression *range_expression; |