X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=type.c;h=67aee7687bce477522d62c6593dff5f333b17395;hb=6b26906854c2f5423fa3986a0caf3c23b200b553;hp=27ec5516557071624cb2dbcde02e9c9cadb731bb;hpb=979fce13621246b706781035786b5d11a8e2f608;p=cparser diff --git a/type.c b/type.c index 27ec551..67aee76 100644 --- a/type.c +++ b/type.c @@ -204,7 +204,8 @@ void init_types(void) } unsigned int_size = machine_size < 32 ? 2 : 4; - unsigned long_size = machine_size < 64 ? 4 : 8; + /* long is always 32bit on windows */ + unsigned long_size = c_mode & _MS ? 4 : (machine_size < 64 ? 4 : 8); unsigned llong_size = machine_size < 32 ? 4 : 8; props[ATOMIC_TYPE_INT].size = int_size; @@ -222,14 +223,22 @@ void init_types(void) /* TODO: backend specific, need a way to query the backend for this. * The following are good settings for x86 */ - props[ATOMIC_TYPE_FLOAT].alignment = 4; - props[ATOMIC_TYPE_DOUBLE].alignment = 4; - props[ATOMIC_TYPE_LONG_DOUBLE].alignment = 4; - props[ATOMIC_TYPE_LONGLONG].alignment = 4; - props[ATOMIC_TYPE_ULONGLONG].alignment = 4; - if (firm_opt.os_support == OS_SUPPORT_MACHO) { - props[ATOMIC_TYPE_LONG_DOUBLE].size = 16; - props[ATOMIC_TYPE_LONG_DOUBLE].alignment = 16; + if (machine_size <= 32) { + props[ATOMIC_TYPE_FLOAT].alignment = 4; + props[ATOMIC_TYPE_DOUBLE].alignment = 4; + props[ATOMIC_TYPE_LONG_DOUBLE].alignment = 4; + props[ATOMIC_TYPE_LONGLONG].alignment = 4; + props[ATOMIC_TYPE_ULONGLONG].alignment = 4; + } else { + props[ATOMIC_TYPE_FLOAT].alignment = 4; + props[ATOMIC_TYPE_DOUBLE].alignment = 8; + props[ATOMIC_TYPE_LONG_DOUBLE].alignment = 8; + props[ATOMIC_TYPE_LONGLONG].alignment = 8; + props[ATOMIC_TYPE_ULONGLONG].alignment = 8; + } + if (force_long_double_size > 0) { + props[ATOMIC_TYPE_LONG_DOUBLE].size = force_long_double_size; + props[ATOMIC_TYPE_LONG_DOUBLE].alignment = force_long_double_size; } /* TODO: make this configurable for platforms which do not use byte sized @@ -1009,9 +1018,9 @@ bool is_type_scalar(const type_t *type) assert(!is_typeref(type)); switch (type->kind) { - case TYPE_POINTER: return true; - case TYPE_BUILTIN: return is_type_scalar(type->builtin.real_type); - default: break; + case TYPE_POINTER: return true; + case TYPE_BUILTIN: return is_type_scalar(type->builtin.real_type); + default: break; } return is_type_arithmetic(type); @@ -1682,6 +1691,57 @@ type_t *make_array_type(type_t *element_type, size_t size, return identify_new_type(type); } +static entity_t *pack_bitfield_members_big_endian(il_size_t *struct_offset, + il_alignment_t *struct_alignment, bool packed, entity_t *first) +{ + type_t *current_base_type = NULL; + il_size_t offset = *struct_offset; + il_alignment_t alignment = *struct_alignment; + size_t bit_offset = 0; + + if (packed) + panic("packed bitfields on big-endian arch not supported yet"); + + entity_t *member; + for (member = first; member != NULL; member = member->base.next) { + if (member->kind != ENTITY_COMPOUND_MEMBER) + continue; + + type_t *type = member->declaration.type; + if (type->kind != TYPE_BITFIELD) + break; + + size_t bit_size = type->bitfield.bit_size; + type_t *base_type = skip_typeref(type->bitfield.base_type); + + /* see if we need to start a new "bucket" */ + if (base_type != current_base_type || bit_size > bit_offset) { + if (current_base_type != NULL) + offset += get_type_size(current_base_type); + + current_base_type = base_type; + il_alignment_t base_alignment = get_type_alignment(base_type); + il_alignment_t alignment_mask = base_alignment-1; + if (base_alignment > alignment) + alignment = base_alignment; + offset = (offset + base_alignment-1) & ~alignment_mask; + bit_offset = get_type_size(base_type) * BITS_PER_BYTE; + assert(bit_offset >= bit_size); + } + + bit_offset -= bit_size; + member->compound_member.offset = offset; + member->compound_member.bit_offset = bit_offset; + } + + if (current_base_type != NULL) + offset += get_type_size(current_base_type); + + *struct_offset = offset; + *struct_alignment = alignment; + return member; +} + static entity_t *pack_bitfield_members(il_size_t *struct_offset, il_alignment_t *struct_alignment, bool packed, entity_t *first) @@ -1693,7 +1753,7 @@ static entity_t *pack_bitfield_members(il_size_t *struct_offset, entity_t *member; for (member = first; member != NULL; member = member->base.next) { if (member->kind != ENTITY_COMPOUND_MEMBER) - break; + continue; type_t *type = member->declaration.type; if (type->kind != TYPE_BITFIELD) @@ -1731,7 +1791,6 @@ static entity_t *pack_bitfield_members(il_size_t *struct_offset, *struct_offset = offset; *struct_alignment = alignment; - return member; } @@ -1764,8 +1823,14 @@ void layout_struct_type(compound_type_t *type) } if (skipped->kind == TYPE_BITFIELD) { - entry = pack_bitfield_members(&offset, &alignment, - compound->packed, entry); + if (byte_order_big_endian) { + entry = pack_bitfield_members_big_endian(&offset, &alignment, + compound->packed, + entry); + } else { + entry = pack_bitfield_members(&offset, &alignment, + compound->packed, entry); + } continue; }