types.c
// Recurse through all struct members and determine offsets
// Bit fields are only implemented for integers (32 bits size) according to the C89 spec.
Recurse through all struct members and determine offsets
Bit fields are only implemented for integers (32 bits size) according to the C89 spec.
Recurse through all struct members and determine offsets Bit fields are only implemented for integers ( 32 bits size ) according to the C89 spec .
int recursive_complete_struct_or_union(StructOrUnion *s, int bit_offset) {
    bit_offset = 0;
    int initial_bit_offset = bit_offset;
    int max_size = 0;
    int max_alignment = 0;
    for (StructOrUnionMember **pmember = s->members; *pmember; pmember++) {
        StructOrUnionMember *member = *pmember;
        int size;
        if (member->is_bit_field) {
            size = member->bit_field_size;
            if (!member->bit_field_size) bit_offset = ((bit_offset + 31) & ~31);
            else {
                int new_bit_offset = (bit_offset + member->bit_field_size - 1) & ~31;
                if (new_bit_offset != (bit_offset & ~31)) bit_offset = ((bit_offset + 31) & ~31);
            }
            if (max_alignment < 32) max_alignment = 32;
        }
        else {
            int alignment = s->is_packed ? 8 : get_type_alignment(member->type) * 8;
            if (alignment > max_alignment) max_alignment = alignment;
            bit_offset = ((bit_offset + alignment - 1) & (~(alignment - 1)));
            if (member->type->type == TYPE_STRUCT_OR_UNION) {
                member->type->struct_or_union_desc = dup_struct_or_union(member->type->struct_or_union_desc);
                size = recursive_complete_struct_or_union(member->type->struct_or_union_desc, bit_offset);
            }
            else {
                size = get_type_size(member->type) * 8;
            }
        }
        member->offset = bit_offset >> 3;
        member->bit_field_offset = bit_offset;
        if (size > max_size) max_size = size;
        if (!s->is_union) bit_offset += size;
    }
    s->is_incomplete = 0;
    int size;
    if (s->is_union)
        size = max_size;
    else {
        bit_offset = ((bit_offset + max_alignment  - 1) & (~(max_alignment - 1)));
        size = bit_offset - initial_bit_offset;
    }
    s->size = size >> 3;
    return size;
}
int recursive_complete_struct_or_union ( StructOrUnion * s , int bit_offset ) { bit_offset = 0 ; int initial_bit_offset = bit_offset ; int max_size = 0 ; int max_alignment = 0 ; for ( StructOrUnionMember * * pmember = s -> members ; * pmember ; pmember ++ ) { StructOrUnionMember * member = * pmember ; int size ; if ( member -> is_bit_field ) { size = member -> bit_field_size ; if ( ! member -> bit_field_size ) bit_offset = ( ( bit_offset + 31 ) & ~ 31 ) ; else { int new_bit_offset = ( bit_offset + member -> bit_field_size - 1 ) & ~ 31 ; if ( new_bit_offset != ( bit_offset & ~ 31 ) ) bit_offset = ( ( bit_offset + 31 ) & ~ 31 ) ; } if ( max_alignment < 32 ) max_alignment = 32 ; } else { int alignment = s -> is_packed ? 8 : get_type_alignment ( member -> type ) * 8 ; if ( alignment > max_alignment ) max_alignment = alignment ; bit_offset = ( ( bit_offset + alignment - 1 ) & ( ~ ( alignment - 1 ) ) ) ; if ( member -> type -> type == TYPE_STRUCT_OR_UNION ) { member -> type -> struct_or_union_desc = dup_struct_or_union ( member -> type -> struct_or_union_desc ) ; size = recursive_complete_struct_or_union ( member -> type -> struct_or_union_desc , bit_offset ) ; } else { size = get_type_size ( member -> type ) * 8 ; } } member -> offset = bit_offset >> 3 ; member -> bit_field_offset = bit_offset ; if ( size > max_size ) max_size = size ; if ( ! s -> is_union ) bit_offset += size ; } s -> is_incomplete = 0 ; int size ; if ( s -> is_union ) size = max_size ; else { bit_offset = ( ( bit_offset + max_alignment - 1 ) & ( ~ ( max_alignment - 1 ) ) ) ; size = bit_offset - initial_bit_offset ; } s -> size = size >> 3 ; return size ; }
Recurse through all struct members and determine offsets
Bit fields are only implemented for integers (32 bits size) according to the C89 spec.
Recurse through all struct members and determine offsets Bit fields are only implemented for integers ( 32 bits size ) according to the C89 spec .
// Align to the next integer boundary if // - It's a size zero unnamed member // - If the member would protrude past the next integer boundary // Ensure the alignment is at least 4 bytes // Duplicate the structs, since the bit_offset will be set and otherwise // would end up to a reused struct having invalid bit_offsets