preliminary Win32 support added
[cparser] / ast2firm.c
index 601a3b1..a33ce29 100644 (file)
@@ -32,6 +32,7 @@ static int       next_value_number_function;
 static ir_node  *continue_label;
 static ir_node  *break_label;
 static ir_node  *current_switch_cond;
+static bool      saw_default_label;
 static ir_node **imature_blocks;
 
 typedef enum declaration_type_t {
@@ -82,8 +83,8 @@ const char *retrieve_dbg(const dbg_info *dbg, unsigned *line)
 void init_ast2firm(void)
 {
        type_const_char = make_atomic_type(ATOMIC_TYPE_CHAR, TYPE_QUALIFIER_CONST);
-       type_void       = make_atomic_type(ATOMIC_TYPE_VOID, 0);
-       type_int        = make_atomic_type(ATOMIC_TYPE_INT, 0);
+       type_void       = make_atomic_type(ATOMIC_TYPE_VOID, TYPE_QUALIFIER_NONE);
+       type_int        = make_atomic_type(ATOMIC_TYPE_INT,  TYPE_QUALIFIER_NONE);
 
        ir_type_int        = get_ir_type(type_int);
        ir_type_const_char = get_ir_type(type_const_char);
@@ -1785,10 +1786,11 @@ static void switch_statement_to_firm(const switch_statement_t *statement)
 
        set_cur_block(NULL);
 
-       ir_node *old_switch_cond = current_switch_cond;
-       ir_node *old_break_label = break_label;
-       current_switch_cond      = cond;
-       break_label              = break_block;
+       ir_node *const old_switch_cond       = current_switch_cond;
+       ir_node *const old_break_label       = break_label;
+       const bool     old_saw_default_label = saw_default_label;
+       current_switch_cond                  = cond;
+       break_label                          = break_block;
 
        statement_to_firm(statement->body);
 
@@ -1797,10 +1799,18 @@ static void switch_statement_to_firm(const switch_statement_t *statement)
                add_immBlock_pred(break_block, jmp);
        }
 
+       if (!saw_default_label) {
+               set_cur_block(get_nodes_block(cond));
+               ir_node *const proj = new_d_defaultProj(dbgi, cond,
+                                                       MAGIC_DEFAULT_PN_NUMBER);
+               add_immBlock_pred(break_block, proj);
+       }
+
        assert(current_switch_cond == cond);
        assert(break_label         == break_block);
        current_switch_cond = old_switch_cond;
        break_label         = old_break_label;
+       saw_default_label   = old_saw_default_label;
 
        mature_immBlock(break_block);
        set_cur_block(break_block);
@@ -1830,6 +1840,8 @@ static void case_label_to_firm(const case_label_statement_t *statement)
 {
        dbg_info *dbgi = get_dbg_info(&statement->statement.source_position);
 
+       ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
+
        /* let's create a node and hope firm constant folding creates a Const
         * node... */
        ir_node *proj;
@@ -1842,11 +1854,15 @@ static void case_label_to_firm(const case_label_statement_t *statement)
                }
                proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
        } else {
+               saw_default_label = true;
                proj = new_d_defaultProj(dbgi, current_switch_cond,
                                         MAGIC_DEFAULT_PN_NUMBER);
        }
 
        ir_node *block = new_immBlock();
+       if (fallthrough != NULL) {
+               add_immBlock_pred(block, fallthrough);
+       }
        add_immBlock_pred(block, proj);
        mature_immBlock(block);
 }