X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ast2firm.c;h=1c9c0c44fb67b220fcf1814bcea97c787d545211;hb=508cc42e42c39c77ed2ec0664a09f4911b0603d1;hp=e5eb0d69712e4661f0b9309cede62706f6cda33e;hpb=c1449206f35164b677f1123d20cb2b306e0b4781;p=cparser diff --git a/ast2firm.c b/ast2firm.c index e5eb0d6..1c9c0c4 100644 --- a/ast2firm.c +++ b/ast2firm.c @@ -368,8 +368,9 @@ static ir_type *create_struct_type(compound_type_t *type) int entry_size = get_type_size_bytes(entry_ir_type); int entry_alignment = get_type_alignment_bytes(entry_ir_type); - int misalign = offset % entry_alignment; - offset += misalign; + int misalign = offset % entry_alignment; + if (misalign != 0) + offset += entry_alignment - misalign; ir_entity *entity = new_entity(ir_type, ident, entry_ir_type); set_entity_offset(entity, offset); @@ -1878,6 +1879,112 @@ static void create_declaration_entity(declaration_t *declaration, /* TODO: visibility? */ } +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_list(initializer_list_t *initializer, + type_t *type, ir_entity *entity, + compound_graph_path_entry_t *entry, int len) +{ + if(type->type == TYPE_ARRAY) { + /* TODO */ + } else { + assert(type->type == TYPE_COMPOUND_STRUCT + || type->type == TYPE_COMPOUND_UNION); + create_initializer_compound(initializer, (compound_type_t*) type, + entity, entry, len); + } +} + static void create_initializer(declaration_t *declaration) { initializer_t *initializer = declaration->init.initializer; @@ -1885,21 +1992,30 @@ static void create_initializer(declaration_t *declaration) return; if(initializer->type == INITIALIZER_VALUE) { - initializer_value_t *value = (initializer_value_t*) initializer; - - ir_node *init_node = expression_to_firm(value->value); + initializer_value_t *initializer_value + = (initializer_value_t*) initializer; + ir_node *value = expression_to_firm(initializer_value->value); if(declaration->declaration_type == DECLARATION_TYPE_LOCAL_VARIABLE) { - set_value(declaration->v.value_number, init_node); + set_value(declaration->v.value_number, value); } else { ir_entity *entity = declaration->v.entity; set_entity_variability(entity, variability_initialized); - set_atomic_ent_value(entity, init_node); + set_atomic_ent_value(entity, value); } } else { assert(initializer->type == INITIALIZER_LIST); - panic("list initializer not supported yet"); + initializer_list_t *list = (initializer_list_t*) initializer; + + declaration_type_t declaration_type = declaration->declaration_type; + assert(declaration_type == DECLARATION_TYPE_LOCAL_VARIABLE_ENTITY + || declaration_type == DECLARATION_TYPE_GLOBAL_VARIABLE); + + ir_entity *entity = declaration->v.entity; + set_entity_variability(entity, variability_initialized); + + create_initializer_list(list, declaration->type, entity, NULL, 0); } } @@ -2375,7 +2491,9 @@ static void create_function(declaration_t *declaration) int misalign = 0; if(align > 0) { misalign = offset % align; - offset += misalign; + if(misalign > 0) { + offset += align - misalign; + } } set_entity_offset(entity, offset); @@ -2429,9 +2547,6 @@ static void context_to_firm(context_t *context) void translation_unit_to_firm(translation_unit_t *unit) { - /* remove me later TODO FIXME */ - (void) get_type_size; - /* just to be sure */ continue_label = NULL; break_label = NULL;