+typedef struct compound_graph_path_entry_t compound_graph_path_entry_t;
+
+enum compound_graph_entry_type_t {
+ COMPOUND_GRAPH_ENTRY_ARRAY,
+ COMPOUND_GRAPH_ENTRY_COMPOUND
+};
+
+struct compound_graph_path_entry_t {
+ int type;
+ union {
+ ir_entity *entity;
+ int array_index;
+ } v;
+ compound_graph_path_entry_t *prev;
+};
+
+static void create_initializer_list(initializer_list_t *initializer,
+ type_t *type, ir_entity *entity,
+ compound_graph_path_entry_t *entry,
+ int len);
+
+static void create_initializer_value(initializer_value_t *initializer,
+ ir_entity *entity,
+ compound_graph_path_entry_t *entry,
+ int len)
+{
+ ir_node *node = expression_to_firm(initializer->value);
+
+ ir_type *type = get_entity_type(entity);
+ compound_graph_path *path = new_compound_graph_path(type, len);
+
+ int i = len - 1;
+ for( ; entry != NULL; entry = entry->prev, --i) {
+ assert(i >= 0);
+ if(entry->type == COMPOUND_GRAPH_ENTRY_COMPOUND) {
+ set_compound_graph_path_node(path, i, entry->v.entity);
+ } else {
+ assert(entry->type == COMPOUND_GRAPH_ENTRY_ARRAY);
+ set_compound_graph_path_array_index(path, i, entry->v.array_index);
+ }
+ }
+ assert(i == -1);
+
+ add_compound_ent_value_w_path(entity, node, path);
+}
+
+static void create_initializer_compound(initializer_list_t *initializer,
+ compound_type_t *type,
+ ir_entity *entity,
+ compound_graph_path_entry_t *last_entry,
+ int len)
+{
+ declaration_t *compound_declaration = type->declaration;
+
+ declaration_t *compound_entry = compound_declaration->context.declarations;
+
+ compound_graph_path_entry_t entry;
+ entry.type = COMPOUND_GRAPH_ENTRY_COMPOUND;
+ entry.prev = last_entry;
+ ++len;
+
+ size_t i = 0;
+ for( ; compound_entry != NULL; compound_entry = compound_entry->next) {
+ if(compound_entry->symbol == NULL)
+ continue;
+ if(compound_entry->namespc != NAMESPACE_NORMAL)
+ continue;
+
+ if(i >= initializer->len)
+ break;
+
+ entry.v.entity = compound_entry->v.entity;
+
+ initializer_t *sub_initializer = initializer->initializers[i];
+
+ assert(compound_entry != NULL);
+ assert(compound_entry->declaration_type
+ == DECLARATION_TYPE_COMPOUND_MEMBER);
+
+ if(sub_initializer->type == INITIALIZER_VALUE) {
+ create_initializer_value((initializer_value_t*) sub_initializer,
+ entity, &entry, len);
+ } else {
+ assert(sub_initializer->type == INITIALIZER_LIST);
+ create_initializer_list((initializer_list_t*) sub_initializer,
+ compound_entry->type, entity, &entry, len);
+ }
+
+ ++i;
+ }
+}
+
+static void create_initializer_array(initializer_list_t *initializer,
+ array_type_t *type, ir_entity *entity,
+ compound_graph_path_entry_t *last_entry,
+ int len)
+{
+ type_t *element_type = type->element_type;
+
+ compound_graph_path_entry_t entry;
+ entry.type = COMPOUND_GRAPH_ENTRY_ARRAY;
+ entry.prev = last_entry;
+ ++len;
+
+ for(size_t i = 0; i < initializer->len; ++i) {
+ entry.v.array_index = i;
+
+ initializer_t *sub_initializer = initializer->initializers[i];
+
+ if(sub_initializer->type == INITIALIZER_VALUE) {
+ create_initializer_value((initializer_value_t*) sub_initializer,
+ entity, &entry, len);
+ } else {
+ assert(sub_initializer->type == INITIALIZER_LIST);
+ create_initializer_list((initializer_list_t*) sub_initializer,
+ element_type, entity, &entry, len);
+ }
+ }
+}
+
+static void create_initializer_list(initializer_list_t *initializer,
+ type_t *type, ir_entity *entity,
+ compound_graph_path_entry_t *entry, int len)
+{
+ if(type->type == TYPE_ARRAY) {
+ create_initializer_array(initializer, (array_type_t*) type,
+ entity, entry, len);
+ } else {
+ assert(type->type == TYPE_COMPOUND_STRUCT
+ || type->type == TYPE_COMPOUND_UNION);
+ create_initializer_compound(initializer, (compound_type_t*) type,
+ entity, entry, len);
+ }
+}
+