ast2firm: Factorise code to convert a value to its storage type.
[cparser] / ast2firm.c
index de449ff..9129e78 100644 (file)
@@ -143,7 +143,7 @@ static ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos)
        const entity_t *entity = get_irg_loc_description(irg, pos);
 
        if (entity != NULL) {
-               source_position_t const *const pos = &entity->base.source_position;
+               position_t const *const pos = &entity->base.pos;
                warningf(WARN_UNINITIALIZED, pos, "'%N' might be used uninitialized", entity);
        }
        return new_r_Unknown(irg, mode);
@@ -151,7 +151,7 @@ static ir_node *uninitialized_local_var(ir_graph *irg, ir_mode *mode, int pos)
 
 static src_loc_t dbg_retrieve(const dbg_info *dbg)
 {
-       source_position_t const *const pos = (source_position_t const*)dbg;
+       position_t const *const pos = (position_t const*)dbg;
        if (pos) {
                return (src_loc_t){ pos->input_name, pos->lineno, pos->colno };
        } else {
@@ -159,7 +159,7 @@ static src_loc_t dbg_retrieve(const dbg_info *dbg)
        }
 }
 
-static dbg_info *get_dbg_info(const source_position_t *pos)
+static dbg_info *get_dbg_info(const position_t *pos)
 {
        return (dbg_info*) pos;
 }
@@ -209,8 +209,7 @@ static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind)
 {
        unsigned flags = get_atomic_type_flags(kind);
        unsigned size  = get_atomic_type_size(kind);
-       if ((flags & ATOMIC_TYPE_FLAG_FLOAT)
-           && !(flags & ATOMIC_TYPE_FLAG_COMPLEX)) {
+       if (flags & ATOMIC_TYPE_FLAG_FLOAT) {
                switch (size) {
                case 4:  return get_modeF();
                case 8:  return get_modeD();
@@ -271,35 +270,50 @@ static unsigned count_parameters(const function_type_t *function_type)
        return count;
 }
 
-/**
- * Creates a Firm type for an atomic type
- */
-static ir_type *create_atomic_type(atomic_type_kind_t akind, const type_t *type)
+static ir_type *create_primitive_irtype(atomic_type_kind_t akind,
+                                        type_dbg_info *dbgi)
 {
        ir_mode        *mode      = atomic_modes[akind];
-       type_dbg_info  *dbgi      = get_type_dbg_info_(type);
        ir_type        *irtype    = new_d_type_primitive(mode, dbgi);
-       il_alignment_t  alignment = get_atomic_type_alignment(akind);
+       unsigned        alignment = get_atomic_type_alignment(akind);
+       unsigned        size      = get_atomic_type_size(akind);
 
-       set_type_size_bytes(irtype, get_atomic_type_size(akind));
+       set_type_size_bytes(irtype, size);
        set_type_alignment_bytes(irtype, alignment);
 
        return irtype;
 }
 
+/**
+ * Creates a Firm type for an atomic type
+ */
+static ir_type *create_atomic_type(atomic_type_kind_t akind, const type_t *type)
+{
+       type_dbg_info *dbgi = get_type_dbg_info_(type);
+       return create_primitive_irtype(akind, dbgi);
+}
+
 /**
  * Creates a Firm type for a complex type
  */
-static ir_type *create_complex_type(const atomic_type_t *type)
+static ir_type *create_complex_type(atomic_type_kind_t akind,
+                                    const type_t *type)
 {
-       atomic_type_kind_t  kind = type->akind;
-       ir_mode            *mode = atomic_modes[kind];
-       ident              *id   = get_mode_ident(mode);
+       type_dbg_info *dbgi   = get_type_dbg_info_(type);
+       ir_type       *etype  = create_primitive_irtype(akind, NULL);
+       ir_type       *irtype = new_d_type_array(1, etype, dbgi);
 
-       (void) id;
+       int align = get_type_alignment_bytes(etype);
+       set_type_alignment_bytes(irtype, align);
+       unsigned n_elements = 2;
+       set_array_bounds_int(irtype, 0, 0, n_elements);
+       size_t elemsize = get_type_size_bytes(etype);
+       if (elemsize % align > 0) {
+               elemsize += align - (elemsize % align);
+       }
+       set_type_size_bytes(irtype, n_elements * elemsize);
 
-       /* FIXME: finish the array */
-       return NULL;
+       return irtype;
 }
 
 /**
@@ -600,7 +614,7 @@ static ir_type *create_compound_type(compound_type_t *const type, bool const inc
                        ident = new_id_from_str(symbol->string);
                }
 
-               dbg_info *dbgi       = get_dbg_info(&entry->base.source_position);
+               dbg_info *dbgi = get_dbg_info(&entry->base.pos);
 
                ir_type *entry_irtype;
                if (entry->compound_member.bitfield) {
@@ -682,7 +696,7 @@ ir_type *get_ir_type(type_t *type)
                firm_type = create_atomic_type(type->atomic.akind, type);
                break;
        case TYPE_COMPLEX:
-               firm_type = create_complex_type(&type->atomic);
+               firm_type = create_complex_type(type->atomic.akind, type);
                break;
        case TYPE_IMAGINARY:
                firm_type = create_imaginary_type(&type->atomic);
@@ -981,7 +995,7 @@ static ir_entity *get_function_entity(entity_t *entity, ir_type *owner_type)
        else
                nested_function = true;
 
-       dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
+       dbg_info *const dbgi = get_dbg_info(&entity->base.pos);
        irentity = new_d_entity(owner_type, id, ir_type_method, dbgi);
 
        ident *ld_id;
@@ -1120,6 +1134,12 @@ static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode)
        return new_d_Conv(dbgi, value, dest_mode);
 }
 
+static ir_node *conv_to_storage_type(dbg_info *const dbgi, ir_node *const val, type_t *const type)
+{
+       ir_mode *const mode = get_ir_mode_storage(type);
+       return create_conv(dbgi, val, mode);
+}
+
 /**
  * Creates a SymConst node representing a string constant.
  *
@@ -1127,7 +1147,7 @@ static ir_node *create_conv(dbg_info *dbgi, ir_node *value, ir_mode *dest_mode)
  * @param id_prefix  a prefix for the name of the generated string constant
  * @param value      the value of the string constant
  */
-static ir_node *string_to_firm(source_position_t const *const src_pos, char const *const id_prefix, string_t const *const value)
+static ir_node *string_to_firm(position_t const *const src_pos, char const *const id_prefix, string_t const *const value)
 {
        size_t            const slen        = get_string_len(value) + 1;
        ir_initializer_t *const initializer = create_initializer_compound(slen);
@@ -1278,7 +1298,7 @@ static ir_node *literal_to_firm(const literal_expression_t *literal)
                panic("invalid literal kind");
        }
 
-       dbg_info *dbgi       = get_dbg_info(&literal->base.source_position);
+       dbg_info *dbgi       = get_dbg_info(&literal->base.pos);
        ir_node  *res        = new_d_Const(dbgi, tv);
        ir_mode  *mode_arith = get_ir_mode_arithmetic(type);
        return create_conv(dbgi, res, mode_arith);
@@ -1328,7 +1348,7 @@ static ir_node *char_literal_to_firm(string_literal_expression_t const *literal)
                panic("invalid literal kind");
        }
 
-       dbg_info *dbgi       = get_dbg_info(&literal->base.source_position);
+       dbg_info *dbgi       = get_dbg_info(&literal->base.pos);
        ir_node  *res        = new_d_Const(dbgi, tv);
        ir_mode  *mode_arith = get_ir_mode_arithmetic(type);
        return create_conv(dbgi, res, mode_arith);
@@ -1491,7 +1511,7 @@ static ir_node *enum_constant_to_firm(reference_expression_t const *const ref)
 
 static ir_node *reference_addr(const reference_expression_t *ref)
 {
-       dbg_info *dbgi   = get_dbg_info(&ref->base.source_position);
+       dbg_info *dbgi   = get_dbg_info(&ref->base.pos);
        entity_t *entity = ref->entity;
        assert(is_declaration(entity));
 
@@ -1501,7 +1521,7 @@ static ir_node *reference_addr(const reference_expression_t *ref)
                /* for gcc compatibility we have to produce (dummy) addresses for some
                 * builtins which don't have entities */
                if (irentity == NULL) {
-                       source_position_t const *const pos = &ref->base.source_position;
+                       position_t const *const pos = &ref->base.pos;
                        warningf(WARN_OTHER, pos, "taking address of builtin '%N'", ref->entity);
 
                        /* simply create a NULL pointer */
@@ -1561,7 +1581,7 @@ static ir_node *reference_addr(const reference_expression_t *ref)
 
 static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
 {
-       dbg_info *const dbgi   = get_dbg_info(&ref->base.source_position);
+       dbg_info *const dbgi   = get_dbg_info(&ref->base.pos);
        entity_t *const entity = ref->entity;
        assert(is_declaration(entity));
 
@@ -1586,7 +1606,7 @@ static ir_node *reference_expression_to_firm(const reference_expression_t *ref)
  */
 static ir_node *process_builtin_call(const call_expression_t *call)
 {
-       dbg_info *dbgi = get_dbg_info(&call->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&call->base.pos);
 
        assert(call->function->kind == EXPR_REFERENCE);
        reference_expression_t *builtin = &call->function->reference;
@@ -1682,7 +1702,7 @@ static ir_node *process_builtin_call(const call_expression_t *call)
  */
 static ir_node *call_expression_to_firm(const call_expression_t *const call)
 {
-       dbg_info *const dbgi = get_dbg_info(&call->base.source_position);
+       dbg_info *const dbgi = get_dbg_info(&call->base.pos);
        assert(currently_reachable());
 
        expression_t   *function = call->function;
@@ -1756,14 +1776,8 @@ static ir_node *call_expression_to_firm(const call_expression_t *const call)
        for (int n = 0; n < n_parameters; ++n) {
                expression_t *expression = argument->expression;
                ir_node      *arg_node   = expression_to_firm(expression);
-
-               type_t *arg_type = skip_typeref(expression->base.type);
-               if (!is_type_compound(arg_type)) {
-                       ir_mode *const mode = get_ir_mode_storage(arg_type);
-                       arg_node = create_conv(dbgi, arg_node, mode);
-               }
-
-               in[n] = arg_node;
+               type_t       *arg_type   = skip_typeref(expression->base.type);
+               in[n] = conv_to_storage_type(dbgi, arg_node, arg_type);
 
                argument = argument->next;
        }
@@ -1830,10 +1844,7 @@ static ir_node *create_condition_evaluation(expression_t const *expression, jump
 static void assign_value(dbg_info *dbgi, ir_node *addr, type_t *type,
                          ir_node *value)
 {
-       if (!is_type_compound(type)) {
-               ir_mode *mode = get_ir_mode_storage(type);
-               value         = create_conv(dbgi, value, mode);
-       }
+       value = conv_to_storage_type(dbgi, value, type);
 
        ir_node *memory = get_store();
 
@@ -1932,7 +1943,7 @@ static ir_node *bitfield_store_to_firm(dbg_info *dbgi,
 static ir_node *bitfield_extract_to_firm(const select_expression_t *expression,
                                          ir_node *addr)
 {
-       dbg_info *dbgi      = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi      = get_dbg_info(&expression->base.pos);
        entity_t *entity    = expression->compound_entry;
        type_t   *base_type = entity->declaration.type;
        ir_mode  *mode      = get_ir_mode_storage(base_type);
@@ -1991,13 +2002,9 @@ static void construct_select_compound(const select_expression_t *expression)
 static ir_node *set_value_for_expression_addr(const expression_t *expression,
                                               ir_node *value, ir_node *addr)
 {
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&expression->base.pos);
        type_t   *type = skip_typeref(expression->base.type);
-
-       if (!is_type_compound(type)) {
-               ir_mode  *mode = get_ir_mode_storage(type);
-               value          = create_conv(dbgi, value, mode);
-       }
+       value = conv_to_storage_type(dbgi, value, type);
 
        if (expression->kind == EXPR_REFERENCE) {
                const reference_expression_t *ref = &expression->reference;
@@ -2066,7 +2073,7 @@ static ir_node *get_value_from_lvalue(const expression_t *expression,
        }
 
        assert(addr != NULL);
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&expression->base.pos);
 
        ir_node *value;
        if (expression->kind == EXPR_SELECT &&
@@ -2083,7 +2090,7 @@ static ir_node *get_value_from_lvalue(const expression_t *expression,
 
 static ir_node *create_incdec(const unary_expression_t *expression)
 {
-       dbg_info *const     dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *const     dbgi = get_dbg_info(&expression->base.pos);
        const expression_t *value_expr = expression->value;
        ir_node            *addr       = expression_to_addr(value_expr);
        ir_node            *value      = get_value_from_lvalue(value_expr, addr);
@@ -2294,7 +2301,7 @@ static ir_node *create_cast(dbg_info *dbgi, ir_node *value_node,
 
 static ir_node *unary_expression_to_firm(const unary_expression_t *expression)
 {
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&expression->base.pos);
        type_t   *type = skip_typeref(expression->base.type);
 
        const expression_t *value = expression->value;
@@ -2520,7 +2527,7 @@ normal_node:
 
 static ir_node *create_lazy_op(const binary_expression_t *expression)
 {
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&expression->base.pos);
        type_t   *type = skip_typeref(expression->base.type);
        ir_mode  *mode = get_ir_mode_arithmetic(type);
 
@@ -2550,12 +2557,9 @@ static ir_node *create_lazy_op(const binary_expression_t *expression)
                                        dbgi);
 }
 
-typedef ir_node * (*create_arithmetic_func)(dbg_info *dbgi, ir_node *left,
-                                            ir_node *right, ir_mode *mode);
-
 static ir_node *create_assign_binop(const binary_expression_t *expression)
 {
-       dbg_info *const     dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *const     dbgi = get_dbg_info(&expression->base.pos);
        const expression_t *left_expr = expression->left;
        type_t             *type      = skip_typeref(left_expr->base.type);
        ir_node            *right     = expression_to_firm(expression->right);
@@ -2591,7 +2595,7 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
        case EXPR_BINARY_ISLESSEQUAL:
        case EXPR_BINARY_ISLESSGREATER:
        case EXPR_BINARY_ISUNORDERED: {
-               dbg_info   *dbgi     = get_dbg_info(&expression->base.source_position);
+               dbg_info   *dbgi     = get_dbg_info(&expression->base.pos);
                ir_node    *left     = expression_to_firm(expression->left);
                ir_node    *right    = expression_to_firm(expression->right);
                ir_relation relation = get_relation(kind);
@@ -2622,7 +2626,7 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
        case EXPR_BINARY_SHIFTLEFT:
        case EXPR_BINARY_SHIFTRIGHT:
        {
-               dbg_info *dbgi  = get_dbg_info(&expression->base.source_position);
+               dbg_info *dbgi  = get_dbg_info(&expression->base.pos);
                ir_node  *left  = expression_to_firm(expression->left);
                ir_node  *right = expression_to_firm(expression->right);
                return create_op(dbgi, expression, left, right);
@@ -2653,7 +2657,7 @@ static ir_node *binary_expression_to_firm(const binary_expression_t *expression)
 
 static ir_node *array_access_addr(const array_access_expression_t *expression)
 {
-       dbg_info *dbgi        = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi        = get_dbg_info(&expression->base.pos);
        ir_node  *base_addr   = expression_to_firm(expression->array_ref);
        ir_node  *offset      = expression_to_firm(expression->index);
        type_t   *ref_type    = skip_typeref(expression->array_ref->base.type);
@@ -2666,7 +2670,7 @@ static ir_node *array_access_addr(const array_access_expression_t *expression)
 static ir_node *array_access_to_firm(
                const array_access_expression_t *expression)
 {
-       dbg_info *dbgi   = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi   = get_dbg_info(&expression->base.pos);
        ir_node  *addr   = array_access_addr(expression);
        type_t   *type   = revert_automatic_type_conversion(
                        (const expression_t*) expression);
@@ -2723,7 +2727,7 @@ static ir_node *offsetof_to_firm(const offsetof_expression_t *expression)
        ir_mode   *mode   = get_ir_mode_arithmetic(expression->base.type);
        long       offset = get_offsetof_offset(expression);
        ir_tarval *tv     = new_tarval_from_long(offset, mode);
-       dbg_info  *dbgi   = get_dbg_info(&expression->base.source_position);
+       dbg_info  *dbgi   = get_dbg_info(&expression->base.pos);
 
        return new_d_Const(dbgi, tv);
 }
@@ -2755,11 +2759,13 @@ static ir_entity *create_initializer_entity(dbg_info *dbgi,
 
 static ir_node *compound_literal_addr(compound_literal_expression_t const *const expression)
 {
-       dbg_info      *dbgi        = get_dbg_info(&expression->base.source_position);
+       dbg_info      *dbgi        = get_dbg_info(&expression->base.pos);
        type_t        *type        = expression->type;
        initializer_t *initializer = expression->initializer;
 
-       if (is_constant_initializer(initializer) == EXPR_CLASS_CONSTANT) {
+       if (expression->global_scope ||
+               ((type->base.qualifiers & TYPE_QUALIFIER_CONST)
+           && is_constant_initializer(initializer) == EXPR_CLASS_CONSTANT)) {
                ir_entity *entity = create_initializer_entity(dbgi, initializer, type);
                return create_symconst(dbgi, entity);
        } else {
@@ -2783,7 +2789,7 @@ static ir_node *compound_literal_addr(compound_literal_expression_t const *const
 
 static ir_node *compound_literal_to_firm(compound_literal_expression_t const* const expr)
 {
-       dbg_info *const dbgi = get_dbg_info(&expr->base.source_position);
+       dbg_info *const dbgi = get_dbg_info(&expr->base.pos);
        type_t   *const type = expr->type;
        ir_node  *const addr = compound_literal_addr(expr);
        return deref_address(dbgi, type, addr);
@@ -2848,7 +2854,7 @@ static ir_node *alignof_to_firm(const typeprop_expression_t *expression)
                alignment = get_type_alignment(type);
        }
 
-       dbg_info  *dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info  *dbgi = get_dbg_info(&expression->base.pos);
        ir_mode   *mode = get_ir_mode_arithmetic(expression->base.type);
        ir_tarval *tv   = new_tarval_from_long(alignment, mode);
        return new_d_Const(dbgi, tv);
@@ -2953,7 +2959,7 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression)
                jump_to_target(&exit_target);
                if (val) {
                        ir_node  *const in[] = { val, false_val };
-                       dbg_info *const dbgi = get_dbg_info(&expression->base.source_position);
+                       dbg_info *const dbgi = get_dbg_info(&expression->base.pos);
                        val = new_rd_Phi(dbgi, exit_target.block, lengthof(in), in, get_irn_mode(val));
                } else {
                        val = false_val;
@@ -2974,7 +2980,7 @@ static ir_node *conditional_to_firm(const conditional_expression_t *expression)
  */
 static ir_node *select_addr(const select_expression_t *expression)
 {
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&expression->base.pos);
 
        construct_select_compound(expression);
 
@@ -2998,7 +3004,7 @@ static ir_node *select_addr(const select_expression_t *expression)
 
 static ir_node *select_to_firm(const select_expression_t *expression)
 {
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&expression->base.pos);
        ir_node  *addr = select_addr(expression);
        type_t   *type = revert_automatic_type_conversion(
                        (const expression_t*) expression);
@@ -3106,7 +3112,7 @@ static ir_node *classify_type_to_firm(const classify_type_expression_t *const ex
        }
 
 make_const:;
-       dbg_info  *const dbgi = get_dbg_info(&expr->base.source_position);
+       dbg_info  *const dbgi = get_dbg_info(&expr->base.pos);
        ir_mode   *const mode = atomic_modes[ATOMIC_TYPE_INT];
        ir_tarval *const tv   = new_tarval_from_long(tc, mode);
        return new_d_Const(dbgi, tv);
@@ -3120,18 +3126,18 @@ static ir_node *function_name_to_firm(
        case FUNCNAME_PRETTY_FUNCTION:
        case FUNCNAME_FUNCDNAME:
                if (current_function_name == NULL) {
-                       source_position_t const *const src_pos = &expr->base.source_position;
-                       char              const *const name    = current_function_entity->base.symbol->string;
-                       string_t                 const string  = { name, strlen(name), STRING_ENCODING_CHAR };
+                       position_t const *const src_pos = &expr->base.pos;
+                       char       const *const name    = current_function_entity->base.symbol->string;
+                       string_t          const string  = { name, strlen(name), STRING_ENCODING_CHAR };
                        current_function_name = string_to_firm(src_pos, "__func__.%u", &string);
                }
                return current_function_name;
        case FUNCNAME_FUNCSIG:
                if (current_funcsig == NULL) {
-                       source_position_t const *const src_pos = &expr->base.source_position;
-                       ir_entity               *const ent     = get_irg_entity(current_ir_graph);
-                       char              const *const name    = get_entity_ld_name(ent);
-                       string_t                 const string  = { name, strlen(name), STRING_ENCODING_CHAR };
+                       position_t const *const src_pos = &expr->base.pos;
+                       ir_entity        *const ent     = get_irg_entity(current_ir_graph);
+                       char       const *const name    = get_entity_ld_name(ent);
+                       string_t          const string  = { name, strlen(name), STRING_ENCODING_CHAR };
                        current_funcsig = string_to_firm(src_pos, "__FUNCSIG__.%u", &string);
                }
                return current_funcsig;
@@ -3160,7 +3166,7 @@ static ir_node *va_start_expression_to_firm(
        }
 
        ir_node  *const frame   = get_irg_frame(current_ir_graph);
-       dbg_info *const dbgi    = get_dbg_info(&expr->base.source_position);
+       dbg_info *const dbgi    = get_dbg_info(&expr->base.pos);
        ir_node  *const no_mem  = new_NoMem();
        ir_node  *const arg_sel = new_d_simpleSel(dbgi, no_mem, frame, param_ent);
 
@@ -3175,7 +3181,7 @@ static ir_node *va_arg_expression_to_firm(const va_arg_expression_t *const expr)
        expression_t *const ap_expr = expr->ap;
        ir_node      *const ap_addr = expression_to_addr(ap_expr);
        ir_node      *const ap      = get_value_from_lvalue(ap_expr, ap_addr);
-       dbg_info     *const dbgi    = get_dbg_info(&expr->base.source_position);
+       dbg_info     *const dbgi    = get_dbg_info(&expr->base.pos);
        ir_node      *const res     = deref_address(dbgi, type, ap);
 
        ir_node      *const cnst    = get_type_size_node(expr->base.type);
@@ -3273,7 +3279,7 @@ static ir_node *label_address_to_firm(const label_address_expression_t *label)
 
        symconst_symbol value;
        value.entity_p = create_Block_entity(label->label->indirect_block);
-       dbg_info *const dbgi = get_dbg_info(&label->base.source_position);
+       dbg_info *const dbgi = get_dbg_info(&label->base.pos);
        return new_d_SymConst(dbgi, mode_P_code, value, symconst_addr_ent);
 }
 
@@ -3316,7 +3322,7 @@ static ir_node *_expression_to_firm(expression_t const *const expr)
        case EXPR_VA_COPY:                    return va_copy_expression_to_firm(      &expr->va_copye);
        case EXPR_VA_START:                   return va_start_expression_to_firm(     &expr->va_starte);
 
-       case EXPR_STRING_LITERAL: return string_to_firm(&expr->base.source_position, "str.%u", &expr->string_literal.value);
+       case EXPR_STRING_LITERAL: return string_to_firm(&expr->base.pos, "str.%u", &expr->string_literal.value);
 
        case EXPR_ERROR: break;
        }
@@ -3387,7 +3393,7 @@ static ir_node *expression_to_firm(const expression_t *expression)
        }
 
        /* we have to produce a 0/1 from the mode_b expression */
-       dbg_info *dbgi = get_dbg_info(&expression->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&expression->base.pos);
        ir_mode  *mode = get_ir_mode_arithmetic(expression->base.type);
        return produce_condition_result(expression, mode, dbgi);
 }
@@ -3432,7 +3438,7 @@ static ir_node *create_condition_evaluation(expression_t const *const expression
                        jump_to_target(true_target);
                }
        } else {
-               dbg_info *dbgi       = get_dbg_info(&expression->base.source_position);
+               dbg_info *dbgi       = get_dbg_info(&expression->base.pos);
                ir_node  *condition  = create_conv(dbgi, cond_expr, mode_b);
                ir_node  *cond       = new_d_Cond(dbgi, condition);
                ir_node  *true_proj  = new_d_Proj(dbgi, cond, mode_X, pn_Cond_true);
@@ -3464,7 +3470,7 @@ static void create_variable_entity(entity_t *variable,
 
        ident     *const id        = new_id_from_str(variable->base.symbol->string);
        ir_type   *const irtype    = get_ir_type(type);
-       dbg_info  *const dbgi      = get_dbg_info(&variable->base.source_position);
+       dbg_info  *const dbgi      = get_dbg_info(&variable->base.pos);
        ir_entity *const irentity  = new_d_entity(parent_type, id, irtype, dbgi);
        unsigned         alignment = variable->declaration.alignment;
 
@@ -3738,26 +3744,26 @@ static ir_initializer_t *create_ir_initializer_value(
                const initializer_value_t *initializer)
 {
        expression_t *expr = initializer->value;
-       type_t       *type = expr->base.type;
+       type_t       *type = skip_typeref(expr->base.type);
 
        if (is_type_compound(type)) {
                if (expr->kind == EXPR_UNARY_CAST) {
                        expr = expr->unary.value;
-                       type = expr->base.type;
+                       type = skip_typeref(expr->base.type);
                }
                /* must be a compound literal... */
-               if (expr->kind != EXPR_COMPOUND_LITERAL)
-                       panic("initializer creation for compounds needs compound literals");
-               return create_ir_initializer(expr->compound_literal.initializer, type);
+               if (expr->kind == EXPR_COMPOUND_LITERAL) {
+                       return create_ir_initializer(expr->compound_literal.initializer,
+                                                    type);
+               }
        }
 
        ir_node *value = expression_to_firm(expr);
-       ir_mode *mode  = get_ir_mode_storage(type);
-       value          = create_conv(NULL, value, mode);
+       value = conv_to_storage_type(NULL, value, type);
        return create_initializer_const(value);
 }
 
-/** test wether type can be initialized by a string constant */
+/** Tests whether type can be initialized by a string constant */
 static bool is_string_type(type_t *type)
 {
        if (!is_type_array(type))
@@ -3961,11 +3967,17 @@ static void create_dynamic_initializer_sub(ir_initializer_t *initializer,
                        return;
                }
 
-               assert(get_type_mode(type) == get_irn_mode(node));
-               ir_node *mem    = get_store();
-               ir_node *store  = new_d_Store(dbgi, mem, base_addr, node, cons_none);
-               ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
-               set_store(proj_m);
+               ir_node *mem = get_store();
+               ir_node *new_mem;
+               if (is_compound_type(ent_type)) {
+                       ir_node *copyb = new_d_CopyB(dbgi, mem, base_addr, node, ent_type);
+                       new_mem = new_Proj(copyb, mode_M, pn_CopyB_M);
+               } else {
+                       assert(get_type_mode(type) == get_irn_mode(node));
+                       ir_node *store = new_d_Store(dbgi, mem, base_addr, node, cons_none);
+                       new_mem = new_Proj(store, mode_M, pn_Store_M);
+               }
+               set_store(new_mem);
                return;
        }
        case IR_INITIALIZER_TARVAL: {
@@ -4084,7 +4096,7 @@ static void create_initializer_local_variable_entity(entity_t *entity)
 {
        assert(entity->kind == ENTITY_VARIABLE);
        initializer_t *initializer = entity->variable.initializer;
-       dbg_info      *dbgi        = get_dbg_info(&entity->base.source_position);
+       dbg_info      *dbgi        = get_dbg_info(&entity->base.pos);
        ir_entity     *irentity    = entity->variable.v.entity;
        type_t        *type        = entity->declaration.type;
 
@@ -4124,9 +4136,8 @@ static void create_variable_initializer(entity_t *entity)
                }
 
                ir_node  *      node = expression_to_firm(value);
-               dbg_info *const dbgi = get_dbg_info(&entity->base.source_position);
-               ir_mode  *const mode = get_ir_mode_storage(init_type);
-               node = create_conv(dbgi, node, mode);
+               dbg_info *const dbgi = get_dbg_info(&entity->base.pos);
+               node = conv_to_storage_type(dbgi, node, init_type);
 
                if (declaration_kind == DECLARATION_KIND_LOCAL_VARIABLE) {
                        set_value(entity->variable.v.value_number, node);
@@ -4175,7 +4186,7 @@ static void allocate_variable_length_array(entity_t *entity)
        assert(entity->variable.initializer == NULL);
        assert(currently_reachable());
 
-       dbg_info *dbgi      = get_dbg_info(&entity->base.source_position);
+       dbg_info *dbgi      = get_dbg_info(&entity->base.pos);
        type_t   *type      = entity->declaration.type;
        ir_type  *el_type   = get_ir_type(type->array.element_type);
 
@@ -4237,7 +4248,7 @@ static void create_local_static_variable(entity_t *entity)
        ir_type  *const var_type = entity->variable.thread_local ?
                get_tls_type() : get_glob_type();
        ir_type  *const irtype   = get_ir_type(type);
-       dbg_info *const dbgi     = get_dbg_info(&entity->base.source_position);
+       dbg_info *const dbgi     = get_dbg_info(&entity->base.pos);
 
        size_t l = strlen(entity->base.symbol->string);
        char   buf[l + sizeof(".%u")];
@@ -4272,17 +4283,16 @@ static ir_node *return_statement_to_firm(return_statement_t *statement)
        if (!currently_reachable())
                return NULL;
 
-       dbg_info *const dbgi = get_dbg_info(&statement->base.source_position);
+       dbg_info *const dbgi = get_dbg_info(&statement->base.pos);
        type_t   *const type = skip_typeref(current_function_entity->declaration.type->function.return_type);
        ir_node  *      res  = statement->value ? expression_to_firm(statement->value) : NULL;
 
        int in_len;
        if (!is_type_void(type)) {
-               ir_mode *const mode = get_ir_mode_storage(type);
                if (res) {
-                       res = create_conv(dbgi, res, mode);
+                       res = conv_to_storage_type(dbgi, res, type);
                } else {
-                       res = new_Unknown(mode);
+                       res = new_Unknown(get_ir_mode_storage(type));
                }
                in_len = 1;
        } else {
@@ -4638,7 +4648,7 @@ static ir_switch_table *create_switch_table(const switch_statement_t *statement)
 
 static ir_node *switch_statement_to_firm(switch_statement_t *statement)
 {
-       dbg_info *dbgi        = get_dbg_info(&statement->base.source_position);
+       dbg_info *dbgi        = get_dbg_info(&statement->base.pos);
        ir_node  *switch_node = NULL;
 
        if (currently_reachable()) {
@@ -4740,7 +4750,7 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
                const char *clobber_str = clobber->clobber.begin;
 
                if (!be_is_valid_clobber(clobber_str)) {
-                       errorf(&statement->base.source_position,
+                       errorf(&statement->base.pos,
                                   "invalid clobber '%s' specified", clobber->clobber);
                        continue;
                }
@@ -4787,7 +4797,7 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
                        = be_parse_asm_constraints(constraints);
 
                {
-                       source_position_t const *const pos = &statement->base.source_position;
+                       position_t const *const pos = &statement->base.pos;
                        if (asm_flags & ASM_CONSTRAINT_FLAG_NO_SUPPORT) {
                                warningf(WARN_OTHER, pos, "some constraints in '%s' are not supported", constraints);
                        }
@@ -4848,7 +4858,7 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
                        ++in_size;
                        continue;
                } else {
-                       errorf(&statement->base.source_position,
+                       errorf(&statement->base.pos,
                               "only modifiers but no place set in constraints '%s'",
                               constraints);
                        continue;
@@ -4876,17 +4886,17 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
                        = be_parse_asm_constraints(constraints);
 
                if (asm_flags & ASM_CONSTRAINT_FLAG_NO_SUPPORT) {
-                       errorf(&statement->base.source_position,
+                       errorf(&statement->base.pos,
                               "some constraints in '%s' are not supported", constraints);
                        continue;
                }
                if (asm_flags & ASM_CONSTRAINT_FLAG_INVALID) {
-                       errorf(&statement->base.source_position,
+                       errorf(&statement->base.pos,
                               "some constraints in '%s' are invalid", constraints);
                        continue;
                }
                if (asm_flags & ASM_CONSTRAINT_FLAG_MODIFIER_WRITE) {
-                       errorf(&statement->base.source_position,
+                       errorf(&statement->base.pos,
                               "write flag specified for input constraints '%s'",
                               constraints);
                        continue;
@@ -4906,7 +4916,7 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
                        needs_memory = true;
                        input = expression_to_addr(argument->expression);
                } else {
-                       errorf(&statement->base.source_position,
+                       errorf(&statement->base.pos,
                               "only modifiers but no place set in constraints '%s'",
                               constraints);
                        continue;
@@ -4927,7 +4937,7 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
        ir_asm_constraint *input_constraints = obstack_finish(&asm_obst);
 
        /* create asm node */
-       dbg_info *dbgi = get_dbg_info(&statement->base.source_position);
+       dbg_info *dbgi = get_dbg_info(&statement->base.pos);
 
        ident *asm_text = new_id_from_str(statement->asm_text.begin);
 
@@ -4964,14 +4974,14 @@ static ir_node *asm_statement_to_firm(const asm_statement_t *statement)
 static ir_node *ms_try_statement_to_firm(ms_try_statement_t *statement)
 {
        statement_to_firm(statement->try_statement);
-       source_position_t const *const pos = &statement->base.source_position;
+       position_t const *const pos = &statement->base.pos;
        warningf(WARN_OTHER, pos, "structured exception handling ignored");
        return NULL;
 }
 
 static ir_node *leave_statement_to_firm(leave_statement_t *statement)
 {
-       errorf(&statement->base.source_position, "__leave not supported yet");
+       errorf(&statement->base.pos, "__leave not supported yet");
        return NULL;
 }
 
@@ -5101,7 +5111,7 @@ static void initialize_function_parameters(entity_t *entity)
                assert(parameter->declaration.kind == DECLARATION_KIND_UNKNOWN);
                type_t *type = skip_typeref(parameter->declaration.type);
 
-               dbg_info *const dbgi         = get_dbg_info(&parameter->base.source_position);
+               dbg_info *const dbgi         = get_dbg_info(&parameter->base.pos);
                ir_type  *const param_irtype = get_method_param_type(function_irtype, n);
                if (var_needs_entity(&parameter->variable)) {
                        ir_type   *frame_type = get_irg_frame_type(irg);
@@ -5115,9 +5125,7 @@ static void initialize_function_parameters(entity_t *entity)
                ir_mode *param_mode = get_type_mode(param_irtype);
                long     pn         = n;
                ir_node *value      = new_rd_Proj(dbgi, args, param_mode, pn);
-
-               ir_mode *mode = get_ir_mode_storage(type);
-               value = create_conv(NULL, value, mode);
+               value = conv_to_storage_type(dbgi, value, type);
 
                parameter->declaration.kind        = DECLARATION_KIND_PARAMETER;
                parameter->variable.v.value_number = next_value_number_function;
@@ -5198,7 +5206,6 @@ static void create_function(entity_t *entity)
        current_vararg_entity = NULL;
 
        set_irg_fp_model(irg, firm_fp_model);
-       tarval_enable_fp_ops(1);
        set_irn_dbg_info(get_irg_start_block(irg),
                         get_entity_dbg_info(function_entity));