unsigned get_type_size(type_t const *const type) { switch (type->kind) { case TYPE_ERROR: return 0; case TYPE_ATOMIC: case TYPE_IMAGINARY: case TYPE_ENUM: return get_atomic_type_size(type->atomic.akind); case TYPE_COMPLEX: return get_atomic_type_size(type->atomic.akind) * 2; case TYPE_COMPOUND_STRUCT: case TYPE_COMPOUND_UNION: return type->compound.compound->size; case TYPE_FUNCTION: case TYPE_VOID: return 1; /* GCC extension. */ case TYPE_REFERENCE: case TYPE_POINTER: return pointer_properties.size; case TYPE_ARRAY: { /* TODO: correct if element_type is aligned? */ il_size_t element_size = get_type_size(type->array.element_type); return type->array.size * element_size; } case TYPE_TYPEDEF: return get_type_size(type->typedeft.typedefe->type); case TYPE_TYPEOF: return get_type_size(type->typeoft.typeof_type); case TYPE_BUILTIN_TEMPLATE: break; } panic("invalid type"); }
unsigned get_type_size(type_t *type) { switch (type->kind) { case TYPE_ERROR: return 0; case TYPE_ATOMIC: case TYPE_IMAGINARY: case TYPE_ENUM: return get_atomic_type_size(type->atomic.akind); case TYPE_COMPLEX: return get_atomic_type_size(type->atomic.akind) * 2; case TYPE_COMPOUND_UNION: layout_union_type(&type->compound); return type->compound.compound->size; case TYPE_COMPOUND_STRUCT: layout_struct_type(&type->compound); return type->compound.compound->size; case TYPE_FUNCTION: return 0; /* non-const (but "address-const") */ case TYPE_REFERENCE: case TYPE_POINTER: return pointer_properties.size; case TYPE_ARRAY: { /* TODO: correct if element_type is aligned? */ il_size_t element_size = get_type_size(type->array.element_type); return type->array.size * element_size; } case TYPE_TYPEDEF: return get_type_size(type->typedeft.typedefe->type); case TYPE_TYPEOF: return get_type_size(type->typeoft.typeof_type); } panic("invalid type in get_type_size"); }
/** * Find the atomic type kind representing a given size (signed). */ atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size) { static const atomic_type_kind_t possible_kinds[] = { ATOMIC_TYPE_UCHAR, ATOMIC_TYPE_USHORT, ATOMIC_TYPE_UINT, ATOMIC_TYPE_ULONG, ATOMIC_TYPE_ULONGLONG }; for (size_t i = 0; i < ARRAY_SIZE(possible_kinds); ++i) { if (get_atomic_type_size(possible_kinds[i]) == size) { return possible_kinds[i]; } } panic("couldn't find atomic type"); }
/** * Find the atomic type kind representing a given size (signed). */ atomic_type_kind_t find_unsigned_int_atomic_type_kind_for_size(unsigned size) { static atomic_type_kind_t kinds[32]; assert(size < 32); atomic_type_kind_t kind = kinds[size]; if (kind == ATOMIC_TYPE_INVALID) { static const atomic_type_kind_t possible_kinds[] = { ATOMIC_TYPE_UCHAR, ATOMIC_TYPE_USHORT, ATOMIC_TYPE_UINT, ATOMIC_TYPE_ULONG, ATOMIC_TYPE_ULONGLONG }; for (size_t i = 0; i < lengthof(possible_kinds); ++i) { if (get_atomic_type_size(possible_kinds[i]) == size) { kind = possible_kinds[i]; break; } } kinds[size] = kind; } return kind; }
static ir_mode *init_atomic_ir_mode(atomic_type_kind_t kind) { unsigned flags = get_atomic_type_flags(kind); unsigned size = get_atomic_type_size(kind); if (flags & ATOMIC_TYPE_FLAG_FLOAT) { if (kind == ATOMIC_TYPE_LONG_DOUBLE && dialect.long_double_x87_80bit_float) { assert(size == 12 || size == 16); return new_float_mode("F80", irma_x86_extended_float, 15, 64, target.float_int_overflow); } switch (size) { case 4: return new_float_mode("F32", irma_ieee754, 8, 23, target.float_int_overflow); case 8: return new_float_mode("F64", irma_ieee754, 11, 52, target.float_int_overflow); case 16: return new_float_mode("F128", irma_ieee754, 15, 112, target.float_int_overflow); default: panic("unexpected kind"); } } else if (flags & ATOMIC_TYPE_FLAG_INTEGER) { char name[64]; unsigned bit_size = size * 8; bool is_signed = (flags & ATOMIC_TYPE_FLAG_SIGNED) != 0; unsigned modulo_shift = decide_modulo_shift(bit_size); snprintf(name, sizeof(name), "%s%u", is_signed ? "I" : "U", bit_size); return new_int_mode(name, irma_twos_complement, bit_size, is_signed, modulo_shift); } return NULL; }