- size_t misalign = offset % align_all;
- if(misalign > 0 || bit_offset > 0) {
- offset += align_all - misalign;
- }
-
- if(outer_offset != NULL) {
- *outer_offset = offset;
- *outer_align = align_all;
- } else {
- set_type_alignment_bytes(irtype, align_all);
- set_type_size_bytes(irtype, offset);
- set_type_state(irtype, layout_fixed);
- }
-
- return irtype;
-}
-
-static ir_type *create_union_type(compound_type_t *type, ir_type *irtype,
- size_t *outer_offset, size_t *outer_align)
-{
- declaration_t *declaration = type->declaration;
- if(declaration->v.irtype != NULL) {
- return declaration->v.irtype;
- }
-
- size_t align_all = 1;
- size_t offset = 0;
- size_t size = 0;
-
- if(irtype == NULL) {
- symbol_t *symbol = declaration->symbol;
- ident *id;
- if(symbol != NULL) {
- id = unique_ident(symbol->string);
- } else {
- id = unique_ident("__anonymous_union");
- }
- dbg_info *dbgi = get_dbg_info(&type->type.source_position);
-
- irtype = new_d_type_union(id, dbgi);
-
- declaration->v.irtype = irtype;
- type->type.firm_type = irtype;
- } else {
- offset = *outer_offset;
- align_all = *outer_align;
- }
-
- type->type.firm_type = irtype;
-
- declaration_t *entry = declaration->scope.declarations;
- for( ; entry != NULL; entry = entry->next) {
- if(entry->namespc != NAMESPACE_NORMAL)
- continue;
-
- symbol_t *symbol = entry->symbol;
- type_t *entry_type = skip_typeref(entry->type);
- ir_type *entry_ir_type = get_ir_type(entry_type);
-
- ident *ident;
- if(symbol != NULL) {
- ident = new_id_from_str(entry->symbol->string);
- } else {
- size_t offs = offset;
- if(entry_type->kind == TYPE_COMPOUND_STRUCT) {
- create_struct_type(&entry_type->compound, irtype, &offs,
- &align_all);
- continue;
- } else if(entry_type->kind == TYPE_COMPOUND_UNION) {
- create_union_type(&entry_type->compound, irtype, &offs,
- &align_all);
- continue;
- } else {
- panic("anonymous union member must be struct or union");
- }
- size_t entry_size = offs - offset;
- if(entry_size > size) {