+ if (is_type_compound(initializer->value->base.type)) {
+ panic("initializer creation for compounds not implemented yet");
+ }
+ ir_node *value = expression_to_firm(initializer->value);
+ return create_initializer_const(value);
+}
+
+static ir_initializer_t *create_ir_initializer_list(
+ const initializer_list_t *initializer, type_t *type)
+{
+ type_path_t path;
+ memset(&path, 0, sizeof(path));
+ path.top_type = type;
+ path.path = NEW_ARR_F(type_path_entry_t, 0);
+
+ descend_into_subtype(&path);
+
+ for(size_t i = 0; i < initializer->len; ++i) {
+ const initializer_t *sub_initializer = initializer->initializers[i];
+
+ if (sub_initializer->kind == INITIALIZER_DESIGNATOR) {
+ walk_designator(&path, sub_initializer->designator.designator);
+ continue;
+ }
+
+ if (sub_initializer->kind == INITIALIZER_VALUE) {
+ /* we might have to descend into types until we're at a scalar
+ * type */
+ while(true) {
+ type_t *orig_top_type = path.top_type;
+ type_t *top_type = skip_typeref(orig_top_type);
+
+ if (is_type_scalar(top_type))
+ break;
+ descend_into_subtype(&path);
+ }
+ }
+
+ ir_initializer_t *sub_irinitializer
+ = create_ir_initializer(sub_initializer, path.top_type);
+
+ size_t path_len = ARR_LEN(path.path);
+ assert(path_len >= 1);
+ type_path_entry_t *entry = & path.path[path_len-1];
+ ir_initializer_t *tinitializer = entry->initializer;
+ set_initializer_compound_value(tinitializer, entry->index,
+ sub_irinitializer);
+
+ advance_current_object(&path);
+ }
+
+ assert(ARR_LEN(path.path) >= 1);
+ ir_initializer_t *result = path.path[0].initializer;
+ DEL_ARR_F(path.path);
+
+ return result;
+}
+
+static ir_initializer_t *create_ir_initializer_string(
+ const initializer_string_t *initializer, type_t *type)
+{
+ type = skip_typeref(type);
+
+ size_t string_len = initializer->string.size;
+ assert(type->kind == TYPE_ARRAY);
+ assert(type->array.size_constant);
+ size_t len = type->array.size;
+ ir_initializer_t *irinitializer = create_initializer_compound(len);
+
+ const char *string = initializer->string.begin;
+ ir_mode *mode = get_ir_mode(type->array.element_type);
+
+ for(size_t i = 0; i < len; ++i) {
+ char c = 0;
+ if (i < string_len)
+ c = string[i];
+
+ tarval *tv = new_tarval_from_long(c, mode);
+ ir_initializer_t *char_initializer = create_initializer_tarval(tv);
+
+ set_initializer_compound_value(irinitializer, i, char_initializer);
+ }
+
+ return irinitializer;
+}
+
+static ir_initializer_t *create_ir_initializer_wide_string(
+ const initializer_wide_string_t *initializer, type_t *type)
+{
+ size_t string_len = initializer->string.size;
+ assert(type->kind == TYPE_ARRAY);
+ assert(type->array.size_constant);
+ size_t len = type->array.size;
+ ir_initializer_t *irinitializer = create_initializer_compound(len);
+
+ const wchar_rep_t *string = initializer->string.begin;
+ ir_mode *mode = get_type_mode(ir_type_wchar_t);
+
+ for(size_t i = 0; i < len; ++i) {
+ wchar_rep_t c = 0;
+ if (i < string_len) {
+ c = string[i];
+ }
+ tarval *tv = new_tarval_from_long(c, mode);
+ ir_initializer_t *char_initializer = create_initializer_tarval(tv);
+
+ set_initializer_compound_value(irinitializer, i, char_initializer);
+ }
+
+ return irinitializer;
+}
+
+static ir_initializer_t *create_ir_initializer(
+ const initializer_t *initializer, type_t *type)
+{
+ switch(initializer->kind) {
+ case INITIALIZER_STRING:
+ return create_ir_initializer_string(&initializer->string, type);
+
+ case INITIALIZER_WIDE_STRING:
+ return create_ir_initializer_wide_string(&initializer->wide_string,
+ type);
+
+ case INITIALIZER_LIST:
+ return create_ir_initializer_list(&initializer->list, type);
+
+ case INITIALIZER_VALUE:
+ return create_ir_initializer_value(&initializer->value);
+
+ case INITIALIZER_DESIGNATOR:
+ panic("unexpected designator initializer found");
+ }
+ 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, mode, zero);
+
+ /* TODO: bitfields */
+ ir_node *mem = get_store();
+ ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst);
+ 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, mode_uint, 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_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);
+ return;
+ }
+ case IR_INITIALIZER_CONST: {
+ ir_node *node = get_initializer_const_value(initializer);
+ ir_mode *mode = get_irn_mode(node);
+ assert(get_type_mode(type) == mode);
+
+ /* TODO: bitfields... */
+ ir_node *mem = get_store();
+ ir_node *store = new_d_Store(dbgi, mem, base_addr, node);
+ ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
+ set_store(proj_m);
+ return;
+ }
+ case IR_INITIALIZER_TARVAL: {
+ tarval *tv = get_initializer_tarval_value(initializer);
+ ir_mode *mode = get_tarval_mode(tv);
+ ir_node *cnst = new_d_Const(dbgi, mode, tv);
+ assert(get_type_mode(type) == mode);
+
+ /* TODO: bitfields... */
+ ir_node *mem = get_store();
+ ir_node *store = new_d_Store(dbgi, mem, base_addr, cnst);
+ ir_node *proj_m = new_Proj(store, mode_M, pn_Store_M);
+ set_store(proj_m);
+ return;
+ }
+ case IR_INITIALIZER_COMPOUND: {
+ 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);
+ }