replaced the different statement types by one union type saving a lot of casts (and...
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sun, 25 Nov 2007 19:35:27 +0000 (19:35 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Sun, 25 Nov 2007 19:35:27 +0000 (19:35 +0000)
[r18530]

ast.c
ast.h
ast2firm.c
ast_t.h
parser.c

diff --git a/ast.c b/ast.c
index c26b8a9..9bc088f 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -299,12 +299,12 @@ void print_expression(const expression_t *expression)
        }
 }
 
-static void print_compound_statement(const compound_statement_t *block)
+static void print_compound_statement(const statement_t *block)
 {
        fputs("{\n", out);
        indent++;
 
-       statement_t *statement = block->statements;
+       statement_t *statement = block->v.compound_stmt.statements;
        while(statement != NULL) {
                print_indent();
                print_statement(statement);
@@ -316,79 +316,78 @@ static void print_compound_statement(const compound_statement_t *block)
        fputs("}\n", out);
 }
 
-static void print_return_statement(const return_statement_t *statement)
+static void print_return_statement(const statement_t *statement)
 {
        fprintf(out, "return ");
-       if(statement->return_value != NULL)
-               print_expression(statement->return_value);
+       if(statement->v.return_value != NULL)
+               print_expression(statement->v.return_value);
        fputs(";\n", out);
 }
 
-static void print_expression_statement(const expression_statement_t *statement)
+static void print_expression_statement(const statement_t *statement)
 {
-       print_expression(statement->expression);
+       print_expression(statement->v.expression);
        fputs(";\n", out);
 }
 
-static void print_goto_statement(const goto_statement_t *statement)
+static void print_goto_statement(const statement_t *statement)
 {
        fprintf(out, "goto ");
-       fputs(statement->label->symbol->string, out);
-       fprintf(stderr, "(%p)", (void*) statement->label);
+       fputs(statement->v.goto_label->symbol->string, out);
+       fprintf(stderr, "(%p)", (void*) statement->v.goto_label);
        fputs(";\n", out);
 }
 
-static void print_label_statement(const label_statement_t *statement)
+static void print_label_statement(const statement_t *statement)
 {
-       fprintf(stderr, "(%p)", (void*) statement->label);
-       fprintf(out, "%s:\n", statement->label->symbol->string);
-       if(statement->label_statement != NULL) {
-               print_statement(statement->label_statement);
+       fprintf(stderr, "(%p)", (void*) statement->v.label_stmt.label);
+       fprintf(out, "%s:\n", statement->v.label_stmt.label->symbol->string);
+       if(statement->v.label_stmt.label_statement != NULL) {
+               print_statement(statement->v.label_stmt.label_statement);
        }
 }
 
-static void print_if_statement(const if_statement_t *statement)
+static void print_if_statement(const statement_t *statement)
 {
        fputs("if(", out);
-       print_expression(statement->condition);
+       print_expression(statement->v.if_stmt.condition);
        fputs(") ", out);
-       if(statement->true_statement != NULL) {
-               print_statement(statement->true_statement);
+       if(statement->v.if_stmt.true_statement != NULL) {
+               print_statement(statement->v.if_stmt.true_statement);
        }
 
-       if(statement->false_statement != NULL) {
+       if(statement->v.if_stmt.false_statement != NULL) {
                print_indent();
                fputs("else ", out);
-               print_statement(statement->false_statement);
+               print_statement(statement->v.if_stmt.false_statement);
        }
 }
 
-static void print_switch_statement(const switch_statement_t *statement)
+static void print_switch_statement(const statement_t *statement)
 {
        fputs("switch(", out);
-       print_expression(statement->expression);
+       print_expression(statement->v.switch_stmt.expression);
        fputs(") ", out);
-       print_statement(statement->body);
+       print_statement(statement->v.switch_stmt.body);
 }
 
-static void print_case_label(const case_label_statement_t *statement)
+static void print_case_label(const statement_t *statement)
 {
-       if(statement->expression == NULL) {
+       if(statement->v.case_label_stmt.expression == NULL) {
                fputs("default:\n", out);
        } else {
                fputs("case ", out);
-               print_expression(statement->expression);
+               print_expression(statement->v.case_label_stmt.expression);
                fputs(":\n", out);
        }
-       print_statement(statement->label_statement);
+       print_statement(statement->v.case_label_stmt.label_statement);
 }
 
-static void print_declaration_statement(
-               const declaration_statement_t *statement)
+static void print_declaration_statement(const statement_t *statement)
 {
        int first = 1;
-       declaration_t *declaration = statement->declarations_begin;
-       for( ; declaration != statement->declarations_end->next;
+       declaration_t *declaration = statement->v.declaration_stmt.begin;
+       for( ; declaration != statement->v.declaration_stmt.end->next;
               declaration = declaration->next) {
                if(!first) {
                        print_indent();
@@ -400,68 +399,68 @@ static void print_declaration_statement(
        }
 }
 
-static void print_while_statement(const while_statement_t *statement)
+static void print_while_statement(const statement_t *statement)
 {
        fputs("while(", out);
-       print_expression(statement->condition);
+       print_expression(statement->v.while_stmt.condition);
        fputs(") ", out);
-       print_statement(statement->body);
+       print_statement(statement->v.while_stmt.body);
 }
 
-static void print_do_while_statement(const do_while_statement_t *statement)
+static void print_do_while_statement(const statement_t *statement)
 {
        fputs("do ", out);
-       print_statement(statement->body);
+       print_statement(statement->v.while_stmt.body);
        print_indent();
        fputs("while(", out);
-       print_expression(statement->condition);
+       print_expression(statement->v.while_stmt.condition);
        fputs(");\n", out);
 }
 
-static void print_for_statement(const for_statement_t *statement)
+static void print_for_statement(const statement_t *statement)
 {
        fputs("for(", out);
-       if(statement->context.declarations != NULL) {
-               assert(statement->initialisation == NULL);
-               print_declaration(statement->context.declarations);
-               if(statement->context.declarations->next != NULL) {
+       if(statement->v.for_stmt.context.declarations != NULL) {
+               assert(statement->v.for_stmt.initialisation == NULL);
+               print_declaration(statement->v.for_stmt.context.declarations);
+               if(statement->v.for_stmt.context.declarations->next != NULL) {
                        panic("multiple declarations in for statement not supported yet");
                }
                fputc(' ', out);
        } else {
-               if(statement->initialisation) {
-                       print_expression(statement->initialisation);
+               if(statement->v.for_stmt.initialisation) {
+                       print_expression(statement->v.for_stmt.initialisation);
                }
                fputs("; ", out);
        }
-       if(statement->condition != NULL) {
-               print_expression(statement->condition);
+       if(statement->v.for_stmt.condition != NULL) {
+               print_expression(statement->v.for_stmt.condition);
        }
        fputs("; ", out);
-       if(statement->step != NULL) {
-               print_expression(statement->step);
+       if(statement->v.for_stmt.step != NULL) {
+               print_expression(statement->v.for_stmt.step);
        }
        fputs(")", out);
-       print_statement(statement->body);
+       print_statement(statement->v.for_stmt.body);
 }
 
 void print_statement(const statement_t *statement)
 {
        switch(statement->type) {
        case STATEMENT_COMPOUND:
-               print_compound_statement((const compound_statement_t*) statement);
+               print_compound_statement(statement);
                break;
        case STATEMENT_RETURN:
-               print_return_statement((const return_statement_t*) statement);
+               print_return_statement(statement);
                break;
        case STATEMENT_EXPRESSION:
-               print_expression_statement((const expression_statement_t*) statement);
+               print_expression_statement(statement);
                break;
        case STATEMENT_LABEL:
-               print_label_statement((const label_statement_t*) statement);
+               print_label_statement(statement);
                break;
        case STATEMENT_GOTO:
-               print_goto_statement((const goto_statement_t*) statement);
+               print_goto_statement(statement);
                break;
        case STATEMENT_CONTINUE:
                fputs("continue;\n", out);
@@ -470,25 +469,25 @@ void print_statement(const statement_t *statement)
                fputs("break;\n", out);
                break;
        case STATEMENT_IF:
-               print_if_statement((const if_statement_t*) statement);
+               print_if_statement(statement);
                break;
        case STATEMENT_SWITCH:
-               print_switch_statement((const switch_statement_t*) statement);
+               print_switch_statement(statement);
                break;
        case STATEMENT_CASE_LABEL:
-               print_case_label((const case_label_statement_t*) statement);
+               print_case_label(statement);
                break;
        case STATEMENT_DECLARATION:
-               print_declaration_statement((const declaration_statement_t*) statement);
+               print_declaration_statement(statement);
                break;
        case STATEMENT_WHILE:
-               print_while_statement((const while_statement_t*) statement);
+               print_while_statement(statement);
                break;
        case STATEMENT_DO_WHILE:
-               print_do_while_statement((const do_while_statement_t*) statement);
+               print_do_while_statement(statement);
                break;
        case STATEMENT_FOR:
-               print_for_statement((const for_statement_t*) statement);
+               print_for_statement(statement);
                break;
        case STATEMENT_INVALID:
                fprintf(out, "*invalid statement*");
diff --git a/ast.h b/ast.h
index 1b1f8d6..76c0b21 100644 (file)
--- a/ast.h
+++ b/ast.h
@@ -32,18 +32,6 @@ typedef struct initializer_t                initializer_t;
 typedef struct declaration_t                declaration_t;
 
 typedef struct statement_t                  statement_t;
-typedef struct compound_statement_t         compound_statement_t;
-typedef struct return_statement_t           return_statement_t;
-typedef struct if_statement_t               if_statement_t;
-typedef struct switch_statement_t           switch_statement_t;
-typedef struct declaration_statement_t      declaration_statement_t;
-typedef struct expression_statement_t       expression_statement_t;
-typedef struct goto_statement_t             goto_statement_t;
-typedef struct label_statement_t            label_statement_t;
-typedef struct case_label_statement_t       case_label_statement_t;
-typedef struct while_statement_t            while_statement_t;
-typedef struct do_while_statement_t         do_while_statement_t;
-typedef struct for_statement_t              for_statement_t;
 
 typedef struct translation_unit_t           translation_unit_t;
 
index 1e0f72b..cf9eb47 100644 (file)
@@ -829,7 +829,7 @@ static ir_node *call_expression_to_firm(const call_expression_t *call)
 }
 
 static void statement_to_firm(statement_t *statement);
-static ir_node *compound_statement_to_firm(compound_statement_t *compound);
+static ir_node *compound_statement_to_firm(statement_t *compound);
 
 static ir_node *expression_to_addr(const expression_t *expression);
 static void create_condition_evaluation(const expression_t *expression,
@@ -1550,7 +1550,7 @@ static ir_node *statement_expression_to_firm(const statement_expression_t *expr)
        statement_t *statement = expr->statement;
 
        assert(statement->type == STATEMENT_COMPOUND);
-       return compound_statement_to_firm((compound_statement_t*) statement);
+       return compound_statement_to_firm(statement);
 }
 
 static ir_node *dereference_addr(const unary_expression_t *const expression)
@@ -1712,16 +1712,16 @@ static void create_condition_evaluation(const expression_t *expression,
 }
 
 
-static void return_statement_to_firm(return_statement_t *statement)
+static void return_statement_to_firm(statement_t *statement)
 {
        if(get_cur_block() == NULL)
                return;
 
-       dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
+       dbg_info *dbgi = get_dbg_info(&statement->source_position);
        ir_node  *ret;
 
-       if(statement->return_value != NULL) {
-               ir_node *retval = expression_to_firm(statement->return_value);
+       if(statement->v.return_value != NULL) {
+               ir_node *retval = expression_to_firm(statement->v.return_value);
                ir_node *in[1];
 
                in[0] = retval;
@@ -1735,24 +1735,23 @@ static void return_statement_to_firm(return_statement_t *statement)
        set_cur_block(NULL);
 }
 
-static ir_node *expression_statement_to_firm(expression_statement_t *statement)
+static ir_node *expression_statement_to_firm(statement_t *statement)
 {
        if(get_cur_block() == NULL)
                return NULL;
 
-       return expression_to_firm(statement->expression);
+       return expression_to_firm(statement->v.expression);
 }
 
-static ir_node *compound_statement_to_firm(compound_statement_t *compound)
+static ir_node *compound_statement_to_firm(statement_t *compound)
 {
        ir_node     *result    = NULL;
-       statement_t *statement = compound->statements;
+       statement_t *statement = compound->v.compound_stmt.statements;
        for( ; statement != NULL; statement = statement->next) {
                //context2firm(&statement->context);
 
                if(statement->next == NULL && statement->type == STATEMENT_EXPRESSION) {
-                       result = expression_statement_to_firm(
-                                       (expression_statement_t*) statement);
+                       result = expression_statement_to_firm(statement);
                        break;
                }
                statement_to_firm(statement);
@@ -1761,7 +1760,7 @@ static ir_node *compound_statement_to_firm(compound_statement_t *compound)
        return result;
 }
 
-static void if_statement_to_firm(if_statement_t *statement)
+static void if_statement_to_firm(statement_t *statement)
 {
        ir_node *cur_block = get_cur_block();
 
@@ -1769,9 +1768,9 @@ static void if_statement_to_firm(if_statement_t *statement)
 
        /* the true (blocks) */
        ir_node *true_block;
-       if (statement->true_statement != NULL) {
+       if (statement->v.if_stmt.true_statement != NULL) {
                true_block = new_immBlock();
-               statement_to_firm(statement->true_statement);
+               statement_to_firm(statement->v.if_stmt.true_statement);
                if(get_cur_block() != NULL) {
                        ir_node *jmp = new_Jmp();
                        add_immBlock_pred(fallthrough_block, jmp);
@@ -1782,10 +1781,10 @@ static void if_statement_to_firm(if_statement_t *statement)
 
        /* the false (blocks) */
        ir_node *false_block;
-       if(statement->false_statement != NULL) {
+       if(statement->v.if_stmt.false_statement != NULL) {
                false_block = new_immBlock();
 
-               statement_to_firm(statement->false_statement);
+               statement_to_firm(statement->v.if_stmt.false_statement);
                if(get_cur_block() != NULL) {
                        ir_node *jmp = new_Jmp();
                        add_immBlock_pred(fallthrough_block, jmp);
@@ -1797,7 +1796,7 @@ static void if_statement_to_firm(if_statement_t *statement)
        /* create the condition */
        if(cur_block != NULL) {
                set_cur_block(cur_block);
-               create_condition_evaluation(statement->condition, true_block,
+               create_condition_evaluation(statement->v.if_stmt.condition, true_block,
                                            false_block);
        }
 
@@ -1810,7 +1809,7 @@ static void if_statement_to_firm(if_statement_t *statement)
        set_cur_block(fallthrough_block);
 }
 
-static void while_statement_to_firm(while_statement_t *statement)
+static void while_statement_to_firm(statement_t *statement)
 {
        ir_node *jmp = NULL;
        if(get_cur_block() != NULL) {
@@ -1828,14 +1827,14 @@ static void while_statement_to_firm(while_statement_t *statement)
 
        /* the loop body */
        ir_node *body_block;
-       if (statement->body != NULL) {
+       if (statement->v.while_stmt.body != NULL) {
                ir_node *old_continue_label = continue_label;
                ir_node *old_break_label    = break_label;
                continue_label              = header_block;
                break_label                 = false_block;
 
                body_block = new_immBlock();
-               statement_to_firm(statement->body);
+               statement_to_firm(statement->v.while_stmt.body);
 
                assert(continue_label == header_block);
                assert(break_label    == false_block);
@@ -1853,7 +1852,7 @@ static void while_statement_to_firm(while_statement_t *statement)
        /* create the condition */
        set_cur_block(header_block);
 
-       create_condition_evaluation(statement->condition, body_block, false_block);
+       create_condition_evaluation(statement->v.while_stmt.condition, body_block, false_block);
        mature_immBlock(body_block);
        mature_immBlock(false_block);
        mature_immBlock(header_block);
@@ -1861,7 +1860,7 @@ static void while_statement_to_firm(while_statement_t *statement)
        set_cur_block(false_block);
 }
 
-static void do_while_statement_to_firm(do_while_statement_t *statement)
+static void do_while_statement_to_firm(statement_t *statement)
 {
        ir_node *jmp = NULL;
        if(get_cur_block() != NULL) {
@@ -1880,13 +1879,13 @@ static void do_while_statement_to_firm(do_while_statement_t *statement)
                add_immBlock_pred(body_block, jmp);
        }
 
-       if (statement->body != NULL) {
+       if (statement->v.while_stmt.body != NULL) {
                ir_node *old_continue_label = continue_label;
                ir_node *old_break_label    = break_label;
                continue_label              = header_block;
                break_label                 = false_block;
 
-               statement_to_firm(statement->body);
+               statement_to_firm(statement->v.while_stmt.body);
 
                assert(continue_label == header_block);
                assert(break_label    == false_block);
@@ -1908,7 +1907,7 @@ static void do_while_statement_to_firm(do_while_statement_t *statement)
        /* create the condition */
        set_cur_block(header_block);
 
-       create_condition_evaluation(statement->condition, body_block, false_block);
+       create_condition_evaluation(statement->v.while_stmt.condition, body_block, false_block);
        mature_immBlock(body_block);
        mature_immBlock(false_block);
        mature_immBlock(header_block);
@@ -1916,20 +1915,20 @@ static void do_while_statement_to_firm(do_while_statement_t *statement)
        set_cur_block(false_block);
 }
 
-static void for_statement_to_firm(for_statement_t *statement)
+static void for_statement_to_firm(statement_t *statement)
 {
        ir_node *jmp = NULL;
        if (get_cur_block() != NULL) {
-               if(statement->initialisation != NULL) {
-                       expression_to_firm(statement->initialisation);
+               if(statement->v.for_stmt.initialisation != NULL) {
+                       expression_to_firm(statement->v.for_stmt.initialisation);
                }
                jmp = new_Jmp();
        }
 
        /* create the step block */
        ir_node *const step_block = new_immBlock();
-       if (statement->step != NULL) {
-               expression_to_firm(statement->step);
+       if (statement->v.for_stmt.step != NULL) {
+               expression_to_firm(statement->v.for_stmt.step);
        }
        ir_node *const step_jmp = new_Jmp();
 
@@ -1945,14 +1944,14 @@ static void for_statement_to_firm(for_statement_t *statement)
 
        /* the loop body */
        ir_node * body_block;
-       if (statement->body != NULL) {
+       if (statement->v.for_stmt.body != NULL) {
                ir_node *const old_continue_label = continue_label;
                ir_node *const old_break_label    = break_label;
                continue_label = step_block;
                break_label    = false_block;
 
                body_block = new_immBlock();
-               statement_to_firm(statement->body);
+               statement_to_firm(statement->v.for_stmt.body);
 
                assert(continue_label == step_block);
                assert(break_label    == false_block);
@@ -1969,8 +1968,8 @@ static void for_statement_to_firm(for_statement_t *statement)
 
        /* create the condition */
        set_cur_block(header_block);
-       if (statement->condition != NULL) {
-               create_condition_evaluation(statement->condition, body_block,
+       if (statement->v.for_stmt.condition != NULL) {
+               create_condition_evaluation(statement->v.for_stmt.condition, body_block,
                                            false_block);
        } else {
                keep_alive(header_block);
@@ -2312,10 +2311,10 @@ static void create_local_static_variable(declaration_t *declaration)
        current_ir_graph = old_current_ir_graph;
 }
 
-static void declaration_statement_to_firm(declaration_statement_t *statement)
+static void declaration_statement_to_firm(statement_t *statement)
 {
-       declaration_t *declaration = statement->declarations_begin;
-       declaration_t *end         = statement->declarations_end->next;
+       declaration_t *declaration = statement->v.declaration_stmt.begin;
+       declaration_t *end         = statement->v.declaration_stmt.end->next;
        for( ; declaration != end; declaration = declaration->next) {
                type_t *type = declaration->type;
 
@@ -2356,11 +2355,11 @@ static void create_jump_statement(const statement_t *statement,
        set_cur_block(NULL);
 }
 
-static void switch_statement_to_firm(const switch_statement_t *statement)
+static void switch_statement_to_firm(const statement_t *statement)
 {
-       dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
+       dbg_info *dbgi = get_dbg_info(&statement->source_position);
 
-       ir_node *expression  = expression_to_firm(statement->expression);
+       ir_node *expression  = expression_to_firm(statement->v.switch_stmt.expression);
        ir_node *cond        = new_d_Cond(dbgi, expression);
        ir_node *break_block = new_immBlock();
 
@@ -2372,7 +2371,7 @@ static void switch_statement_to_firm(const switch_statement_t *statement)
        current_switch_cond                  = cond;
        break_label                          = break_block;
 
-       statement_to_firm(statement->body);
+       statement_to_firm(statement->v.switch_stmt.body);
 
        if(get_cur_block() != NULL) {
                ir_node *jmp = new_Jmp();
@@ -2403,7 +2402,7 @@ static long fold_constant(const expression_t *expression)
 
        ir_node *cnst = expression_to_firm(expression);
        if(!is_Const(cnst)) {
-               panic("couldn't fold constantl");
+               panic("couldn't fold constant");
        }
        tarval *tv = get_Const_tarval(cnst);
        if(!tarval_is_long(tv)) {
@@ -2416,9 +2415,9 @@ static long fold_constant(const expression_t *expression)
        return res;
 }
 
-static void case_label_to_firm(const case_label_statement_t *statement)
+static void case_label_to_firm(const statement_t *statement)
 {
-       dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
+       dbg_info *dbgi = get_dbg_info(&statement->source_position);
 
        ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
 
@@ -2426,8 +2425,8 @@ static void case_label_to_firm(const case_label_statement_t *statement)
         * node... */
        ir_node *proj;
        set_cur_block(get_nodes_block(current_switch_cond));
-       if(statement->expression) {
-               long pn = fold_constant(statement->expression);
+       if(statement->v.case_label_stmt.expression) {
+               long pn = fold_constant(statement->v.case_label_stmt.expression);
                if(pn == MAGIC_DEFAULT_PN_NUMBER) {
                        /* oops someone detected our cheating... */
                        panic("magic default pn used");
@@ -2446,7 +2445,7 @@ static void case_label_to_firm(const case_label_statement_t *statement)
        add_immBlock_pred(block, proj);
        mature_immBlock(block);
 
-       statement_to_firm(statement->label_statement);
+       statement_to_firm(statement->v.case_label_stmt.label_statement);
 }
 
 static ir_node *get_label_block(declaration_t *label)
@@ -2470,9 +2469,9 @@ static ir_node *get_label_block(declaration_t *label)
        return block;
 }
 
-static void label_to_firm(const label_statement_t *statement)
+static void label_to_firm(const statement_t *statement)
 {
-       ir_node *block = get_label_block(statement->label);
+       ir_node *block = get_label_block(statement->v.label_stmt.label);
 
        if(get_cur_block() != NULL) {
                ir_node *jmp = new_Jmp();
@@ -2482,15 +2481,15 @@ static void label_to_firm(const label_statement_t *statement)
        set_cur_block(block);
        keep_alive(block);
 
-       statement_to_firm(statement->label_statement);
+       statement_to_firm(statement->v.label_stmt.label_statement);
 }
 
-static void goto_to_firm(const goto_statement_t *statement)
+static void goto_to_firm(const statement_t *statement)
 {
        if(get_cur_block() == NULL)
                return;
 
-       ir_node *block = get_label_block(statement->label);
+       ir_node *block = get_label_block(statement->v.goto_label);
        ir_node *jmp   = new_Jmp();
        add_immBlock_pred(block, jmp);
 
@@ -2501,25 +2500,25 @@ static void statement_to_firm(statement_t *statement)
 {
        switch(statement->type) {
        case STATEMENT_COMPOUND:
-               compound_statement_to_firm((compound_statement_t*) statement);
+               compound_statement_to_firm(statement);
                return;
        case STATEMENT_RETURN:
-               return_statement_to_firm((return_statement_t*) statement);
+               return_statement_to_firm(statement);
                return;
        case STATEMENT_EXPRESSION:
-               expression_statement_to_firm((expression_statement_t*) statement);
+               expression_statement_to_firm(statement);
                return;
        case STATEMENT_IF:
-               if_statement_to_firm((if_statement_t*) statement);
+               if_statement_to_firm(statement);
                return;
        case STATEMENT_WHILE:
-               while_statement_to_firm((while_statement_t*) statement);
+               while_statement_to_firm(statement);
                return;
        case STATEMENT_DO_WHILE:
-               do_while_statement_to_firm((do_while_statement_t*) statement);
+               do_while_statement_to_firm(statement);
                return;
        case STATEMENT_DECLARATION:
-               declaration_statement_to_firm((declaration_statement_t*) statement);
+               declaration_statement_to_firm(statement);
                return;
        case STATEMENT_BREAK:
                create_jump_statement(statement, break_label);
@@ -2528,19 +2527,19 @@ static void statement_to_firm(statement_t *statement)
                create_jump_statement(statement, continue_label);
                return;
        case STATEMENT_SWITCH:
-               switch_statement_to_firm((switch_statement_t*) statement);
+               switch_statement_to_firm(statement);
                return;
        case STATEMENT_CASE_LABEL:
-               case_label_to_firm((case_label_statement_t*) statement);
+               case_label_to_firm(statement);
                return;
        case STATEMENT_FOR:
-               for_statement_to_firm((for_statement_t*) statement);
+               for_statement_to_firm(statement);
                return;
        case STATEMENT_LABEL:
-               label_to_firm((label_statement_t*) statement);
+               label_to_firm(statement);
                return;
        case STATEMENT_GOTO:
-               goto_to_firm((goto_statement_t*) statement);
+               goto_to_firm(statement);
                return;
        default:
                break;
@@ -2572,61 +2571,39 @@ static int count_decls_in_stmts(const statement_t *stmt)
        int count = 0;
        for (; stmt != NULL; stmt = stmt->next) {
                switch (stmt->type) {
-                       case STATEMENT_DECLARATION: {
-                               const declaration_statement_t *const decl_stmt =
-                                       (const declaration_statement_t*)stmt;
-                               count += count_local_declarations(decl_stmt->declarations_begin,
-                                                                 decl_stmt->declarations_end->next);
+                       case STATEMENT_DECLARATION:
+                               count += count_local_declarations(stmt->v.declaration_stmt.begin,
+                                                                 stmt->v.declaration_stmt.end->next);
                                break;
-                       }
 
-                       case STATEMENT_COMPOUND: {
-                               const compound_statement_t *const comp =
-                                       (const compound_statement_t*)stmt;
-                               count += count_decls_in_stmts(comp->statements);
+                       case STATEMENT_COMPOUND:
+                               count += count_decls_in_stmts(stmt->v.compound_stmt.statements);
                                break;
-                       }
 
-                       case STATEMENT_IF: {
-                               const if_statement_t *const if_stmt = (const if_statement_t*)stmt;
-                               count += count_decls_in_stmts(if_stmt->true_statement);
-                               count += count_decls_in_stmts(if_stmt->false_statement);
+                       case STATEMENT_IF:
+                               count += count_decls_in_stmts(stmt->v.if_stmt.true_statement);
+                               count += count_decls_in_stmts(stmt->v.if_stmt.false_statement);
                                break;
-                       }
 
-                       case STATEMENT_SWITCH: {
-                               const switch_statement_t *const switch_stmt =
-                                       (const switch_statement_t*)stmt;
-                               count += count_decls_in_stmts(switch_stmt->body);
+                       case STATEMENT_SWITCH:
+                               count += count_decls_in_stmts(stmt->v.switch_stmt.body);
                                break;
-                       }
 
-                       case STATEMENT_LABEL: {
-                               const label_statement_t *const label_stmt =
-                                       (const label_statement_t*)stmt;
-                               count += count_decls_in_stmts(label_stmt->label_statement);
+                       case STATEMENT_LABEL:
+                               count += count_decls_in_stmts(stmt->v.label_stmt.label_statement);
                                break;
-                       }
 
-                       case STATEMENT_WHILE: {
-                               const while_statement_t *const while_stmt =
-                                       (const while_statement_t*)stmt;
-                               count += count_decls_in_stmts(while_stmt->body);
+                       case STATEMENT_WHILE:
+                               count += count_decls_in_stmts(stmt->v.while_stmt.body);
                                break;
-                       }
 
-                       case STATEMENT_DO_WHILE: {
-                               const do_while_statement_t *const do_while_stmt =
-                                       (const do_while_statement_t*)stmt;
-                               count += count_decls_in_stmts(do_while_stmt->body);
+                       case STATEMENT_DO_WHILE:
+                               count += count_decls_in_stmts(stmt->v.while_stmt.body);
                                break;
-                       }
 
                        case STATEMENT_FOR: {
-                               const for_statement_t *const for_stmt =
-                                       (const for_statement_t*)stmt;
                                /* TODO initialisation */
-                               count += count_decls_in_stmts(for_stmt->body);
+                               count += count_decls_in_stmts(stmt->v.for_stmt.body);
                                break;
                        }
 
diff --git a/ast_t.h b/ast_t.h
index 75c0f03..7dd8480 100644 (file)
--- a/ast_t.h
+++ b/ast_t.h
@@ -287,79 +287,58 @@ struct statement_t {
        statement_type_t   type;
        statement_t       *next;
        source_position_t  source_position;
-};
-
-struct return_statement_t {
-       statement_t   statement;
-       expression_t *return_value;
-};
-
-struct compound_statement_t {
-       statement_t  statement;
-       statement_t *statements;
-       context_t    context;
-};
-
-struct declaration_statement_t {
-       statement_t    statement;
-       declaration_t *declarations_begin;
-       declaration_t *declarations_end;
-};
-
-struct if_statement_t {
-       statement_t   statement;
-       expression_t *condition;
-       statement_t  *true_statement;
-       statement_t  *false_statement;
-};
-
-struct switch_statement_t {
-       statement_t   statement;
-       expression_t *expression;
-       statement_t  *body;
-};
-
-struct goto_statement_t {
-       statement_t    statement;
-       declaration_t *label;
-};
-
-struct case_label_statement_t {
-       statement_t   statement;
-       expression_t *expression;
-       statement_t  *label_statement;
-};
-
-struct label_statement_t {
-       statement_t    statement;
-       declaration_t *label;
-       statement_t   *label_statement;
-};
-
-struct expression_statement_t {
-       statement_t   statement;
-       expression_t *expression;
-};
-
-struct while_statement_t {
-       statement_t   statement;
-       expression_t *condition;
-       statement_t  *body;
-};
-
-struct do_while_statement_t {
-       statement_t   statement;
-       expression_t *condition;
-       statement_t  *body;
-};
-
-struct for_statement_t {
-       statement_t   statement;
-       expression_t  *initialisation;
-       expression_t  *condition;
-       expression_t  *step;
-       statement_t   *body;
-       context_t      context;
+       union {
+               /* if type == STATEMENT_COMPOUND */
+               struct {
+                       statement_t *statements;
+                       context_t    context;
+               } compound_stmt;
+               /* if type == STATEMENT_RETURN */
+               expression_t *return_value;
+               /* if type == STATEMENT_DECLARATION */
+               struct {
+                       declaration_t *begin;
+                       declaration_t *end;
+               } declaration_stmt;
+               /* if type == STATEMENT_IF */
+               struct {
+                       expression_t *condition;
+                       statement_t  *true_statement;
+                       statement_t  *false_statement;
+               } if_stmt;
+               /* if type == STATEMENT_SWITCH */
+               struct {
+                       expression_t *expression;
+                       statement_t  *body;
+               } switch_stmt;
+               /* if type == STATEMENT_EXPRESSION */
+               expression_t *expression;
+               /* if type == STATEMENT_GOTO */
+               declaration_t *goto_label;
+               /* if type == STATEMENT_LABEL */
+               struct {
+                       declaration_t *label;
+                       statement_t   *label_statement;
+               } label_stmt;
+               /* if type == STATEMENT_CASE_LABEL */
+               struct {
+                       expression_t *expression;
+                       statement_t  *label_statement;
+               } case_label_stmt;
+               /* if type == STATEMENT_WHILE or STATEMENT_DO_WHILE */
+               struct {
+                       expression_t *condition;
+                       statement_t  *body;
+               } while_stmt;
+               /* if type == STATEMENT_FOR */
+               struct {
+                       expression_t  *initialisation;
+                       expression_t  *condition;
+                       expression_t  *step;
+                       statement_t   *body;
+                       context_t      context;
+               } for_stmt;
+       } v;
 };
 
 struct translation_unit_t {
index 0274220..4b888fc 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -2585,21 +2585,17 @@ static expression_t *parse_statement_expression(void)
        }
 
        assert(statement->type == STATEMENT_COMPOUND);
-       compound_statement_t *compound_statement
-               = (compound_statement_t*) statement;
 
        /* find last statement and use it's type */
        const statement_t *last_statement = NULL;
-       const statement_t *iter           = compound_statement->statements;
+       const statement_t *iter           = statement->v.compound_stmt.statements;
        for( ; iter != NULL; iter = iter->next) {
                last_statement = iter;
        }
 
        if(last_statement->type == STATEMENT_EXPRESSION) {
-               const expression_statement_t *expression_statement =
-                       (const expression_statement_t*) last_statement;
                expression->expression.datatype
-                       = expression_statement->expression->datatype;
+                       = last_statement->v.expression->datatype;
        } else {
                expression->expression.datatype = type_void;
        }
@@ -3907,28 +3903,28 @@ static void init_expression_parsers(void)
 static statement_t *parse_case_statement(void)
 {
        eat(T_case);
-       case_label_statement_t *label = allocate_ast_zero(sizeof(label[0]));
-       label->statement.type            = STATEMENT_CASE_LABEL;
-       label->statement.source_position = token.source_position;
+       statement_t *label = allocate_ast_zero(sizeof(label[0]));
+       label->type            = STATEMENT_CASE_LABEL;
+       label->source_position = token.source_position;
 
-       label->expression = parse_expression();
+       label->v.case_label_stmt.expression = parse_expression();
 
        expect(':');
-       label->label_statement = parse_statement();
+       label->v.case_label_stmt.label_statement = parse_statement();
 
-       return (statement_t*) label;
+       return label;
 }
 
 static statement_t *parse_default_statement(void)
 {
        eat(T_default);
 
-       case_label_statement_t *label = allocate_ast_zero(sizeof(label[0]));
-       label->statement.type            = STATEMENT_CASE_LABEL;
-       label->statement.source_position = token.source_position;
+       statement_t *label = allocate_ast_zero(sizeof(label[0]));
+       label->type            = STATEMENT_CASE_LABEL;
+       label->source_position = token.source_position;
 
        expect(':');
-       label->label_statement = parse_statement();
+       label->v.case_label_stmt.label_statement = parse_statement();
 
        return (statement_t*) label;
 }
@@ -3974,11 +3970,11 @@ static statement_t *parse_label_statement(void)
                label->source_position = token.source_position;
        }
 
-       label_statement_t *label_statement = allocate_ast_zero(sizeof(label[0]));
+       statement_t *label_statement = allocate_ast_zero(sizeof(label[0]));
 
-       label_statement->statement.type            = STATEMENT_LABEL;
-       label_statement->statement.source_position = token.source_position;
-       label_statement->label                     = label;
+       label_statement->type               = STATEMENT_LABEL;
+       label_statement->source_position    = token.source_position;
+       label_statement->v.label_stmt.label = label;
 
        expect(':');
 
@@ -3986,102 +3982,102 @@ static statement_t *parse_label_statement(void)
                parse_error("label at end of compound statement");
                return (statement_t*) label_statement;
        } else {
-               label_statement->label_statement = parse_statement();
+               label_statement->v.label_stmt.label_statement = parse_statement();
        }
 
-       return (statement_t*) label_statement;
+       return label_statement;
 }
 
 static statement_t *parse_if(void)
 {
        eat(T_if);
 
-       if_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
-       statement->statement.type            = STATEMENT_IF;
-       statement->statement.source_position = token.source_position;
+       statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+       statement->type            = STATEMENT_IF;
+       statement->source_position = token.source_position;
 
        expect('(');
-       statement->condition = parse_expression();
+       statement->v.if_stmt.condition = parse_expression();
        expect(')');
 
-       statement->true_statement = parse_statement();
+       statement->v.if_stmt.true_statement = parse_statement();
        if(token.type == T_else) {
                next_token();
-               statement->false_statement = parse_statement();
+               statement->v.if_stmt.false_statement = parse_statement();
        }
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_switch(void)
 {
        eat(T_switch);
 
-       switch_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
-       statement->statement.type            = STATEMENT_SWITCH;
-       statement->statement.source_position = token.source_position;
+       statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+       statement->type            = STATEMENT_SWITCH;
+       statement->source_position = token.source_position;
 
        expect('(');
-       statement->expression = parse_expression();
+       statement->v.switch_stmt.expression = parse_expression();
        expect(')');
-       statement->body = parse_statement();
+       statement->v.switch_stmt.body = parse_statement();
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_while(void)
 {
        eat(T_while);
 
-       while_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
-       statement->statement.type            = STATEMENT_WHILE;
-       statement->statement.source_position = token.source_position;
+       statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+       statement->type            = STATEMENT_WHILE;
+       statement->source_position = token.source_position;
 
        expect('(');
-       statement->condition = parse_expression();
+       statement->v.while_stmt.condition = parse_expression();
        expect(')');
-       statement->body = parse_statement();
+       statement->v.while_stmt.body = parse_statement();
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_do(void)
 {
        eat(T_do);
 
-       do_while_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
-       statement->statement.type            = STATEMENT_DO_WHILE;
-       statement->statement.source_position = token.source_position;
+       statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+       statement->type            = STATEMENT_DO_WHILE;
+       statement->source_position = token.source_position;
 
-       statement->body = parse_statement();
+       statement->v.while_stmt.body = parse_statement();
        expect(T_while);
        expect('(');
-       statement->condition = parse_expression();
+       statement->v.while_stmt.condition = parse_expression();
        expect(')');
        expect(';');
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_for(void)
 {
        eat(T_for);
 
-       for_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
-       statement->statement.type            = STATEMENT_FOR;
-       statement->statement.source_position = token.source_position;
+       statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+       statement->type            = STATEMENT_FOR;
+       statement->source_position = token.source_position;
 
        expect('(');
 
        int         top          = environment_top();
        context_t  *last_context = context;
-       set_context(&statement->context);
+       set_context(&statement->v.for_stmt.context);
 
        if(token.type != ';') {
                if(is_declaration_specifier(&token, false)) {
                        parse_declaration();
                } else {
-                       statement->initialisation = parse_expression();
+                       statement->v.for_stmt.initialisation = parse_expression();
                        expect(';');
                }
        } else {
@@ -4089,20 +4085,20 @@ static statement_t *parse_for(void)
        }
 
        if(token.type != ';') {
-               statement->condition = parse_expression();
+               statement->v.for_stmt.condition = parse_expression();
        }
        expect(';');
        if(token.type != ')') {
-               statement->step = parse_expression();
+               statement->v.for_stmt.step = parse_expression();
        }
        expect(')');
-       statement->body = parse_statement();
+       statement->v.for_stmt.body = parse_statement();
 
-       assert(context == &statement->context);
+       assert(context == &statement->v.for_stmt.context);
        set_context(last_context);
        environment_pop_to(top);
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_goto(void)
@@ -4119,16 +4115,16 @@ static statement_t *parse_goto(void)
 
        declaration_t *label = get_label(symbol);
 
-       goto_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+       statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
 
-       statement->statement.type            = STATEMENT_GOTO;
-       statement->statement.source_position = token.source_position;
+       statement->type            = STATEMENT_GOTO;
+       statement->source_position = token.source_position;
 
-       statement->label = label;
+       statement->v.goto_label = label;
 
        expect(';');
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_continue(void)
@@ -4159,10 +4155,10 @@ static statement_t *parse_return(void)
 {
        eat(T_return);
 
-       return_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+       statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
 
-       statement->statement.type            = STATEMENT_RETURN;
-       statement->statement.source_position = token.source_position;
+       statement->type            = STATEMENT_RETURN;
+       statement->source_position = token.source_position;
 
        assert(current_function->type->type == TYPE_FUNCTION);
        function_type_t *function_type = (function_type_t*) current_function->type;
@@ -4187,21 +4183,21 @@ static statement_t *parse_return(void)
                                      "non-void");
                }
        }
-       statement->return_value = return_value;
+       statement->v.return_value = return_value;
 
        expect(';');
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_declaration_statement(void)
 {
        declaration_t *before = last_declaration;
 
-       declaration_statement_t *statement
+       statement_t *statement
                = allocate_ast_zero(sizeof(statement[0]));
-       statement->statement.type            = STATEMENT_DECLARATION;
-       statement->statement.source_position = token.source_position;
+       statement->type            = STATEMENT_DECLARATION;
+       statement->source_position = token.source_position;
 
        declaration_specifiers_t specifiers;
        memset(&specifiers, 0, sizeof(specifiers));
@@ -4214,26 +4210,26 @@ static statement_t *parse_declaration_statement(void)
        }
 
        if(before == NULL) {
-               statement->declarations_begin = context->declarations;
+               statement->v.declaration_stmt.begin = context->declarations;
        } else {
-               statement->declarations_begin = before->next;
+               statement->v.declaration_stmt.begin = before->next;
        }
-       statement->declarations_end = last_declaration;
+       statement->v.declaration_stmt.end = last_declaration;
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_expression_statement(void)
 {
-       expression_statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
-       statement->statement.type            = STATEMENT_EXPRESSION;
-       statement->statement.source_position = token.source_position;
+       statement_t *statement = allocate_ast_zero(sizeof(statement[0]));
+       statement->type            = STATEMENT_EXPRESSION;
+       statement->source_position = token.source_position;
 
-       statement->expression = parse_expression();
+       statement->v.expression = parse_expression();
 
        expect(';');
 
-       return (statement_t*) statement;
+       return statement;
 }
 
 static statement_t *parse_statement(void)
@@ -4334,16 +4330,16 @@ static statement_t *parse_statement(void)
 
 static statement_t *parse_compound_statement(void)
 {
-       compound_statement_t *compound_statement
+       statement_t *compound_statement
                = allocate_ast_zero(sizeof(compound_statement[0]));
-       compound_statement->statement.type            = STATEMENT_COMPOUND;
-       compound_statement->statement.source_position = token.source_position;
+       compound_statement->type            = STATEMENT_COMPOUND;
+       compound_statement->source_position = token.source_position;
 
        eat('{');
 
        int        top          = environment_top();
        context_t *last_context = context;
-       set_context(&compound_statement->context);
+       set_context(&compound_statement->v.compound_stmt.context);
 
        statement_t *last_statement = NULL;
 
@@ -4355,7 +4351,7 @@ static statement_t *parse_compound_statement(void)
                if(last_statement != NULL) {
                        last_statement->next = statement;
                } else {
-                       compound_statement->statements = statement;
+                       compound_statement->v.compound_stmt.statements = statement;
                }
 
                while(statement->next != NULL)
@@ -4366,16 +4362,16 @@ static statement_t *parse_compound_statement(void)
 
        if(token.type != '}') {
                parser_print_error_prefix_pos(
-                               compound_statement->statement.source_position);
+                               compound_statement->source_position);
                fprintf(stderr, "end of file while looking for closing '}'\n");
        }
        next_token();
 
-       assert(context == &compound_statement->context);
+       assert(context == &compound_statement->v.compound_stmt.context);
        set_context(last_context);
        environment_pop_to(top);
 
-       return (statement_t*) compound_statement;
+       return compound_statement;
 }
 
 static translation_unit_t *parse_translation_unit(void)