preliminary Win32 support added
[cparser] / ast2firm.c
index 334ac62..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);
@@ -501,7 +502,7 @@ static inline ir_mode *get_ir_mode(type_t *type)
                return mode_P;
        }
 
-       ir_mode *mode   = get_type_mode(irtype);
+       ir_mode *mode = get_type_mode(irtype);
        assert(mode != NULL);
        return mode;
 }
@@ -622,13 +623,14 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
        dbg_info      *dbgi        = get_dbg_info(&ref->expression.source_position);
        declaration_t *declaration = ref->declaration;
        type_t        *type        = skip_typeref(declaration->type);
-       ir_mode       *mode        = get_ir_mode(type);
 
        switch((declaration_type_t) declaration->declaration_type) {
        case DECLARATION_TYPE_UNKNOWN:
                break;
-       case DECLARATION_TYPE_LOCAL_VARIABLE:
+       case DECLARATION_TYPE_LOCAL_VARIABLE: {
+               ir_mode *mode = get_ir_mode(type);
                return get_value(declaration->v.value_number, mode);
+       }
        case DECLARATION_TYPE_FUNCTION: {
                return create_symconst(dbgi, declaration->v.entity);
        }
@@ -647,7 +649,8 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
                ir_node   *frame  = get_irg_frame(current_ir_graph);
                ir_node   *sel    = new_d_simpleSel(dbgi, new_NoMem(), frame, entity);
 
-               if(type->type == TYPE_ARRAY) {
+               if(type->type == TYPE_ARRAY || type->type == TYPE_COMPOUND_STRUCT
+                               || type->type == TYPE_COMPOUND_UNION) {
                        return sel;
                } else {
                        return load_from_expression_addr(type, sel, dbgi);
@@ -1373,13 +1376,13 @@ static ir_node *_expression_to_firm(const expression_t *expression)
 
 static ir_node *expression_to_firm(const expression_t *expression)
 {
-       ir_node *res  = _expression_to_firm(expression);
+       ir_node *res = _expression_to_firm(expression);
 
-       if(expression->datatype == type_void)
-               return NULL;
+       if(res != NULL && get_irn_mode(res) == mode_b) {
+               ir_mode *mode = get_ir_mode(expression->datatype);
+               res           = create_conv(NULL, res, mode);
+       }
 
-       ir_mode *mode = get_ir_mode(expression->datatype);
-       res           = create_conv(NULL, res, mode);
        return res;
 }
 
@@ -1708,7 +1711,8 @@ static void create_local_variable(declaration_t *declaration)
        assert(declaration->declaration_type == DECLARATION_TYPE_UNKNOWN);
 
        bool needs_entity = declaration->address_taken;
-       type_t *type = declaration->type;
+       type_t *type = skip_typeref(declaration->type);
+
        if(type->type == TYPE_ARRAY
                        || type->type == TYPE_COMPOUND_STRUCT
                        || type->type == TYPE_COMPOUND_UNION) {
@@ -1782,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);
 
@@ -1794,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);
@@ -1827,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;
@@ -1839,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);
 }
@@ -1964,9 +1983,16 @@ static void initialize_function_parameters(declaration_t *declaration)
        declaration_t *parameter = declaration->context.declarations;
        for( ; parameter != NULL; parameter = parameter->next) {
                assert(parameter->declaration_type == DECLARATION_TYPE_UNKNOWN);
+               type_t *type = parameter->type;
+
+               bool needs_entity = parameter->address_taken;
+               if(type->type == TYPE_COMPOUND_STRUCT
+                               || type->type == TYPE_COMPOUND_UNION) {
+                       needs_entity = true;
+               }
 
-               if(parameter->address_taken) {
-                       panic("address take from parameter not implemented yet");
+               if(needs_entity) {
+                       panic("entities for function parameters not implemented yet");
                }
 
                ir_mode *mode = get_ir_mode(parameter->type);