diff options
| author | Linus Torvalds <torvalds@penguin.transmeta.com> | 2003-04-09 14:23:20 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:00:24 -0700 |
| commit | ce96e2585847e1f1482d55d49b14574b3af47cf3 (patch) | |
| tree | 1b9bd1ef2330f63c304de91be11270b4008d0fd9 | |
| parent | c5dd7c8e714f9264e95dd9e376e4bba4c600c9f2 (diff) | |
| download | sparse-dev-ce96e2585847e1f1482d55d49b14574b3af47cf3.tar.gz | |
Show iterators and goto's properly as pseudo-assembler.
| -rw-r--r-- | parse.c | 5 | ||||
| -rw-r--r-- | show-parse.c | 76 | ||||
| -rw-r--r-- | symbol.c | 4 | ||||
| -rw-r--r-- | symbol.h | 4 |
4 files changed, 47 insertions, 42 deletions
@@ -631,9 +631,10 @@ struct token *statement(struct token *token, struct statement **tree) return expression_statement(token->next, &stmt->expression); } if (token->ident == &break_ident || token->ident == &continue_ident) { + struct symbol *target = lookup_symbol(token->ident, NS_ITERATOR); stmt->type = STMT_GOTO; - stmt->goto_label = lookup_symbol(token->ident, NS_ITERATOR); - if (!stmt->goto_label) + stmt->goto_label = target; + if (!target) warn(stmt->pos, "break/continue not in iterator scope"); return expect(token->next, ';', "at end of statement"); } diff --git a/show-parse.c b/show-parse.c index 1437f374..343cc38a 100644 --- a/show-parse.c +++ b/show-parse.c @@ -328,6 +328,12 @@ static int show_return_stmt(struct statement *stmt) static int show_symbol_init(struct symbol *sym); +static int new_label(void) +{ + static int label = 0; + return ++label; +} + /* * Print out a statement */ @@ -393,43 +399,38 @@ int show_statement(struct statement *stmt) struct statement *statement = stmt->iterator_statement; struct statement *post_statement = stmt->iterator_post_statement; struct expression *post_condition = stmt->iterator_post_condition; - - /* - * THIS IS ONLY APPROXIMATE! - * - * Real iterators are more generic than - * any of for/while/do-while, and can't - * be printed out as C without goto's - */ - if (post_statement || !post_condition) { - printf("\tfor ( "); - show_statement(pre_statement); - printf(" ; "); - show_expression(pre_condition); - printf(" ; "); - show_statement(post_statement); - printf(" )\n"); - show_statement(statement); - } else if (pre_condition) { - if (pre_statement) { - show_statement(pre_statement); - printf(";\n"); + int val, loop_top = 0, loop_bottom = 0; + + show_statement(pre_statement); + if (pre_condition) { + if (pre_condition->type == EXPR_VALUE) { + if (!pre_condition->value) + break; + pre_condition = NULL; + } else { + loop_bottom = new_label(); + val = show_expression(pre_condition); + printf("\tje v%d, .L%d\n", val, loop_bottom); } - printf("\twhile ("); - show_expression(pre_condition); - printf(")\n"); - show_statement(statement); + } + if (post_condition->type != EXPR_VALUE || post_condition->value) + loop_top = new_label(); + printf(".L%d:\n", loop_top); + show_statement(statement); + if (stmt->cont_symbol->used) + printf(".L%p:\n", stmt->cont_symbol); + show_statement(post_statement); + if (post_condition->type == EXPR_VALUE) { + if (post_condition->value) + printf("\tjmp .L%d\n", loop_top); } else { - if (pre_statement) { - show_statement(pre_statement); - printf(";\n"); - } - printf("\tdo\n"); - show_statement(statement); - printf("\twhile ("); - show_expression(post_condition); - printf(")"); + val = show_expression(post_condition); + printf("\tjne v%d, .L%d\n", val, loop_top); } + if (stmt->break_symbol->used) + printf(".L%p:\n", stmt->break_symbol); + if (pre_condition) + printf(".L%d:\n", loop_bottom); break; } case STMT_NONE: @@ -444,11 +445,10 @@ int show_statement(struct statement *stmt) case STMT_GOTO: if (stmt->goto_expression) { - printf("\tgoto *"); - show_expression(stmt->goto_expression); + int val = show_expression(stmt->goto_expression); + printf("\tgoto *v%d\n", val); } else { - printf("\tgoto "); - show_symbol(stmt->goto_label); + printf("\tgoto .L%p\n", stmt->goto_label); } break; case STMT_ASM: @@ -41,8 +41,10 @@ struct symbol *lookup_symbol(struct ident *ident, enum namespace ns) struct symbol *sym; for (sym = ident->symbols; sym; sym = sym->next_id) { - if (sym->namespace == ns) + if (sym->namespace == ns) { + sym->used = 1; return sym; + } } return sym; } @@ -74,7 +74,9 @@ struct symbol { unsigned int bit_offset:8, fieldwidth:8, arg_count:10, - variadic:1; + variadic:1, + used:1, + initialized:1; int array_size; struct ctype ctype; struct symbol_list *arguments; |
