condeval is called jump threading now
[cparser] / ast2firm.c
index 222965c..ab7516b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ * Copyright (C) 2007-2009 Matthias Braun <matze@braunis.de>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -79,6 +79,7 @@ static label_t  **all_labels;
 static entity_t **inner_functions;
 static ir_node   *ijmp_list;
 static bool       constant_folding;
+static bool       initializer_use_bitfield_basetype;
 
 extern bool       have_const_functions;
 
@@ -323,13 +324,13 @@ static ir_type *create_complex_type(const complex_type_t *type)
 /**
  * Creates a Firm type for an imaginary type
  */
-static ir_type *create_imaginary_type(const imaginary_type_t *type)
+static ir_type *create_imaginary_type(imaginary_type_t *type)
 {
        atomic_type_kind_t  kind      = type->akind;
        ir_mode            *mode      = atomic_modes[kind];
        ident              *id        = get_mode_ident(mode);
        ir_type            *irtype    = new_type_primitive(id, mode);
-       il_alignment_t      alignment = get_type_alignment((const type_t*) type);
+       il_alignment_t      alignment = get_type_alignment((type_t*) type);
 
        set_type_alignment_bytes(irtype, alignment);
 
@@ -380,9 +381,10 @@ static ir_type *create_method_type(const function_type_t *function_type, bool fo
                ++n;
        }
 
-       if (function_type->variadic || function_type->unspecified_parameters) {
+       bool is_variadic = function_type->variadic;
+
+       if (is_variadic)
                set_method_variadicity(irtype, variadicity_variadic);
-       }
 
        unsigned cc = get_method_calling_convention(irtype);
        switch (function_type->calling_convention) {
@@ -393,7 +395,7 @@ is_cdecl:
                break;
 
        case CC_STDCALL:
-               if (function_type->variadic || function_type->unspecified_parameters)
+               if (is_variadic)
                        goto is_cdecl;
 
                /* only non-variadic function can use stdcall, else use cdecl */
@@ -401,7 +403,7 @@ is_cdecl:
                break;
 
        case CC_FASTCALL:
-               if (function_type->variadic || function_type->unspecified_parameters)
+               if (is_variadic)
                        goto is_cdecl;
                /* only non-variadic function can use fastcall, else use cdecl */
                set_method_calling_convention(irtype, SET_FASTCALL(cc));
@@ -599,6 +601,12 @@ static ir_type *create_compound_type(compound_type_t *type,
        if (incomplete)
                return irtype;
 
+       if (is_union) {
+               layout_union_type(type);
+       } else {
+               layout_struct_type(type);
+       }
+
        compound->irtype_complete = true;
 
        entity_t *entry = compound->members.entities;
@@ -928,8 +936,8 @@ static bool is_main(entity_t *entity)
 static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
 {
        assert(entity->kind == ENTITY_FUNCTION);
-       if (entity->function.entity != NULL) {
-               return entity->function.entity;
+       if (entity->function.irentity != NULL) {
+               return entity->function.irentity;
        }
 
        if (is_main(entity)) {
@@ -1031,8 +1039,8 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
        entitymap_insert(&entitymap, symbol, irentity);
 
 entity_created:
-       entity->declaration.kind = DECLARATION_KIND_FUNCTION;
-       entity->function.entity  = irentity;
+       entity->declaration.kind  = DECLARATION_KIND_FUNCTION;
+       entity->function.irentity = irentity;
 
        return irentity;
 }
@@ -1219,7 +1227,7 @@ static ir_node *create_trampoline(dbg_info *dbgi, ir_mode *mode,
        in[1] = create_symconst(dbgi, mode, entity);
        in[2] = get_irg_frame(current_ir_graph);
 
-       ir_node *irn = new_d_Builtin(dbgi, get_store(), ir_bk_inner_trampoline, 3, in, get_unknown_type());
+       ir_node *irn = new_d_Builtin(dbgi, get_store(), 3, in, ir_bk_inner_trampoline, get_unknown_type());
        set_store(new_Proj(irn, mode_M, pn_Builtin_M));
        return new_Proj(irn, mode, pn_Builtin_1_result);
 }
@@ -1245,6 +1253,7 @@ static ir_node *string_to_firm(const source_position_t *const src_pos,
        set_entity_ld_ident(entity, id);
        set_entity_variability(entity, variability_constant);
        set_entity_allocation(entity, allocation_static);
+       set_entity_visibility(entity, visibility_local);
 
        ir_type *const elem_type = ir_type_const_char;
        ir_mode *const mode      = get_type_mode(elem_type);
@@ -1447,6 +1456,21 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
        /* make sure the type is constructed */
        (void) get_ir_type(type);
 
+       /* for gcc compatibility we have to produce (dummy) addresses for some
+        * builtins */
+       if (entity->kind == ENTITY_FUNCTION && entity->function.btk != bk_none) {
+               if (warning.other) {
+                       warningf(&ref->base.source_position,
+                                       "taking address of builtin '%Y'", ref->entity->base.symbol);
+               }
+
+               /* simply create a NULL pointer */
+               ir_mode  *mode = get_ir_mode_arithmetic(type_void_ptr);
+               ir_node  *res  = new_Const_long(mode, 0);
+
+               return res;
+       }
+
        switch ((declaration_kind_t) entity->declaration.kind) {
        case DECLARATION_KIND_UNKNOWN:
                break;
@@ -1463,31 +1487,16 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
        }
        case DECLARATION_KIND_FUNCTION: {
                ir_mode *const mode = get_ir_mode_storage(type);
-
-               if (entity->function.btk != bk_none) {
-                       /* for gcc compatibility we have to produce (dummy) addresses for some
-                        * builtins */
-                       if (warning.other) {
-                               warningf(&ref->base.source_position,
-                                       "taking address of builtin '%Y'", ref->entity->base.symbol);
-                       }
-
-                       /* simply create a NULL pointer */
-                       ir_mode  *mode = get_ir_mode_arithmetic(type_void_ptr);
-                       ir_node  *res  = new_Const_long(mode, 0);
-
-                       return res;
-               }
-               return create_symconst(dbgi, mode, entity->function.entity);
+               return create_symconst(dbgi, mode, entity->function.irentity);
        }
        case DECLARATION_KIND_INNER_FUNCTION: {
                ir_mode *const mode = get_ir_mode_storage(type);
                if (!entity->function.goto_to_outer && !entity->function.need_closure) {
                        /* inner function not using the closure */
-                       return create_symconst(dbgi, mode, entity->function.entity);
+                       return create_symconst(dbgi, mode, entity->function.irentity);
                } else {
                        /* need trampoline here */
-                       return create_trampoline(dbgi, mode, entity->function.entity);
+                       return create_trampoline(dbgi, mode, entity->function.irentity);
                }
        }
        case DECLARATION_KIND_GLOBAL_VARIABLE: {
@@ -1558,7 +1567,7 @@ static ir_node *reference_addr(const reference_expression_t *ref)
        case DECLARATION_KIND_FUNCTION: {
                type_t  *const type = skip_typeref(entity->declaration.type);
                ir_mode *const mode = get_ir_mode_storage(type);
-               return create_symconst(dbgi, mode, entity->function.entity);
+               return create_symconst(dbgi, mode, entity->function.irentity);
        }
 
        case DECLARATION_KIND_INNER_FUNCTION: {
@@ -1566,10 +1575,10 @@ static ir_node *reference_addr(const reference_expression_t *ref)
                ir_mode *const mode = get_ir_mode_storage(type);
                if (!entity->function.goto_to_outer && !entity->function.need_closure) {
                        /* inner function not using the closure */
-                       return create_symconst(dbgi, mode, entity->function.entity);
+                       return create_symconst(dbgi, mode, entity->function.irentity);
                } else {
                        /* need trampoline here */
-                       return create_trampoline(dbgi, mode, entity->function.entity);
+                       return create_trampoline(dbgi, mode, entity->function.irentity);
                }
        }
 
@@ -1595,7 +1604,7 @@ static ir_node *gen_unary_builtin(ir_builtin_kind kind, expression_t *op, type_t
 
        ir_type *tp  = get_ir_type(function_type);
        ir_type *res = get_method_res_type(tp, 0);
-       ir_node *irn = new_d_Builtin(db, get_irg_no_mem(current_ir_graph), kind, 1, in, tp);
+       ir_node *irn = new_d_Builtin(db, get_irg_no_mem(current_ir_graph), 1, in, kind, tp);
        set_irn_pinned(irn, op_pin_state_floats);
        return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
 }
@@ -1616,7 +1625,7 @@ static ir_node *gen_unary_builtin_pinned(ir_builtin_kind kind, expression_t *op,
        ir_type *tp  = get_ir_type(function_type);
        ir_type *res = get_method_res_type(tp, 0);
        ir_node *mem = get_store();
-       ir_node *irn = new_d_Builtin(db, mem, kind, 1, in, tp);
+       ir_node *irn = new_d_Builtin(db, mem, 1, in, kind, tp);
        set_store(new_Proj(irn, mode_M, pn_Builtin_M));
        return new_Proj(irn, get_type_mode(res), pn_Builtin_1_result);
 }
@@ -1640,7 +1649,7 @@ static ir_node *gen_binary_builtin_mem(ir_builtin_kind kind, expression_t *op1,
 
        ir_type *tp  = get_ir_type(function_type);
        ir_node *mem = get_store();
-       ir_node *irn = new_d_Builtin(db, mem, kind, 2, in, tp);
+       ir_node *irn = new_d_Builtin(db, mem, 2, in, kind, tp);
        set_store(new_Proj(irn, mode_M, pn_Builtin_M));
        return NULL;
 }
@@ -1720,7 +1729,7 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                        in[0] = expression_to_firm(expression);
                        in[1] = get_irg_frame(current_ir_graph);
                        ir_type *tp  = get_ir_type(function_type);
-                       ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_frame_addess, 2, in, tp);
+                       ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_frame_address, tp);
                        return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
                }
        }
@@ -1732,7 +1741,7 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                in[0] = expression_to_firm(expression);
                in[1] = get_irg_frame(current_ir_graph);
                ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_return_address, 2, in, tp);
+               ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_return_address, tp);
                return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
        }
        case bk_gnu_builtin_ffs:
@@ -1769,7 +1778,7 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                        in[2] = new_Const_long(mode_int, 3);
                }
                ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), ir_bk_prefetch, 3, in, tp);
+               ir_node *irn = new_d_Builtin(dbgi, get_store(), 3, in, ir_bk_prefetch, tp);
                set_store(new_Proj(irn, mode_M, pn_Builtin_M));
                return NULL;
        }
@@ -1777,13 +1786,13 @@ static ir_node *process_builtin_call(const call_expression_t *call)
        case bk_ms__ud2:
        {
                ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), ir_bk_trap, 0, NULL, tp);
+               ir_node *irn = new_d_Builtin(dbgi, get_store(), 0, NULL, ir_bk_trap, tp);
                set_store(new_Proj(irn, mode_M, pn_Builtin_M));
                return NULL;
        }
        case bk_ms__debugbreak: {
                ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_store(), ir_bk_debugbreak, 0, NULL, tp);
+               ir_node *irn = new_d_Builtin(dbgi, get_store(), 0, NULL, ir_bk_debugbreak, tp);
                set_store(new_Proj(irn, mode_M, pn_Builtin_M));
                return NULL;
        }
@@ -1793,7 +1802,7 @@ static ir_node *process_builtin_call(const call_expression_t *call)
                in[0] = new_Const_long(mode_int, 0);
                in[1] = get_irg_frame(current_ir_graph);
                ir_type *tp  = get_ir_type(function_type);
-               ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), ir_bk_return_address, 2, in, tp);
+               ir_node *irn = new_d_Builtin(dbgi, get_irg_no_mem(current_ir_graph), 2, in, ir_bk_return_address, tp);
                return new_Proj(irn, mode_P_data, pn_Builtin_1_result);
        }
        case bk_ms_rotl:
@@ -1847,28 +1856,32 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
                const reference_expression_t *ref    = &function->reference;
                entity_t                     *entity = ref->entity;
 
-               if (ref->entity->kind == ENTITY_FUNCTION &&
-                   ref->entity->function.btk != bk_none) {
-                       return process_builtin_call(call);
-               }
+               if (entity->kind == ENTITY_FUNCTION) {
+                       if (entity->function.btk != bk_none) {
+                               return process_builtin_call(call);
+                       }
+
+                       ir_entity *irentity = entity->function.irentity;
+                       if (irentity == NULL)
+                               irentity = get_function_entity(entity, NULL);
 
-               if (entity->kind == ENTITY_FUNCTION
-                               && entity->function.entity == rts_entities[rts_alloca]) {
-                       /* handle alloca() call */
-                       expression_t *argument = call->arguments->expression;
-                       ir_node      *size     = expression_to_firm(argument);
-                       ir_mode      *mode     = get_ir_mode_arithmetic(type_size_t);
+                       if (irentity == rts_entities[rts_alloca]) {
+                               /* handle alloca() call */
+                               expression_t *argument = call->arguments->expression;
+                               ir_node      *size     = expression_to_firm(argument);
+                               ir_mode      *mode     = get_ir_mode_arithmetic(type_size_t);
 
-                       size = create_conv(dbgi, size, mode);
+                               size = create_conv(dbgi, size, mode);
 
-                       ir_node  *store  = get_store();
-                       ir_node  *alloca = new_d_Alloc(dbgi, store, size, firm_unknown_type,
-                                                      stack_alloc);
-                       ir_node  *proj_m = new_Proj(alloca, mode_M, pn_Alloc_M);
-                       set_store(proj_m);
-                       ir_node  *res    = new_Proj(alloca, mode_P_data, pn_Alloc_res);
+                               ir_node  *store  = get_store();
+                               ir_node  *alloca = new_d_Alloc(dbgi, store, size,
+                                                              firm_unknown_type, stack_alloc);
+                               ir_node  *proj_m = new_Proj(alloca, mode_M, pn_Alloc_M);
+                               set_store(proj_m);
+                               ir_node  *res    = new_Proj(alloca, mode_P_data, pn_Alloc_res);
 
-                       return res;
+                               return res;
+                       }
                }
        }
        ir_node *callee = expression_to_firm(function);
@@ -2386,6 +2399,50 @@ static ir_node *handle_assume(dbg_info *dbi, const expression_t *expression)
        }
 }
 
+static ir_node *create_cast(dbg_info *dbgi,    ir_node *value_node,
+                            type_t *from_type, type_t *type)
+{
+       type = skip_typeref(type);
+       if (!is_type_scalar(type)) {
+               /* make sure firm type is constructed */
+               (void) get_ir_type(type);
+               return value_node;
+       }
+
+       from_type     = skip_typeref(from_type);
+       ir_mode *mode = get_ir_mode_storage(type);
+       /* check for conversion from / to __based types */
+       if (is_type_pointer(type) && is_type_pointer(from_type)) {
+               const variable_t *from_var = from_type->pointer.base_variable;
+               const variable_t *to_var   = type->pointer.base_variable;
+               if (from_var != to_var) {
+                       if (from_var != NULL) {
+                               ir_node *const addr = get_global_var_address(dbgi, from_var);
+                               ir_node *const base = deref_address(dbgi, from_var->base.type, addr);
+                               value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(from_type));
+                       }
+                       if (to_var != NULL) {
+                               ir_node *const addr = get_global_var_address(dbgi, to_var);
+                               ir_node *const base = deref_address(dbgi, to_var->base.type, addr);
+                               value_node = new_d_Sub(dbgi, value_node, base, mode);
+                       }
+               }
+       }
+
+       if (is_type_atomic(type, ATOMIC_TYPE_BOOL)) {
+               /* bool adjustments (we save a mode_Bu, but have to temporarily
+                * convert to mode_b so we only get a 0/1 value */
+               value_node = create_conv(dbgi, value_node, mode_b);
+       }
+
+       ir_mode *mode_arith = get_ir_mode_arithmetic(type);
+       ir_node *node       = create_conv(dbgi, value_node, mode);
+       node                = do_strict_conv(dbgi, node);
+       node                = create_conv(dbgi, node, mode_arith);
+
+       return node;
+}
+
 static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
 {
        dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
@@ -2435,50 +2492,11 @@ static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
        case EXPR_UNARY_PREFIX_INCREMENT:
        case EXPR_UNARY_PREFIX_DECREMENT:
                return create_incdec(expression);
+       case EXPR_UNARY_CAST_IMPLICIT:
        case EXPR_UNARY_CAST: {
                ir_node *value_node = expression_to_firm(value);
-               if (is_type_scalar(type)) {
-                       ir_mode *mode      = get_ir_mode_storage(type);
-                       type_t  *from_type = skip_typeref(value->base.type);
-                       /* check for conversion from / to __based types */
-                       if (is_type_pointer(type) && is_type_pointer(from_type)) {
-                               const variable_t *from_var = from_type->pointer.base_variable;
-                               const variable_t *to_var   = type->pointer.base_variable;
-                               if (from_var != to_var) {
-                                       if (from_var != NULL) {
-                                               ir_node *const addr = get_global_var_address(dbgi, from_var);
-                                               ir_node *const base = deref_address(dbgi, from_var->base.type, addr);
-                                               value_node = new_d_Add(dbgi, value_node, base, get_ir_mode_storage(from_type));
-                                       }
-                                       if (to_var != NULL) {
-                                               ir_node *const addr = get_global_var_address(dbgi, to_var);
-                                               ir_node *const base = deref_address(dbgi, to_var->base.type, addr);
-                                               value_node = new_d_Sub(dbgi, value_node, base, mode);
-                                       }
-                               }
-                       }
-                       ir_node *node       = create_conv(dbgi, value_node, mode);
-                       node                = do_strict_conv(dbgi, node);
-                       ir_mode *mode_arith = get_ir_mode_arithmetic(type);
-                       node                = create_conv(dbgi, node, mode_arith);
-                       return node;
-               } else {
-                       /* make sure firm type is constructed */
-                       (void) get_ir_type(type);
-                       return value_node;
-               }
-       }
-       case EXPR_UNARY_CAST_IMPLICIT: {
-               ir_node *value_node = expression_to_firm(value);
-               if (is_type_scalar(type)) {
-                       ir_mode *mode       = get_ir_mode_storage(type);
-                       ir_node *res        = create_conv(dbgi, value_node, mode);
-                       ir_mode *mode_arith = get_ir_mode_arithmetic(type);
-                       res                 = create_conv(dbgi, res, mode_arith);
-                       return res;
-               } else {
-                       return value_node;
-               }
+               type_t  *from_type  = value->base.type;
+               return create_cast(dbgi, value_node, from_type, type);
        }
        case EXPR_UNARY_ASSUME:
                if (firm_opt.confirm)
@@ -2697,13 +2715,12 @@ static ir_node *create_assign_binop(const binary_expression_t *expression)
        dbg_info *const     dbgi = get_dbg_info(&expression->base.source_position);
        const expression_t *left_expr = expression->left;
        type_t             *type      = skip_typeref(left_expr->base.type);
-       ir_mode            *left_mode = get_ir_mode_storage(type);
        ir_node            *right     = expression_to_firm(expression->right);
        ir_node            *left_addr = expression_to_addr(left_expr);
        ir_node            *left      = get_value_from_lvalue(left_expr, left_addr);
        ir_node            *result    = create_op(dbgi, expression, left, right);
 
-       result = create_conv(dbgi, result, left_mode);
+       result = create_cast(dbgi, result, expression->right->base.type, type);
        result = do_strict_conv(dbgi, result);
 
        result = set_value_for_expression_addr(left_expr, result, left_addr);
@@ -2909,13 +2926,7 @@ static ir_node *compound_literal_to_firm(
  */
 static ir_node *sizeof_to_firm(const typeprop_expression_t *expression)
 {
-       type_t *type = expression->type;
-       if (type == NULL) {
-               type = expression->tp_expression->base.type;
-               assert(type != NULL);
-       }
-
-       type = skip_typeref(type);
+       type_t *const type = skip_typeref(expression->type);
        /* ยง6.5.3.4:2 if the type is a VLA, evaluate the expression. */
        if (is_type_array(type) && type->array.is_vla
                        && expression->tp_expression != NULL) {
@@ -3412,19 +3423,15 @@ static ir_node *get_label_block(label_t *label)
  * Pointer to a label.  This is used for the
  * GNU address-of-label extension.
  */
-static ir_node *label_address_to_firm(
-               const label_address_expression_t *label)
+static ir_node *label_address_to_firm(const label_address_expression_t *label)
 {
-       ir_node    *block = get_label_block(label->label);
-       ir_label_t  nr    = get_Block_label(block);
+       dbg_info  *dbgi   = get_dbg_info(&label->base.source_position);
+       ir_node   *block  = get_label_block(label->label);
+       ir_entity *entity = create_Block_entity(block);
 
-       if (nr == 0) {
-               nr = get_irp_next_label_nr();
-               set_Block_label(block, nr);
-       }
        symconst_symbol value;
-       value.label = nr;
-       return new_SymConst(mode_P_code, value, symconst_label);
+       value.entity_p = entity;
+       return new_d_SymConst(dbgi, mode_P_code, value, symconst_addr_ent);
 }
 
 /**
@@ -3849,6 +3856,27 @@ static void walk_designator(type_path_t *path, const designator_t *designator)
                        }
                        assert(iter != NULL);
 
+                       /* revert previous initialisations of other union elements */
+                       if (type->kind == TYPE_COMPOUND_UNION) {
+                               ir_initializer_t *initializer = top->initializer;
+                               if (initializer != NULL
+                                       && get_initializer_kind(initializer) == IR_INITIALIZER_COMPOUND) {
+                                       /* are we writing to a new element? */
+                                       ir_initializer_t *oldi
+                                               = get_initializer_compound_value(initializer, index);
+                                       if (get_initializer_kind(oldi) == IR_INITIALIZER_NULL) {
+                                               /* clear initializer */
+                                               size_t len
+                                                       = get_initializer_compound_n_entries(initializer);
+                                               ir_initializer_t *nulli = get_initializer_null();
+                                               for (size_t i = 0; i < len; ++i) {
+                                                       set_initializer_compound_value(initializer, i,
+                                                                                      nulli);
+                                               }
+                                       }
+                               }
+                       }
+
                        top->type           = orig_type;
                        top->compound_entry = iter;
                        top->index          = index;
@@ -3892,6 +3920,7 @@ static void advance_current_object(type_path_t *path)
 
        type_t *type = skip_typeref(top->type);
        if (is_type_union(type)) {
+               /* only the first element is initialized in unions */
                top->compound_entry = NULL;
        } else if (is_type_struct(type)) {
                entity_t *entry = top->compound_entry;
@@ -3935,8 +3964,18 @@ static ir_initializer_t *create_ir_initializer_value(
        if (is_type_compound(initializer->value->base.type)) {
                panic("initializer creation for compounds not implemented yet");
        }
-       ir_node *value = expression_to_firm(initializer->value);
-       type_t  *type  = initializer->value->base.type;
+       type_t       *type = initializer->value->base.type;
+       expression_t *expr = initializer->value;
+       if (initializer_use_bitfield_basetype) {
+               type_t *skipped = skip_typeref(type);
+               if (skipped->kind == TYPE_BITFIELD) {
+                       /* remove the bitfield cast... */
+                       assert(expr->kind == EXPR_UNARY_CAST_IMPLICIT);
+                       expr = expr->unary.value;
+                       type = skipped->bitfield.base_type;
+               }
+       }
+       ir_node *value = expression_to_firm(expr);
        ir_mode *mode  = get_ir_mode_storage(type);
        value          = create_conv(NULL, value, mode);
        return create_initializer_const(value);
@@ -4097,58 +4136,12 @@ static ir_initializer_t *create_ir_initializer(
        panic("unknown initializer");
 }
 
-static void create_dynamic_null_initializer(ir_type *type, dbg_info *dbgi,
-               ir_node *base_addr)
-{
-       if (is_atomic_type(type)) {
-               ir_mode *mode = get_type_mode(type);
-               tarval  *zero = get_mode_null(mode);
-               ir_node *cnst = new_d_Const(dbgi, zero);
-
-               /* TODO: bitfields */
-               ir_node *mem    = get_store();
-               ir_node *store  = new_d_Store(dbgi, mem, base_addr, cnst, cons_none);
-               ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
-               set_store(proj_m);
-       } else {
-               assert(is_compound_type(type));
-
-               int n_members;
-               if (is_Array_type(type)) {
-                       assert(has_array_upper_bound(type, 0));
-                       n_members = get_array_upper_bound_int(type, 0);
-               } else {
-                       n_members = get_compound_n_members(type);
-               }
-
-               for (int i = 0; i < n_members; ++i) {
-                       ir_node *addr;
-                       ir_type *irtype;
-                       if (is_Array_type(type)) {
-                               ir_entity *entity   = get_array_element_entity(type);
-                               tarval    *index_tv = new_tarval_from_long(i, mode_uint);
-                               ir_node   *cnst     = new_d_Const(dbgi, index_tv);
-                               ir_node   *in[1]    = { cnst };
-                               irtype = get_array_element_type(type);
-                               addr   = new_d_Sel(dbgi, new_NoMem(), base_addr, 1, in, entity);
-                       } else {
-                               ir_entity *member = get_compound_member(type, i);
-
-                               irtype = get_entity_type(member);
-                               addr   = new_d_simpleSel(dbgi, new_NoMem(), base_addr, member);
-                       }
-
-                       create_dynamic_null_initializer(irtype, dbgi, addr);
-               }
-       }
-}
-
 static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
                ir_entity *entity, ir_type *type, dbg_info *dbgi, ir_node *base_addr)
 {
        switch(get_initializer_kind(initializer)) {
        case IR_INITIALIZER_NULL: {
-               create_dynamic_null_initializer(type, dbgi, base_addr);
+               /* NULL is undefined for dynamic initializers */
                return;
        }
        case IR_INITIALIZER_CONST: {
@@ -4264,8 +4257,13 @@ static void create_local_initializer(initializer_t *initializer, dbg_info *dbgi,
        }
 
        if (!is_constant_initializer(initializer)) {
+               bool old_initializer_use_bitfield_basetype
+                       = initializer_use_bitfield_basetype;
+               initializer_use_bitfield_basetype = true;
                ir_initializer_t *irinitializer
                        = create_ir_initializer(initializer, type);
+               initializer_use_bitfield_basetype
+                       = old_initializer_use_bitfield_basetype;
 
                create_dynamic_initializer(irinitializer, dbgi, entity);
                return;
@@ -4599,7 +4597,11 @@ static void create_local_declaration(entity_t *entity)
 
        switch ((storage_class_tag_t) entity->declaration.storage_class) {
        case STORAGE_CLASS_STATIC:
-               create_local_static_variable(entity);
+               if (entity->kind == ENTITY_FUNCTION) {
+                       (void)get_function_entity(entity, NULL);
+               } else {
+                       create_local_static_variable(entity);
+               }
                return;
        case STORAGE_CLASS_EXTERN:
                if (entity->kind == ENTITY_FUNCTION) {
@@ -4985,10 +4987,15 @@ static ir_node *get_break_label(void)
 
 static void switch_statement_to_firm(switch_statement_t *statement)
 {
-       dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
+       ir_node  *first_block = NULL;
+       dbg_info *dbgi        = get_dbg_info(&statement->base.source_position);
+       ir_node  *cond        = NULL;
 
-       ir_node *expression  = expression_to_firm(statement->expression);
-       ir_node *cond        = new_d_Cond(dbgi, expression);
+       if (get_cur_block() != NULL) {
+               ir_node *expression = expression_to_firm(statement->expression);
+               cond                = new_d_Cond(dbgi, expression);
+               first_block         = get_cur_block();
+       }
 
        set_cur_block(NULL);
 
@@ -5063,8 +5070,8 @@ static void switch_statement_to_firm(switch_statement_t *statement)
                add_immBlock_pred(get_break_label(), jmp);
        }
 
-       if (!saw_default_label) {
-               set_cur_block(get_nodes_block(cond));
+       if (!saw_default_label && first_block != NULL) {
+               set_cur_block(first_block);
                ir_node *const proj = new_d_defaultProj(dbgi, cond,
                                                        statement->default_proj_nr);
                add_immBlock_pred(get_break_label(), proj);
@@ -5092,24 +5099,26 @@ static void case_label_to_firm(const case_label_statement_t *statement)
        ir_node *const fallthrough = (get_cur_block() == NULL ? NULL : new_Jmp());
 
        ir_node *proj;
-       ir_node *block     = new_immBlock();
-
-       set_cur_block(get_nodes_block(current_switch_cond));
-       if (statement->expression != NULL) {
-               long pn     = statement->first_case;
-               long end_pn = statement->last_case;
-               assert(pn <= end_pn);
-               /* create jumps for all cases in the given range */
-               do {
-                       proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
-                       add_immBlock_pred(block, proj);
-               } while (pn++ < end_pn);
-       } else {
-               saw_default_label = true;
-               proj = new_d_defaultProj(dbgi, current_switch_cond,
-                                        current_switch->default_proj_nr);
+       ir_node *block = new_immBlock();
 
-               add_immBlock_pred(block, proj);
+       if (current_switch_cond != NULL) {
+               set_cur_block(get_nodes_block(current_switch_cond));
+               if (statement->expression != NULL) {
+                       long pn     = statement->first_case;
+                       long end_pn = statement->last_case;
+                       assert(pn <= end_pn);
+                       /* create jumps for all cases in the given range */
+                       do {
+                               proj = new_d_Proj(dbgi, current_switch_cond, mode_X, pn);
+                               add_immBlock_pred(block, proj);
+                       } while (pn++ < end_pn);
+               } else {
+                       saw_default_label = true;
+                       proj = new_d_defaultProj(dbgi, current_switch_cond,
+                                                                        current_switch->default_proj_nr);
+
+                       add_immBlock_pred(block, proj);
+               }
        }
 
        if (fallthrough != NULL) {
@@ -5248,7 +5257,7 @@ static void asm_statement_to_firm(const asm_statement_t *statement)
                                char     buf[64];
                                ir_node *value = get_value_from_lvalue(expr, addr);
 
-                               snprintf(buf, sizeof(buf), "%u", pos);
+                               snprintf(buf, sizeof(buf), "%u", (unsigned) out_size);
 
                                ir_asm_constraint constraint;
                                constraint.pos              = pos;
@@ -5562,7 +5571,7 @@ static void initialize_function_parameters(entity_t *entity)
 
        if (entity->function.need_closure) {
                /* add an extra parameter for the static link */
-               entity->function.static_link = new_r_Proj(irg, start_block, args, mode_P_data, 0);
+               entity->function.static_link = new_r_Proj(start_block, args, mode_P_data, 0);
                ++first_param_nr;
        }
 
@@ -5596,7 +5605,7 @@ static void initialize_function_parameters(entity_t *entity)
                ir_mode *param_mode   = get_type_mode(param_irtype);
 
                long     pn    = n + first_param_nr;
-               ir_node *value = new_r_Proj(irg, start_block, args, param_mode, pn);
+               ir_node *value = new_r_Proj(start_block, args, param_mode, pn);
 
                ir_mode *mode = get_ir_mode_storage(type);
                value = create_conv(NULL, value, mode);
@@ -5694,6 +5703,10 @@ static void create_function(entity_t *entity)
        if (entity->function.statement == NULL)
                return;
 
+       if (is_main(entity) && firm_opt.os_support == OS_SUPPORT_MINGW) {
+               prepare_main_collect2(entity);
+       }
+
        inner_functions     = NULL;
        current_trampolines = NULL;
 
@@ -5864,6 +5877,8 @@ static void scope_to_firm(scope_t *scope)
                        (void)get_function_entity(entity, NULL);
                } else if (entity->kind == ENTITY_VARIABLE) {
                        create_global_variable(entity);
+               } else if (entity->kind == ENTITY_NAMESPACE) {
+                       scope_to_firm(&entity->namespacee.members);
                }
        }