mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-05 02:04:06 +00:00
Remove bit_field type from Odin (keyword and dead runtime code still exists)
This commit is contained in:
@@ -195,4 +195,4 @@ is_windows_8_1 :: proc() -> bool {
|
||||
is_windows_10 :: proc() -> bool {
|
||||
osvi := get_windows_version_w();
|
||||
return (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,14 +240,14 @@ Typeid_Kind :: enum u8 {
|
||||
}
|
||||
#assert(len(Typeid_Kind) < 32);
|
||||
|
||||
Typeid_Bit_Field :: bit_field #align align_of(uintptr) {
|
||||
index: 8*size_of(uintptr) - 8,
|
||||
kind: 5, // Typeid_Kind
|
||||
named: 1,
|
||||
special: 1, // signed, cstring, etc
|
||||
reserved: 1,
|
||||
}
|
||||
#assert(size_of(Typeid_Bit_Field) == size_of(uintptr));
|
||||
// Typeid_Bit_Field :: bit_field #align align_of(uintptr) {
|
||||
// index: 8*size_of(uintptr) - 8,
|
||||
// kind: 5, // Typeid_Kind
|
||||
// named: 1,
|
||||
// special: 1, // signed, cstring, etc
|
||||
// reserved: 1,
|
||||
// }
|
||||
// #assert(size_of(Typeid_Bit_Field) == size_of(uintptr));
|
||||
|
||||
// NOTE(bill): only the ones that are needed (not all types)
|
||||
// This will be set by the compiler
|
||||
@@ -417,8 +417,9 @@ type_info_core :: proc "contextless" (info: ^Type_Info) -> ^Type_Info {
|
||||
type_info_base_without_enum :: type_info_core;
|
||||
|
||||
__type_info_of :: proc "contextless" (id: typeid) -> ^Type_Info {
|
||||
data := transmute(Typeid_Bit_Field)id;
|
||||
n := int(data.index);
|
||||
MASK :: 1<<(8*size_of(typeid) - 8) - 1;
|
||||
data := transmute(uintptr)id;
|
||||
n := int(data & MASK);
|
||||
if n < 0 || n >= len(type_table) {
|
||||
n = 0;
|
||||
}
|
||||
|
||||
@@ -9,10 +9,9 @@ Menu_Bar_Info :: struct {
|
||||
bar: Rect,
|
||||
menu: Hmenu,
|
||||
wnd_menu: Hwnd,
|
||||
using fields: bit_field {
|
||||
bar_focused: 1,
|
||||
focuses: 1,
|
||||
},
|
||||
fields: u8,
|
||||
// field.bar_focused: 1,
|
||||
// field.focuses: 1,
|
||||
}
|
||||
|
||||
Menu_Item_Info_A :: struct {
|
||||
|
||||
@@ -655,7 +655,8 @@ WIN32_MEMORY_REGION_INFORMATION_u :: struct #raw_union {
|
||||
WIN32_MEMORY_REGION_INFORMATION_u_s :: struct {
|
||||
Bitfield: ULONG,
|
||||
}
|
||||
WIN32_MEMORY_REGION_INFORMATION_u_s_Bitfield :: bit_field #align align_of(ULONG) {
|
||||
WIN32_MEMORY_REGION_INFORMATION_u_s_Bitfield :: distinct ULONG;
|
||||
/*bit_field #align align_of(ULONG) {
|
||||
Private : 1-0,
|
||||
MappedDataFile : 2-1,
|
||||
MappedImage : 3-2,
|
||||
@@ -663,7 +664,7 @@ WIN32_MEMORY_REGION_INFORMATION_u_s_Bitfield :: bit_field #align align_of(ULONG)
|
||||
MappedPhysical : 5-4,
|
||||
DirectMapped : 6-5,
|
||||
Reserved : 32-6,
|
||||
}
|
||||
}*/
|
||||
|
||||
foreign kernel32 {
|
||||
QueryVirtualMemoryInformation :: proc(
|
||||
|
||||
@@ -98,7 +98,7 @@ general_stuff :: proc() {
|
||||
{ // `distinct` types
|
||||
// Originally, all type declarations would create a distinct type unless #type_alias was present.
|
||||
// Now the behaviour has been reversed. All type declarations create a type alias unless `distinct` is present.
|
||||
// If the type expression is `struct`, `union`, `enum`, `proc`, or `bit_field`, the types will always been distinct.
|
||||
// If the type expression is `struct`, `union`, `enum`, or `proc`, the types will always been distinct.
|
||||
|
||||
Int32 :: i32;
|
||||
#assert(Int32 == i32);
|
||||
|
||||
@@ -96,9 +96,6 @@ Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *operand, Stri
|
||||
e->type = t_invalid;
|
||||
return nullptr;
|
||||
}
|
||||
if (is_type_bit_field_value(t)) {
|
||||
t = default_bit_field_value_type(t);
|
||||
}
|
||||
GB_ASSERT(is_type_typed(t));
|
||||
e->type = t;
|
||||
}
|
||||
|
||||
@@ -549,15 +549,6 @@ i64 check_distance_between_types(CheckerContext *c, Operand *operand, Type *type
|
||||
}
|
||||
}
|
||||
|
||||
if (is_type_bit_field_value(operand->type) && is_type_integer(type)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (is_type_bit_field_value(operand->type) && is_type_bit_field_value(type)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
isize subtype_level = check_is_assignable_to_using_subtype(operand->type, type);
|
||||
@@ -1701,9 +1692,6 @@ bool check_is_not_addressable(CheckerContext *c, Operand *o) {
|
||||
if (o->mode != Addressing_Variable) {
|
||||
return true;
|
||||
}
|
||||
if (is_type_bit_field_value(o->type)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -2269,13 +2257,6 @@ bool check_is_castable_to(CheckerContext *c, Operand *operand, Type *y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_type_bit_field_value(src) && is_type_integer(dst)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_type_bit_field_value(src) && is_type_boolean(dst)) {
|
||||
return src->BitFieldValue.bits == 1;
|
||||
}
|
||||
|
||||
// Cast between pointers
|
||||
if (is_type_pointer(src) && is_type_pointer(dst)) {
|
||||
@@ -2899,45 +2880,6 @@ ExactValue convert_exact_value_for_type(ExactValue v, Type *type) {
|
||||
return v;
|
||||
}
|
||||
|
||||
Type *check_assignment_bit_field(CheckerContext *ctx, Operand *operand, Type *target_type) {
|
||||
if (is_type_bit_field_value(target_type)) {
|
||||
Type *lt = base_type(target_type);
|
||||
i64 lhs_bits = lt->BitFieldValue.bits;
|
||||
if (operand->mode == Addressing_Constant) {
|
||||
ExactValue v = exact_value_to_integer(operand->value);
|
||||
if (v.kind == ExactValue_Integer) {
|
||||
BigInt i = v.value_integer;
|
||||
if (!i.neg) {
|
||||
u64 imax_ = ~cast(u64)0ull;
|
||||
if (lhs_bits < 64) {
|
||||
imax_ = (1ull << cast(u64)lhs_bits) - 1ull;
|
||||
}
|
||||
|
||||
BigInt imax = big_int_make_u64(imax_);
|
||||
if (big_int_cmp(&i, &imax) <= 0) {
|
||||
return operand->type;
|
||||
}
|
||||
}
|
||||
} else if (operand->value.kind == ExactValue_Bool) {
|
||||
bool b = operand->value.value_bool;
|
||||
if (lhs_bits == 1) {
|
||||
return operand->type;
|
||||
}
|
||||
}
|
||||
} else if (is_type_integer(operand->type)) {
|
||||
// TODO(bill): Any other checks?
|
||||
return operand->type;
|
||||
} else if (is_type_boolean(operand->type)) {
|
||||
if (lhs_bits == 1) {
|
||||
return operand->type;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) {
|
||||
GB_ASSERT_NOT_NULL(target_type);
|
||||
if (operand->mode == Addressing_Invalid ||
|
||||
@@ -3040,14 +2982,6 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_BitFieldValue: {
|
||||
Type *res = check_assignment_bit_field(c, operand, target_type);
|
||||
if (res == nullptr) {
|
||||
convert_untyped_error(c, operand, target_type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_Union:
|
||||
if (!is_operand_nil(*operand) && !is_operand_undef(*operand)) {
|
||||
isize count = t->Union.variants.count;
|
||||
@@ -3875,8 +3809,6 @@ BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_boolean_end -
|
||||
is_type_union,
|
||||
is_type_enum,
|
||||
is_type_proc,
|
||||
is_type_bit_field,
|
||||
is_type_bit_field_value,
|
||||
is_type_bit_set,
|
||||
is_type_simd_vector,
|
||||
|
||||
|
||||
@@ -330,17 +330,6 @@ Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs)
|
||||
return nullptr;
|
||||
|
||||
case Addressing_Variable:
|
||||
if (is_type_bit_field_value(lhs->type)) {
|
||||
Type *res = check_assignment_bit_field(ctx, rhs, lhs->type);
|
||||
if (res == nullptr) {
|
||||
gbString lhs_expr = expr_to_string(lhs->expr);
|
||||
gbString rhs_expr = expr_to_string(rhs->expr);
|
||||
error(rhs->expr, "Cannot assign '%s' to bit field '%s'", rhs_expr, lhs_expr);
|
||||
gb_string_free(rhs_expr);
|
||||
gb_string_free(lhs_expr);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
break;
|
||||
|
||||
case Addressing_MapIndex: {
|
||||
|
||||
@@ -58,22 +58,6 @@ void populate_using_entity_scope(CheckerContext *ctx, Ast *node, AstField *field
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (t->kind == Type_BitField) {
|
||||
for_array(i, t->BitField.fields) {
|
||||
Entity *f = t->BitField.fields[i];
|
||||
String name = f->token.string;
|
||||
Entity *e = scope_lookup_current(ctx->scope, name);
|
||||
if ((e != nullptr && name != "_") && (e != f)) {
|
||||
// TODO(bill): Better type error
|
||||
if (str != nullptr) {
|
||||
error(e->token, "'%.*s' is already declared in '%s'", LIT(name), str);
|
||||
} else {
|
||||
error(e->token, "'%.*s' is already declared", LIT(name));
|
||||
}
|
||||
} else {
|
||||
add_entity(ctx->checker, ctx->scope, nullptr, f);
|
||||
}
|
||||
}
|
||||
} else if (t->kind == Type_Array && t->Array.count <= 4) {
|
||||
Entity *e = nullptr;
|
||||
String name = {};
|
||||
@@ -107,8 +91,6 @@ bool does_field_type_allow_using(Type *t) {
|
||||
return true;
|
||||
} else if (is_type_raw_union(t)) {
|
||||
return true;
|
||||
} else if (is_type_bit_field(t)) {
|
||||
return true;
|
||||
} else if (is_type_array(t)) {
|
||||
return t->Array.count <= 4;
|
||||
} else if (is_type_typeid(t)) {
|
||||
@@ -981,82 +963,6 @@ void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *named_type, Ast
|
||||
enum_type->Enum.max_value_index = max_value_index;
|
||||
}
|
||||
|
||||
|
||||
void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, Ast *node) {
|
||||
ast_node(bft, BitFieldType, node);
|
||||
GB_ASSERT(is_type_bit_field(bit_field_type));
|
||||
|
||||
auto fields = array_make<Entity*>(permanent_allocator(), 0, bft->fields.count);
|
||||
auto sizes = array_make<u32> (permanent_allocator(), 0, bft->fields.count);
|
||||
auto offsets = array_make<u32> (permanent_allocator(), 0, bft->fields.count);
|
||||
|
||||
scope_reserve(ctx->scope, bft->fields.count);
|
||||
|
||||
u32 curr_offset = 0;
|
||||
for_array(i, bft->fields) {
|
||||
Ast *field = bft->fields[i];
|
||||
GB_ASSERT(field->kind == Ast_FieldValue);
|
||||
Ast *ident = field->FieldValue.field;
|
||||
Ast *value = field->FieldValue.value;
|
||||
|
||||
if (ident->kind != Ast_Ident) {
|
||||
error(field, "A bit field value's name must be an identifier");
|
||||
continue;
|
||||
}
|
||||
String name = ident->Ident.token.string;
|
||||
|
||||
Operand o = {};
|
||||
check_expr(ctx, &o, value);
|
||||
if (o.mode != Addressing_Constant) {
|
||||
error(value, "Bit field bit size must be a constant");
|
||||
continue;
|
||||
}
|
||||
ExactValue v = exact_value_to_integer(o.value);
|
||||
if (v.kind != ExactValue_Integer) {
|
||||
error(value, "Bit field bit size must be a constant integer");
|
||||
continue;
|
||||
}
|
||||
i64 bits_ = big_int_to_i64(&v.value_integer); // TODO(bill): what if the integer is huge?
|
||||
if (bits_ < 0 || bits_ > 64) {
|
||||
error(value, "Bit field's bit size must be within the range 1...64, got %lld", cast(long long)bits_);
|
||||
continue;
|
||||
}
|
||||
u32 bits = cast(u32)bits_;
|
||||
|
||||
Type *value_type = alloc_type_bit_field_value(bits);
|
||||
Entity *e = alloc_entity_variable(bit_field_type->BitField.scope, ident->Ident.token, value_type);
|
||||
e->identifier = ident;
|
||||
e->flags |= EntityFlag_BitFieldValue;
|
||||
|
||||
if (!is_blank_ident(name) &&
|
||||
scope_lookup_current(ctx->scope, name) != nullptr) {
|
||||
error(ident, "'%.*s' is already declared in this bit field", LIT(name));
|
||||
} else {
|
||||
add_entity(ctx->checker, ctx->scope, nullptr, e);
|
||||
// TODO(bill): Should this entity be "used"?
|
||||
add_entity_use(ctx, field, e);
|
||||
|
||||
array_add(&fields, e);
|
||||
array_add(&offsets, curr_offset);
|
||||
array_add(&sizes, bits);
|
||||
|
||||
curr_offset += bits;
|
||||
}
|
||||
}
|
||||
GB_ASSERT(fields.count <= bft->fields.count);
|
||||
|
||||
bit_field_type->BitField.fields = fields;
|
||||
bit_field_type->BitField.sizes = sizes;
|
||||
bit_field_type->BitField.offsets = offsets;
|
||||
|
||||
if (bft->align != nullptr) {
|
||||
i64 custom_align = 1;
|
||||
if (check_custom_align(ctx, bft->align, &custom_align)) {
|
||||
bit_field_type->BitField.custom_align = custom_align;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool is_type_valid_bit_set_range(Type *t) {
|
||||
if (is_type_integer(t)) {
|
||||
return true;
|
||||
@@ -2066,7 +1972,6 @@ Array<Type *> systemv_distribute_struct_fields(Type *t) {
|
||||
case Type_Union:
|
||||
case Type_DynamicArray:
|
||||
case Type_Map:
|
||||
case Type_BitField: // TODO(bill): Ignore?
|
||||
// NOTE(bill, 2019-10-10): Odin specific, don't worry about C calling convention yet
|
||||
goto DEFAULT;
|
||||
|
||||
@@ -3619,12 +3524,9 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
|
||||
case_end;
|
||||
|
||||
case_ast_node(et, BitFieldType, e);
|
||||
*type = alloc_type_bit_field();
|
||||
set_base_type(named_type, *type);
|
||||
check_open_scope(ctx, e);
|
||||
check_bit_field_type(ctx, *type, e);
|
||||
check_close_scope(ctx);
|
||||
return true;
|
||||
error(e, "'bit_field' types have now been removed");
|
||||
error_line("\tSuggestion: package math/bits 'bitfield_extract' and 'bitfield_insert' are better replacements\n");
|
||||
return false;
|
||||
case_end;
|
||||
|
||||
case_ast_node(bs, BitSetType, e);
|
||||
|
||||
@@ -1258,9 +1258,6 @@ void add_type_info_type(CheckerContext *c, Type *t) {
|
||||
return;
|
||||
}
|
||||
t = default_type(t);
|
||||
if (is_type_bit_field_value(t)) {
|
||||
t = default_bit_field_value_type(t);
|
||||
}
|
||||
if (is_type_untyped(t)) {
|
||||
return; // Could be nil
|
||||
}
|
||||
@@ -1428,11 +1425,6 @@ void add_type_info_type(CheckerContext *c, Type *t) {
|
||||
add_comparison_procedures_for_fields(c, bt);
|
||||
break;
|
||||
|
||||
case Type_BitFieldValue:
|
||||
break;
|
||||
case Type_BitField:
|
||||
break;
|
||||
|
||||
case Type_Map:
|
||||
init_map_internal_types(bt);
|
||||
add_type_info_type(c, bt->Map.key);
|
||||
@@ -1505,9 +1497,6 @@ void add_min_dep_type_info(Checker *c, Type *t) {
|
||||
return;
|
||||
}
|
||||
t = default_type(t);
|
||||
if (is_type_bit_field_value(t)) {
|
||||
t = default_bit_field_value_type(t);
|
||||
}
|
||||
if (is_type_untyped(t)) {
|
||||
return; // Could be nil
|
||||
}
|
||||
@@ -1647,11 +1636,6 @@ void add_min_dep_type_info(Checker *c, Type *t) {
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_BitFieldValue:
|
||||
break;
|
||||
case Type_BitField:
|
||||
break;
|
||||
|
||||
case Type_Map:
|
||||
init_map_internal_types(bt);
|
||||
add_min_dep_type_info(c, bt->Map.key);
|
||||
|
||||
@@ -4446,10 +4446,10 @@ gb_inline i64 gb_atomic64_fetch_or(gbAtomic64 volatile *a, i64 operand) {
|
||||
|
||||
#elif defined(GB_CPU_ARM)
|
||||
|
||||
gb_inline i32 gb_atomic32_load (gbAtomic32 const volatile *a) {
|
||||
gb_inline i32 gb_atomic32_load (gbAtomic32 const volatile *a) {
|
||||
return __atomic_load_n(&a->value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
gb_inline void gb_atomic32_store(gbAtomic32 volatile *a, i32 value) {
|
||||
gb_inline void gb_atomic32_store(gbAtomic32 volatile *a, i32 value) {
|
||||
__atomic_store_n(&a->value, value, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
@@ -8903,7 +8903,7 @@ gb_inline gbDllProc gb_dll_proc_address(gbDllHandle dll, char const *proc_name)
|
||||
asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
|
||||
return virtual_timer_value;
|
||||
}
|
||||
#else
|
||||
#else
|
||||
#error "gb_rdtsc not supported"
|
||||
#endif
|
||||
|
||||
|
||||
330
src/ir.cpp
330
src/ir.cpp
@@ -494,7 +494,6 @@ gb_global irValue *v_raw_nil = nullptr;
|
||||
enum irAddrKind {
|
||||
irAddr_Default,
|
||||
irAddr_Map,
|
||||
irAddr_BitField,
|
||||
irAddr_Context,
|
||||
irAddr_SoaVariable,
|
||||
irAddr_RelativePointer,
|
||||
@@ -562,12 +561,6 @@ irAddr ir_addr_context(irValue *addr, Selection sel = empty_selection) {
|
||||
}
|
||||
|
||||
|
||||
irAddr ir_addr_bit_field(irValue *addr, i32 bit_field_value_index) {
|
||||
irAddr v = {irAddr_BitField, addr};
|
||||
v.bit_field_value_index = bit_field_value_index;
|
||||
return v;
|
||||
}
|
||||
|
||||
irAddr ir_addr_soa_variable(irValue *addr, irValue *index, Ast *index_expr) {
|
||||
irAddr v = {irAddr_SoaVariable, addr};
|
||||
v.soa.index = index;
|
||||
@@ -2246,49 +2239,6 @@ irDebugInfo *ir_add_debug_info_type_dynamic_array(irModule *module, Type *type,
|
||||
return di;
|
||||
}
|
||||
|
||||
irDebugInfo *ir_add_debug_info_type_bit_field(irModule *module, Type *type, Entity *e, irDebugInfo *scope) {
|
||||
GB_ASSERT(type->kind == Type_BitField || (type->kind == Type_Named && type->Named.base->kind == Type_BitField));
|
||||
|
||||
Type *bf_type = base_type(type);
|
||||
|
||||
irDebugInfo *di = ir_alloc_debug_info(irDebugInfo_CompositeType);
|
||||
di->CompositeType.name = is_type_named(type) ? type->Named.name : str_lit("bit_field");
|
||||
di->CompositeType.tag = irDebugBasicEncoding_structure_type;
|
||||
di->CompositeType.size = ir_debug_size_bits(bf_type);
|
||||
map_set(&module->debug_info, hash_type(type), di);
|
||||
|
||||
GB_ASSERT(bf_type->BitField.fields.count == bf_type->BitField.offsets.count &&
|
||||
bf_type->BitField.fields.count == bf_type->BitField.sizes.count);
|
||||
|
||||
irDebugInfo *elements_di = ir_add_debug_info_array(module, 0, bf_type->BitField.fields.count);
|
||||
di->CompositeType.elements = elements_di;
|
||||
map_set(&module->debug_info, hash_pointer(elements_di), elements_di);
|
||||
|
||||
for_array(field_index, bf_type->BitField.fields) {
|
||||
Entity *field = bf_type->BitField.fields[field_index];
|
||||
u32 offset = bf_type->BitField.offsets[field_index];
|
||||
u32 size = bf_type->BitField.sizes[field_index];
|
||||
String name = str_lit("field_todo");
|
||||
if (field != nullptr && field->token.string.len > 0) {
|
||||
name = field->token.string;
|
||||
}
|
||||
// TODO(lachsinc): t_i64 may not be safe to use for all bitfields?
|
||||
irDebugInfo *field_di = ir_add_debug_info_field_internal(module, name, t_i64,
|
||||
0,
|
||||
nullptr,
|
||||
di);
|
||||
// NOTE(lachsinc): Above calls BitFieldValues type_size_of() which returns size in bits,
|
||||
// replace with its true bit value here..
|
||||
field_di->DerivedType.size = size;
|
||||
field_di->DerivedType.offset = offset; // Offset stored in bits already, no need to convert
|
||||
field_di->DerivedType.flags = irDebugInfoFlag_Bitfield;
|
||||
map_set(&module->debug_info, hash_pointer(field_di), field_di);
|
||||
array_add(&elements_di->DebugInfoArray.elements, field_di);
|
||||
}
|
||||
|
||||
return di;
|
||||
}
|
||||
|
||||
irDebugInfo *ir_add_debug_info_type_bit_set(irModule *module, Type *type, Entity *e, irDebugInfo *scope) {
|
||||
GB_ASSERT(type->kind == Type_BitSet || type->kind == Type_Named);
|
||||
|
||||
@@ -2579,7 +2529,6 @@ irDebugInfo *ir_add_debug_info_type(irModule *module, Type *type, Entity *e, irD
|
||||
if (named_base->kind != Type_Struct &&
|
||||
named_base->kind != Type_Union &&
|
||||
named_base->kind != Type_Enum &&
|
||||
named_base->kind != Type_BitField &&
|
||||
named_base->kind != Type_Tuple) {
|
||||
// distinct / typedef etc.
|
||||
irDebugInfo *di = ir_alloc_debug_info(irDebugInfo_DerivedType);
|
||||
@@ -2845,10 +2794,6 @@ irDebugInfo *ir_add_debug_info_type(irModule *module, Type *type, Entity *e, irD
|
||||
}
|
||||
*/
|
||||
|
||||
if (is_type_bit_field(type)) {
|
||||
return ir_add_debug_info_type_bit_field(module, type, e, scope);
|
||||
}
|
||||
|
||||
if (is_type_bit_set(type)) {
|
||||
return ir_add_debug_info_type_bit_set(module, type, e, scope);
|
||||
}
|
||||
@@ -3146,7 +3091,6 @@ bool ir_type_requires_mem_zero(Type *t) {
|
||||
|
||||
case Type_DynamicArray:
|
||||
case Type_Map:
|
||||
case Type_BitField:
|
||||
return true;
|
||||
case Type_Array:
|
||||
return ir_type_requires_mem_zero(t->Array.elem);
|
||||
@@ -3971,96 +3915,6 @@ void ir_addr_store(irProcedure *proc, irAddr addr, irValue *value) {
|
||||
} else if (addr.kind == irAddr_Map) {
|
||||
ir_insert_dynamic_map_key_and_value(proc, addr.addr, addr.map_type, addr.map_key, value, proc->curr_stmt);
|
||||
return;
|
||||
} else if (addr.kind == irAddr_BitField) {
|
||||
gbAllocator a = ir_allocator();
|
||||
|
||||
Type *bft = base_type(type_deref(ir_type(addr.addr)));
|
||||
GB_ASSERT(is_type_bit_field(bft));
|
||||
i32 value_index = addr.bit_field_value_index;
|
||||
i32 offset = bft->BitField.offsets[value_index];
|
||||
i32 size_in_bits = bft->BitField.fields[value_index]->type->BitFieldValue.bits;
|
||||
|
||||
|
||||
i32 byte_index = offset / 8;
|
||||
i32 bit_inset = offset % 8;
|
||||
|
||||
i32 size_in_bytes = next_pow2((size_in_bits+7)/8);
|
||||
if (size_in_bytes == 0) {
|
||||
GB_ASSERT(size_in_bits == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
Type *int_type = nullptr;
|
||||
switch (size_in_bytes) {
|
||||
case 1: int_type = t_u8; break;
|
||||
case 2: int_type = t_u16; break;
|
||||
case 4: int_type = t_u32; break;
|
||||
case 8: int_type = t_u64; break;
|
||||
}
|
||||
GB_ASSERT(int_type != nullptr);
|
||||
|
||||
value = ir_emit_conv(proc, value, int_type);
|
||||
|
||||
irValue *bytes = ir_emit_conv(proc, addr.addr, t_u8_ptr);
|
||||
bytes = ir_emit_ptr_offset(proc, bytes, ir_const_int(byte_index));
|
||||
|
||||
|
||||
if (bit_inset == 0) {
|
||||
irValue *v = value;
|
||||
i32 sa = 8*size_in_bytes - size_in_bits;
|
||||
if (sa > 0) {
|
||||
irValue *shift_amount = ir_const_int(sa);
|
||||
v = ir_emit_arith(proc, Token_Shl, v, shift_amount, int_type);
|
||||
v = ir_emit_arith(proc, Token_Shr, v, shift_amount, int_type);
|
||||
}
|
||||
irValue *ptr = ir_emit_conv(proc, bytes, alloc_type_pointer(int_type));
|
||||
|
||||
|
||||
irValue *sv = ir_emit_load(proc, ptr, 1);
|
||||
// NOTE(bill): Zero out the lower bits that need to be stored to
|
||||
sv = ir_emit_arith(proc, Token_Shr, sv, ir_const_int(size_in_bits), int_type);
|
||||
sv = ir_emit_arith(proc, Token_Shl, sv, ir_const_int(size_in_bits), int_type);
|
||||
|
||||
v = ir_emit_arith(proc, Token_Or, sv, v, int_type);
|
||||
ir_emit_store(proc, ptr, v, true);
|
||||
return;
|
||||
}
|
||||
|
||||
GB_ASSERT(0 < bit_inset && bit_inset < 8);
|
||||
|
||||
// First byte
|
||||
{
|
||||
irValue *shift_amount = ir_const_int(bit_inset);
|
||||
|
||||
irValue *ptr = ir_emit_conv(proc, bytes, alloc_type_pointer(t_u8));
|
||||
|
||||
irValue *v = ir_emit_conv(proc, value, t_u8);
|
||||
v = ir_emit_arith(proc, Token_Shl, v, shift_amount, t_u8);
|
||||
|
||||
irValue *sv = ir_emit_load(proc, bytes, 1);
|
||||
// NOTE(bill): Zero out the upper bits that need to be stored to
|
||||
sv = ir_emit_arith(proc, Token_Shl, sv, ir_const_int(8-bit_inset), t_u8);
|
||||
sv = ir_emit_arith(proc, Token_Shr, sv, ir_const_int(8-bit_inset), t_u8);
|
||||
|
||||
v = ir_emit_arith(proc, Token_Or, sv, v, t_u8);
|
||||
ir_emit_store(proc, ptr, v, true);
|
||||
}
|
||||
|
||||
// Remaining bytes
|
||||
if (bit_inset+size_in_bits > 8) {
|
||||
irValue *ptr = ir_emit_conv(proc, ir_emit_ptr_offset(proc, bytes, v_one), alloc_type_pointer(int_type));
|
||||
irValue *v = ir_emit_conv(proc, value, int_type);
|
||||
v = ir_emit_arith(proc, Token_Shr, v, ir_const_int(8-bit_inset), int_type);
|
||||
|
||||
irValue *sv = ir_emit_load(proc, ptr, 1);
|
||||
// NOTE(bill): Zero out the lower bits that need to be stored to
|
||||
sv = ir_emit_arith(proc, Token_Shr, sv, ir_const_int(size_in_bits-bit_inset), int_type);
|
||||
sv = ir_emit_arith(proc, Token_Shl, sv, ir_const_int(size_in_bits-bit_inset), int_type);
|
||||
|
||||
v = ir_emit_arith(proc, Token_Or, sv, v, int_type);
|
||||
ir_emit_store(proc, ptr, v, true);
|
||||
}
|
||||
return;
|
||||
} else if (addr.kind == irAddr_Context) {
|
||||
irValue *old = ir_emit_load(proc, ir_find_or_generate_context_ptr(proc));
|
||||
irValue *next = ir_add_local_generated(proc, t_context, true);
|
||||
@@ -4206,62 +4060,6 @@ irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) {
|
||||
irValue *single = ir_emit_struct_ep(proc, v, 0);
|
||||
return ir_emit_load(proc, single);
|
||||
}
|
||||
} else if (addr.kind == irAddr_BitField) {
|
||||
gbAllocator a = ir_allocator();
|
||||
|
||||
|
||||
Type *bft = base_type(type_deref(ir_type(addr.addr)));
|
||||
GB_ASSERT(is_type_bit_field(bft));
|
||||
i32 value_index = addr.bit_field_value_index;
|
||||
i32 offset = bft->BitField.offsets[value_index];
|
||||
i32 size_in_bits = bft->BitField.fields[value_index]->type->BitFieldValue.bits;
|
||||
|
||||
i32 byte_index = offset / 8;
|
||||
i32 bit_inset = offset % 8;
|
||||
|
||||
i32 size_in_bytes = next_pow2((size_in_bits+7)/8);
|
||||
if (size_in_bytes == 0) {
|
||||
GB_ASSERT(size_in_bits == 0);
|
||||
return v_zero32;
|
||||
}
|
||||
|
||||
Type *int_type = nullptr;
|
||||
switch (size_in_bytes) {
|
||||
case 1: int_type = t_u8; break;
|
||||
case 2: int_type = t_u16; break;
|
||||
case 4: int_type = t_u32; break;
|
||||
case 8: int_type = t_u64; break;
|
||||
}
|
||||
GB_ASSERT(int_type != nullptr);
|
||||
|
||||
|
||||
irValue *bytes = ir_emit_conv(proc, addr.addr, t_u8_ptr);
|
||||
bytes = ir_emit_ptr_offset(proc, bytes, ir_const_int(byte_index));
|
||||
|
||||
Type *int_ptr = alloc_type_pointer(int_type);
|
||||
|
||||
i32 sa = 8*size_in_bytes - size_in_bits;
|
||||
if (bit_inset == 0) {
|
||||
irValue *v = ir_emit_load(proc, ir_emit_conv(proc, bytes, int_ptr), 1);
|
||||
if (sa > 0) {
|
||||
irValue *shift_amount = ir_const_int(sa);
|
||||
v = ir_emit_arith(proc, Token_Shl, v, shift_amount, int_type);
|
||||
v = ir_emit_arith(proc, Token_Shr, v, shift_amount, int_type);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
GB_ASSERT(8 > bit_inset);
|
||||
|
||||
irValue *ptr = ir_emit_conv(proc, bytes, int_ptr);
|
||||
irValue *v = ir_emit_load(proc, ptr, 1);
|
||||
v = ir_emit_arith(proc, Token_Shr, v, ir_const_int(bit_inset), int_type);
|
||||
if (sa > 0) {
|
||||
irValue *shift_amount = ir_const_int(sa);
|
||||
v = ir_emit_arith(proc, Token_Shl, v, shift_amount, int_type);
|
||||
v = ir_emit_arith(proc, Token_Shr, v, shift_amount, int_type);
|
||||
}
|
||||
return v;
|
||||
} else if (addr.kind == irAddr_Context) {
|
||||
if (addr.ctx.sel.index.count > 0) {
|
||||
irValue *a = addr.addr;
|
||||
@@ -4381,11 +4179,6 @@ irValue *ir_addr_get_ptr(irProcedure *proc, irAddr const &addr, bool allow_refer
|
||||
return final_ptr;
|
||||
}
|
||||
|
||||
case irAddr_BitField: {
|
||||
irValue *v = ir_addr_load(proc, addr);
|
||||
return ir_address_from_load_or_generate_local(proc, v);
|
||||
}
|
||||
|
||||
case irAddr_Context:
|
||||
GB_PANIC("irAddr_Context should be handled elsewhere");
|
||||
}
|
||||
@@ -4945,14 +4738,6 @@ irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue
|
||||
} else if (is_type_typeid(t)) {
|
||||
irValue *invalid_typeid = ir_value_constant(t_typeid, exact_value_i64(0));
|
||||
return ir_emit_comp(proc, op_kind, x, invalid_typeid);
|
||||
} else if (is_type_bit_field(t)) {
|
||||
auto args = array_make<irValue *>(permanent_allocator(), 2);
|
||||
irValue *lhs = ir_address_from_load_or_generate_local(proc, x);
|
||||
args[0] = ir_emit_conv(proc, lhs, t_rawptr);
|
||||
args[1] = ir_const_int(type_size_of(t));
|
||||
irValue *val = ir_emit_runtime_call(proc, "memory_compare_zero", args);
|
||||
irValue *res = ir_emit_comp(proc, op_kind, val, v_zero);
|
||||
return ir_emit_conv(proc, res, t_bool);
|
||||
} else if (is_type_soa_struct(t)) {
|
||||
Type *bt = base_type(t);
|
||||
if (bt->Struct.soa_kind == StructSoa_Slice) {
|
||||
@@ -5243,33 +5028,31 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal
|
||||
Type *lt = ir_type(left);
|
||||
Type *rt = ir_type(right);
|
||||
|
||||
if (is_type_bit_set(lt) && is_type_bit_set(rt)) {
|
||||
Type *blt = base_type(lt);
|
||||
Type *brt = base_type(rt);
|
||||
GB_ASSERT(is_type_bit_field_value(blt));
|
||||
GB_ASSERT(is_type_bit_field_value(brt));
|
||||
i64 bits = gb_max(blt->BitFieldValue.bits, brt->BitFieldValue.bits);
|
||||
i64 bytes = bits / 8;
|
||||
switch (bytes) {
|
||||
case 1:
|
||||
left = ir_emit_conv(proc, left, t_u8);
|
||||
right = ir_emit_conv(proc, right, t_u8);
|
||||
break;
|
||||
case 2:
|
||||
left = ir_emit_conv(proc, left, t_u16);
|
||||
right = ir_emit_conv(proc, right, t_u16);
|
||||
break;
|
||||
case 4:
|
||||
left = ir_emit_conv(proc, left, t_u32);
|
||||
right = ir_emit_conv(proc, right, t_u32);
|
||||
break;
|
||||
case 8:
|
||||
left = ir_emit_conv(proc, left, t_u64);
|
||||
right = ir_emit_conv(proc, right, t_u64);
|
||||
break;
|
||||
default: GB_PANIC("Unknown integer size"); break;
|
||||
}
|
||||
}
|
||||
// if (is_type_bit_set(lt) && is_type_bit_set(rt)) {
|
||||
// Type *blt = base_type(lt);
|
||||
// Type *brt = base_type(rt);
|
||||
// i64 bits = gb_max(blt->BitFieldValue.bits, brt->BitFieldValue.bits);
|
||||
// i64 bytes = bits / 8;
|
||||
// switch (bytes) {
|
||||
// case 1:
|
||||
// left = ir_emit_conv(proc, left, t_u8);
|
||||
// right = ir_emit_conv(proc, right, t_u8);
|
||||
// break;
|
||||
// case 2:
|
||||
// left = ir_emit_conv(proc, left, t_u16);
|
||||
// right = ir_emit_conv(proc, right, t_u16);
|
||||
// break;
|
||||
// case 4:
|
||||
// left = ir_emit_conv(proc, left, t_u32);
|
||||
// right = ir_emit_conv(proc, right, t_u32);
|
||||
// break;
|
||||
// case 8:
|
||||
// left = ir_emit_conv(proc, left, t_u64);
|
||||
// right = ir_emit_conv(proc, right, t_u64);
|
||||
// break;
|
||||
// default: GB_PANIC("Unknown integer size"); break;
|
||||
// }
|
||||
// }
|
||||
|
||||
lt = ir_type(left);
|
||||
rt = ir_type(right);
|
||||
@@ -6493,7 +6276,6 @@ bool ir_is_type_aggregate(Type *t) {
|
||||
case Type_Tuple:
|
||||
case Type_DynamicArray:
|
||||
case Type_Map:
|
||||
case Type_BitField:
|
||||
case Type_SimdVector:
|
||||
return true;
|
||||
|
||||
@@ -6790,7 +6572,6 @@ u64 ir_typeid_as_integer(irModule *m, Type *type) {
|
||||
case Type_Union: kind = Typeid_Union; break;
|
||||
case Type_Tuple: kind = Typeid_Tuple; break;
|
||||
case Type_Proc: kind = Typeid_Procedure; break;
|
||||
case Type_BitField: kind = Typeid_Bit_Field; break;
|
||||
case Type_BitSet: kind = Typeid_Bit_Set; break;
|
||||
case Type_SimdVector: kind = Typeid_Simd_Vector; break;
|
||||
case Type_RelativePointer: kind = Typeid_Relative_Pointer; break;
|
||||
@@ -8826,22 +8607,7 @@ irAddr ir_build_addr(irProcedure *proc, Ast *expr) {
|
||||
GB_ASSERT(sel.entity != nullptr);
|
||||
|
||||
|
||||
if (sel.entity->type->kind == Type_BitFieldValue) {
|
||||
irAddr addr = ir_build_addr(proc, se->expr);
|
||||
Type *bft = type_deref(ir_addr_type(addr));
|
||||
if (sel.index.count == 1) {
|
||||
GB_ASSERT(is_type_bit_field(bft));
|
||||
i32 index = sel.index[0];
|
||||
return ir_addr_bit_field(ir_addr_get_ptr(proc, addr), index);
|
||||
} else {
|
||||
Selection s = sel;
|
||||
s.index.count--;
|
||||
i32 index = s.index[s.index.count-1];
|
||||
irValue *a = ir_addr_get_ptr(proc, addr);
|
||||
a = ir_emit_deep_field_gep(proc, a, s);
|
||||
return ir_addr_bit_field(a, index);
|
||||
}
|
||||
} else {
|
||||
{
|
||||
irAddr addr = ir_build_addr(proc, se->expr);
|
||||
if (addr.kind == irAddr_Context) {
|
||||
GB_ASSERT(sel.index.count > 0);
|
||||
@@ -12726,50 +12492,6 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_BitField: {
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Bit_Field"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_bit_field_ptr);
|
||||
// names: []string;
|
||||
// bits: []u32;
|
||||
// offsets: []u32;
|
||||
isize count = t->BitField.fields.count;
|
||||
if (count > 0) {
|
||||
auto fields = t->BitField.fields;
|
||||
irValue *name_array = ir_generate_array(m, t_string, count, str_lit("$bit_field_names"), cast(i64)entry_index);
|
||||
irValue *bit_array = ir_generate_array(m, t_i32, count, str_lit("$bit_field_bits"), cast(i64)entry_index);
|
||||
irValue *offset_array = ir_generate_array(m, t_i32, count, str_lit("$bit_field_offsets"), cast(i64)entry_index);
|
||||
|
||||
for (isize i = 0; i < count; i++) {
|
||||
Entity *f = fields[i];
|
||||
GB_ASSERT(f->type != nullptr);
|
||||
GB_ASSERT(f->type->kind == Type_BitFieldValue);
|
||||
irValue *name_ep = ir_emit_array_epi(proc, name_array, cast(i32)i);
|
||||
irValue *bit_ep = ir_emit_array_epi(proc, bit_array, cast(i32)i);
|
||||
irValue *offset_ep = ir_emit_array_epi(proc, offset_array, cast(i32)i);
|
||||
|
||||
ir_emit_store(proc, name_ep, ir_const_string(proc->module, f->token.string));
|
||||
ir_emit_store(proc, bit_ep, ir_const_i32(f->type->BitFieldValue.bits));
|
||||
ir_emit_store(proc, offset_ep, ir_const_i32(t->BitField.offsets[i]));
|
||||
|
||||
}
|
||||
|
||||
irValue *v_count = ir_const_int(count);
|
||||
|
||||
irValue *names = ir_emit_struct_ep(proc, tag, 0);
|
||||
irValue *name_array_elem = ir_array_elem(proc, name_array);
|
||||
ir_fill_slice(proc, names, name_array_elem, v_count);
|
||||
|
||||
irValue *bits = ir_emit_struct_ep(proc, tag, 1);
|
||||
irValue *bit_array_elem = ir_array_elem(proc, bit_array);
|
||||
ir_fill_slice(proc, bits, bit_array_elem, v_count);
|
||||
|
||||
irValue *offsets = ir_emit_struct_ep(proc, tag, 2);
|
||||
irValue *offset_array_elem = ir_array_elem(proc, offset_array);
|
||||
ir_fill_slice(proc, offsets, offset_array_elem, v_count);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_BitSet:
|
||||
ir_emit_comment(proc, str_lit("Type_Info_Bit_Set"));
|
||||
tag = ir_emit_conv(proc, variant_ptr, t_type_info_bit_set_ptr);
|
||||
|
||||
@@ -635,15 +635,6 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
|
||||
ir_print_type(f, m, t->Map.internal_type);
|
||||
break;
|
||||
|
||||
case Type_BitField: {
|
||||
i64 align = type_align_of(t);
|
||||
i64 size = type_size_of(t);
|
||||
ir_write_string(f, str_lit("<{"));
|
||||
ir_print_alignment_prefix_hack(f, align);
|
||||
ir_fprintf(f, ", [%lld x i8]}>", size);
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_BitSet: {
|
||||
i64 size = type_size_of(t);
|
||||
if (size == 0) {
|
||||
@@ -2641,7 +2632,6 @@ bool ir_print_global_type_allowed(Type *t) {
|
||||
case Type_DynamicArray:
|
||||
case Type_Map:
|
||||
case Type_Union:
|
||||
case Type_BitField:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,15 +108,6 @@ lbAddr lb_addr_soa_variable(lbValue addr, lbValue index, Ast *index_expr) {
|
||||
return v;
|
||||
}
|
||||
|
||||
lbAddr lb_addr_bit_field(lbValue value, i32 index) {
|
||||
lbAddr addr = {};
|
||||
addr.kind = lbAddr_BitField;
|
||||
addr.addr = value;
|
||||
addr.bit_field.value_index = index;
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
||||
Type *lb_addr_type(lbAddr const &addr) {
|
||||
if (addr.addr.value == nullptr) {
|
||||
return nullptr;
|
||||
@@ -176,11 +167,6 @@ lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
||||
return final_ptr;
|
||||
}
|
||||
|
||||
case lbAddr_BitField: {
|
||||
lbValue v = lb_addr_load(p, addr);
|
||||
return lb_address_from_load_or_generate_local(p, v);
|
||||
}
|
||||
|
||||
case lbAddr_Context:
|
||||
GB_PANIC("lbAddr_Context should be handled elsewhere");
|
||||
}
|
||||
@@ -403,24 +389,6 @@ void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) {
|
||||
} else if (addr.kind == lbAddr_Map) {
|
||||
lb_insert_dynamic_map_key_and_value(p, addr, addr.map.type, addr.map.key, value, p->curr_stmt);
|
||||
return;
|
||||
} else if (addr.kind == lbAddr_BitField) {
|
||||
Type *bft = base_type(type_deref(addr.addr.type));
|
||||
GB_ASSERT(is_type_bit_field(bft));
|
||||
|
||||
unsigned value_index = cast(unsigned)addr.bit_field.value_index;
|
||||
i32 size_in_bits = bft->BitField.fields[value_index]->type->BitFieldValue.bits;
|
||||
if (size_in_bits == 0) {
|
||||
return;
|
||||
}
|
||||
i32 size_in_bytes = next_pow2((size_in_bits+7)/8);
|
||||
|
||||
LLVMTypeRef dst_type = LLVMIntTypeInContext(p->module->ctx, size_in_bits);
|
||||
LLVMValueRef src = LLVMBuildIntCast2(p->builder, value.value, dst_type, false, "");
|
||||
|
||||
LLVMValueRef internal_data = LLVMBuildStructGEP(p->builder, addr.addr.value, 1, "");
|
||||
LLVMValueRef field_ptr = LLVMBuildStructGEP(p->builder, internal_data, value_index, "");
|
||||
LLVMBuildStore(p->builder, src, field_ptr);
|
||||
return;
|
||||
} else if (addr.kind == lbAddr_Context) {
|
||||
lbValue old = lb_addr_load(p, lb_find_or_generate_context_ptr(p));
|
||||
lbAddr next_addr = lb_add_local_generated(p, t_context, true);
|
||||
@@ -622,41 +590,6 @@ lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) {
|
||||
lbValue single = lb_emit_struct_ep(p, v.addr, 0);
|
||||
return lb_emit_load(p, single);
|
||||
}
|
||||
|
||||
} else if (addr.kind == lbAddr_BitField) {
|
||||
Type *bft = base_type(type_deref(addr.addr.type));
|
||||
GB_ASSERT(is_type_bit_field(bft));
|
||||
|
||||
unsigned value_index = cast(unsigned)addr.bit_field.value_index;
|
||||
i32 size_in_bits = bft->BitField.fields[value_index]->type->BitFieldValue.bits;
|
||||
|
||||
i32 size_in_bytes = next_pow2((size_in_bits+7)/8);
|
||||
if (size_in_bytes == 0) {
|
||||
GB_ASSERT(size_in_bits == 0);
|
||||
lbValue res = {};
|
||||
res.type = t_i32;
|
||||
res.value = LLVMConstInt(lb_type(p->module, res.type), 0, false);
|
||||
return res;
|
||||
}
|
||||
|
||||
Type *int_type = nullptr;
|
||||
switch (size_in_bytes) {
|
||||
case 1: int_type = t_u8; break;
|
||||
case 2: int_type = t_u16; break;
|
||||
case 4: int_type = t_u32; break;
|
||||
case 8: int_type = t_u64; break;
|
||||
case 16: int_type = t_u128; break;
|
||||
}
|
||||
GB_ASSERT(int_type != nullptr);
|
||||
|
||||
LLVMValueRef internal_data = LLVMBuildStructGEP(p->builder, addr.addr.value, 1, "");
|
||||
LLVMValueRef field_ptr = LLVMBuildStructGEP(p->builder, internal_data, value_index, "");
|
||||
LLVMValueRef field = LLVMBuildLoad(p->builder, field_ptr, "");
|
||||
|
||||
lbValue res = {};
|
||||
res.type = int_type;
|
||||
res.value = LLVMBuildZExtOrBitCast(p->builder, field, lb_type(p->module, int_type), "");
|
||||
return res;
|
||||
} else if (addr.kind == lbAddr_Context) {
|
||||
lbValue a = addr.addr;
|
||||
a.value = LLVMBuildPointerCast(p->builder, a.value, lb_type(p->module, t_context_ptr), "");
|
||||
@@ -1159,7 +1092,6 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
|
||||
case Type_Named:
|
||||
case Type_Generic:
|
||||
case Type_BitFieldValue:
|
||||
GB_PANIC("INVALID TYPE");
|
||||
break;
|
||||
|
||||
@@ -1204,7 +1136,6 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
switch (base->kind) {
|
||||
case Type_Struct:
|
||||
case Type_Union:
|
||||
case Type_BitField:
|
||||
{
|
||||
char const *name = alloc_cstring(permanent_allocator(), lb_get_entity_name(m, type->Named.type_name));
|
||||
LLVMTypeRef llvm_type = LLVMGetTypeByName(m->mod, name);
|
||||
@@ -1497,37 +1428,6 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Type_BitFieldValue:
|
||||
return LLVMIntTypeInContext(m->ctx, type->BitFieldValue.bits);
|
||||
|
||||
case Type_BitField:
|
||||
{
|
||||
LLVMTypeRef internal_type = nullptr;
|
||||
{
|
||||
GB_ASSERT(type->BitField.fields.count == type->BitField.sizes.count);
|
||||
unsigned field_count = cast(unsigned)type->BitField.fields.count;
|
||||
LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, field_count);
|
||||
|
||||
for_array(i, type->BitField.sizes) {
|
||||
u32 size = type->BitField.sizes[i];
|
||||
fields[i] = LLVMIntTypeInContext(m->ctx, size);
|
||||
}
|
||||
|
||||
internal_type = LLVMStructTypeInContext(ctx, fields, field_count, true);
|
||||
}
|
||||
unsigned field_count = 2;
|
||||
LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count);
|
||||
|
||||
i64 alignment = 1;
|
||||
if (type->BitField.custom_align > 0) {
|
||||
alignment = type->BitField.custom_align;
|
||||
}
|
||||
fields[0] = lb_alignment_prefix_type_hack(m, alignment);
|
||||
fields[1] = internal_type;
|
||||
|
||||
return LLVMStructTypeInContext(ctx, fields, field_count, true);
|
||||
}
|
||||
break;
|
||||
case Type_BitSet:
|
||||
{
|
||||
@@ -2017,40 +1917,6 @@ LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
// return LLVMPointerType(t, 0);
|
||||
}
|
||||
break;
|
||||
case Type_BitFieldValue:
|
||||
return nullptr;
|
||||
// return LLVMIntTypeInContext(m->ctx, type->BitFieldValue.bits);
|
||||
|
||||
case Type_BitField:
|
||||
{
|
||||
return nullptr;
|
||||
// LLVMTypeRef internal_type = nullptr;
|
||||
// {
|
||||
// GB_ASSERT(type->BitField.fields.count == type->BitField.sizes.count);
|
||||
// unsigned field_count = cast(unsigned)type->BitField.fields.count;
|
||||
// LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count);
|
||||
// defer (gb_free(heap_allocator(), fields));
|
||||
|
||||
// for_array(i, type->BitField.sizes) {
|
||||
// u32 size = type->BitField.sizes[i];
|
||||
// fields[i] = LLVMIntTypeInContext(m->ctx, size);
|
||||
// }
|
||||
|
||||
// internal_type = LLVMStructTypeInContext(ctx, fields, field_count, true);
|
||||
// }
|
||||
// unsigned field_count = 2;
|
||||
// LLVMTypeRef *fields = gb_alloc_array(heap_allocator(), LLVMTypeRef, field_count);
|
||||
|
||||
// i64 alignment = 1;
|
||||
// if (type->BitField.custom_align > 0) {
|
||||
// alignment = type->BitField.custom_align;
|
||||
// }
|
||||
// fields[0] = lb_alignment_prefix_type_hack(m, alignment);
|
||||
// fields[1] = internal_type;
|
||||
|
||||
// return LLVMStructTypeInContext(ctx, fields, field_count, true);
|
||||
}
|
||||
break;
|
||||
case Type_BitSet:
|
||||
return nullptr;
|
||||
// return LLVMIntTypeInContext(m->ctx, 8*cast(unsigned)type_size_of(type));
|
||||
@@ -5014,7 +4880,6 @@ lbValue lb_typeid(lbModule *m, Type *type) {
|
||||
case Type_Union: kind = Typeid_Union; break;
|
||||
case Type_Tuple: kind = Typeid_Tuple; break;
|
||||
case Type_Proc: kind = Typeid_Procedure; break;
|
||||
case Type_BitField: kind = Typeid_Bit_Field; break;
|
||||
case Type_BitSet: kind = Typeid_Bit_Set; break;
|
||||
case Type_Opaque: kind = Typeid_Opaque; break;
|
||||
case Type_SimdVector: kind = Typeid_Simd_Vector; break;
|
||||
@@ -6836,7 +6701,6 @@ bool lb_is_type_aggregate(Type *t) {
|
||||
case Type_Tuple:
|
||||
case Type_DynamicArray:
|
||||
case Type_Map:
|
||||
case Type_BitField:
|
||||
case Type_SimdVector:
|
||||
return true;
|
||||
|
||||
@@ -9152,14 +9016,6 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
|
||||
} else if (is_type_typeid(t)) {
|
||||
lbValue invalid_typeid = lb_const_value(p->module, t_typeid, exact_value_i64(0));
|
||||
return lb_emit_comp(p, op_kind, x, invalid_typeid);
|
||||
} else if (is_type_bit_field(t)) {
|
||||
auto args = array_make<lbValue>(permanent_allocator(), 2);
|
||||
lbValue lhs = lb_address_from_load_or_generate_local(p, x);
|
||||
args[0] = lb_emit_conv(p, lhs, t_rawptr);
|
||||
args[1] = lb_const_int(p->module, t_int, type_size_of(t));
|
||||
lbValue val = lb_emit_runtime_call(p, "memory_compare_zero", args);
|
||||
lbValue res = lb_emit_comp(p, op_kind, val, lb_const_int(p->module, t_int, 0));
|
||||
return res;
|
||||
} else if (is_type_soa_struct(t)) {
|
||||
Type *bt = base_type(t);
|
||||
if (bt->Struct.soa_kind == StructSoa_Slice) {
|
||||
@@ -9444,33 +9300,31 @@ lbValue lb_emit_comp(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue ri
|
||||
Type *lt = left.type;
|
||||
Type *rt = right.type;
|
||||
|
||||
if (is_type_bit_set(lt) && is_type_bit_set(rt)) {
|
||||
Type *blt = base_type(lt);
|
||||
Type *brt = base_type(rt);
|
||||
GB_ASSERT(is_type_bit_field_value(blt));
|
||||
GB_ASSERT(is_type_bit_field_value(brt));
|
||||
i64 bits = gb_max(blt->BitFieldValue.bits, brt->BitFieldValue.bits);
|
||||
i64 bytes = bits / 8;
|
||||
switch (bytes) {
|
||||
case 1:
|
||||
left = lb_emit_conv(p, left, t_u8);
|
||||
right = lb_emit_conv(p, right, t_u8);
|
||||
break;
|
||||
case 2:
|
||||
left = lb_emit_conv(p, left, t_u16);
|
||||
right = lb_emit_conv(p, right, t_u16);
|
||||
break;
|
||||
case 4:
|
||||
left = lb_emit_conv(p, left, t_u32);
|
||||
right = lb_emit_conv(p, right, t_u32);
|
||||
break;
|
||||
case 8:
|
||||
left = lb_emit_conv(p, left, t_u64);
|
||||
right = lb_emit_conv(p, right, t_u64);
|
||||
break;
|
||||
default: GB_PANIC("Unknown integer size"); break;
|
||||
}
|
||||
}
|
||||
// if (is_type_bit_set(lt) && is_type_bit_set(rt)) {
|
||||
// Type *blt = base_type(lt);
|
||||
// Type *brt = base_type(rt);
|
||||
// i64 bits = gb_max(blt->BitSet.bits, brt->BitSet.bits);
|
||||
// i64 bytes = bits / 8;
|
||||
// switch (bytes) {
|
||||
// case 1:
|
||||
// left = lb_emit_conv(p, left, t_u8);
|
||||
// right = lb_emit_conv(p, right, t_u8);
|
||||
// break;
|
||||
// case 2:
|
||||
// left = lb_emit_conv(p, left, t_u16);
|
||||
// right = lb_emit_conv(p, right, t_u16);
|
||||
// break;
|
||||
// case 4:
|
||||
// left = lb_emit_conv(p, left, t_u32);
|
||||
// right = lb_emit_conv(p, right, t_u32);
|
||||
// break;
|
||||
// case 8:
|
||||
// left = lb_emit_conv(p, left, t_u64);
|
||||
// right = lb_emit_conv(p, right, t_u64);
|
||||
// break;
|
||||
// default: GB_PANIC("Unknown integer size"); break;
|
||||
// }
|
||||
// }
|
||||
|
||||
lt = left.type;
|
||||
rt = right.type;
|
||||
@@ -10632,23 +10486,7 @@ lbAddr lb_build_addr(lbProcedure *p, Ast *expr) {
|
||||
Selection sel = lookup_field(type, selector, false);
|
||||
GB_ASSERT(sel.entity != nullptr);
|
||||
|
||||
|
||||
if (sel.entity->type->kind == Type_BitFieldValue) {
|
||||
lbAddr addr = lb_build_addr(p, se->expr);
|
||||
Type *bft = type_deref(lb_addr_type(addr));
|
||||
if (sel.index.count == 1) {
|
||||
GB_ASSERT(is_type_bit_field(bft));
|
||||
i32 index = sel.index[0];
|
||||
return lb_addr_bit_field(lb_addr_get_ptr(p, addr), index);
|
||||
} else {
|
||||
Selection s = sel;
|
||||
s.index.count--;
|
||||
i32 index = s.index[s.index.count-1];
|
||||
lbValue a = lb_addr_get_ptr(p, addr);
|
||||
a = lb_emit_deep_field_gep(p, a, s);
|
||||
return lb_addr_bit_field(a, index);
|
||||
}
|
||||
} else {
|
||||
{
|
||||
lbAddr addr = lb_build_addr(p, se->expr);
|
||||
if (addr.kind == lbAddr_Map) {
|
||||
lbValue v = lb_addr_load(p, addr);
|
||||
@@ -12547,52 +12385,6 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_BitField: {
|
||||
tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_bit_field_ptr);
|
||||
// names: []string;
|
||||
// bits: []u32;
|
||||
// offsets: []u32;
|
||||
isize count = t->BitField.fields.count;
|
||||
if (count > 0) {
|
||||
auto fields = t->BitField.fields;
|
||||
lbValue name_array = lb_generate_global_array(m, t_string, count, str_lit("$bit_field_names"), cast(i64)entry_index);
|
||||
lbValue bit_array = lb_generate_global_array(m, t_i32, count, str_lit("$bit_field_bits"), cast(i64)entry_index);
|
||||
lbValue offset_array = lb_generate_global_array(m, t_i32, count, str_lit("$bit_field_offsets"), cast(i64)entry_index);
|
||||
|
||||
for (isize i = 0; i < count; i++) {
|
||||
Entity *f = fields[i];
|
||||
GB_ASSERT(f->type != nullptr);
|
||||
GB_ASSERT(f->type->kind == Type_BitFieldValue);
|
||||
lbValue name_ep = lb_emit_array_epi(p, name_array, cast(i32)i);
|
||||
lbValue bit_ep = lb_emit_array_epi(p, bit_array, cast(i32)i);
|
||||
lbValue offset_ep = lb_emit_array_epi(p, offset_array, cast(i32)i);
|
||||
|
||||
lb_emit_store(p, name_ep, lb_const_string(m, f->token.string));
|
||||
lb_emit_store(p, bit_ep, lb_const_int(m, t_i32, f->type->BitFieldValue.bits));
|
||||
lb_emit_store(p, offset_ep, lb_const_int(m, t_i32, t->BitField.offsets[i]));
|
||||
|
||||
}
|
||||
|
||||
lbValue v_count = lb_const_int(m, t_int, count);
|
||||
lbValue name_array_elem = lb_array_elem(p, name_array);
|
||||
lbValue bit_array_elem = lb_array_elem(p, bit_array);
|
||||
lbValue offset_array_elem = lb_array_elem(p, offset_array);
|
||||
|
||||
|
||||
LLVMValueRef vals[3] = {
|
||||
llvm_const_slice(name_array_elem, v_count),
|
||||
llvm_const_slice(bit_array_elem, v_count),
|
||||
llvm_const_slice(offset_array_elem, v_count),
|
||||
};
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = LLVMConstNamedStruct(lb_type(m, res.type), vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Type_BitSet:
|
||||
{
|
||||
tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_bit_set_ptr);
|
||||
|
||||
@@ -43,7 +43,6 @@ struct lbValue {
|
||||
enum lbAddrKind {
|
||||
lbAddr_Default,
|
||||
lbAddr_Map,
|
||||
lbAddr_BitField,
|
||||
lbAddr_Context,
|
||||
lbAddr_SoaVariable,
|
||||
|
||||
|
||||
@@ -606,13 +606,11 @@ void generate_and_print_query_data_global_definitions(Checker *c, Timings *timin
|
||||
case Type_Union: type_kind = str_lit("union"); break;
|
||||
case Type_Enum: type_kind = str_lit("enum"); break;
|
||||
case Type_Proc: type_kind = str_lit("procedure"); break;
|
||||
case Type_BitField: type_kind = str_lit("bit field"); break;
|
||||
case Type_BitSet: type_kind = str_lit("bit set"); break;
|
||||
case Type_SimdVector: type_kind = str_lit("simd vector"); break;
|
||||
|
||||
case Type_Generic:
|
||||
case Type_Tuple:
|
||||
case Type_BitFieldValue:
|
||||
GB_PANIC("Invalid definition type");
|
||||
break;
|
||||
}
|
||||
|
||||
140
src/types.cpp
140
src/types.cpp
@@ -272,14 +272,6 @@ struct TypeProc {
|
||||
bool is_packed; \
|
||||
}) \
|
||||
TYPE_KIND(Proc, TypeProc) \
|
||||
TYPE_KIND(BitFieldValue, struct { u32 bits; }) \
|
||||
TYPE_KIND(BitField, struct { \
|
||||
Array<Entity *> fields; \
|
||||
Array<u32> offsets; \
|
||||
Array<u32> sizes; \
|
||||
Scope * scope; \
|
||||
i64 custom_align; \
|
||||
}) \
|
||||
TYPE_KIND(BitSet, struct { \
|
||||
Type *elem; \
|
||||
Type *underlying; \
|
||||
@@ -972,16 +964,6 @@ Type *alloc_type_map(i64 count, Type *key, Type *value) {
|
||||
return t;
|
||||
}
|
||||
|
||||
Type *alloc_type_bit_field_value(u32 bits) {
|
||||
Type *t = alloc_type(Type_BitFieldValue);
|
||||
t->BitFieldValue.bits = bits;
|
||||
return t;
|
||||
}
|
||||
|
||||
Type *alloc_type_bit_field() {
|
||||
Type *t = alloc_type(Type_BitField);
|
||||
return t;
|
||||
}
|
||||
Type *alloc_type_bit_set() {
|
||||
Type *t = alloc_type(Type_BitSet);
|
||||
return t;
|
||||
@@ -1363,14 +1345,6 @@ bool is_type_enum(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Enum);
|
||||
}
|
||||
bool is_type_bit_field(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_BitField);
|
||||
}
|
||||
bool is_type_bit_field_value(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_BitFieldValue);
|
||||
}
|
||||
bool is_type_bit_set(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_BitSet);
|
||||
@@ -1853,7 +1827,6 @@ bool type_has_nil(Type *t) {
|
||||
} break;
|
||||
case Type_Enum:
|
||||
case Type_BitSet:
|
||||
case Type_BitField:
|
||||
return true;
|
||||
case Type_Slice:
|
||||
case Type_Proc:
|
||||
@@ -1926,9 +1899,6 @@ bool is_type_comparable(Type *t) {
|
||||
case Type_BitSet:
|
||||
return true;
|
||||
|
||||
case Type_BitFieldValue:
|
||||
return true;
|
||||
|
||||
case Type_Opaque:
|
||||
return is_type_comparable(t->Opaque.elem);
|
||||
|
||||
@@ -1972,7 +1942,6 @@ bool is_type_simple_compare(Type *t) {
|
||||
case Type_Pointer:
|
||||
case Type_Proc:
|
||||
case Type_BitSet:
|
||||
case Type_BitField:
|
||||
return true;
|
||||
|
||||
case Type_Struct:
|
||||
@@ -2072,24 +2041,6 @@ bool are_types_identical(Type *x, Type *y) {
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_BitField:
|
||||
if (y->kind == Type_BitField) {
|
||||
if (x->BitField.fields.count == y->BitField.fields.count &&
|
||||
x->BitField.custom_align == y->BitField.custom_align) {
|
||||
for (i32 i = 0; i < x->BitField.fields.count; i++) {
|
||||
if (x->BitField.offsets[i] != y->BitField.offsets[i]) {
|
||||
return false;
|
||||
}
|
||||
if (x->BitField.sizes[i] != y->BitField.sizes[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_BitSet:
|
||||
if (y->kind == Type_BitSet) {
|
||||
return are_types_identical(x->BitSet.elem, y->BitSet.elem) &&
|
||||
@@ -2225,25 +2176,6 @@ bool are_types_identical(Type *x, Type *y) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Type *default_bit_field_value_type(Type *type) {
|
||||
if (type == nullptr) {
|
||||
return t_invalid;
|
||||
}
|
||||
Type *t = base_type(type);
|
||||
if (t->kind == Type_BitFieldValue) {
|
||||
i32 bits = t->BitFieldValue.bits;
|
||||
i32 size = 8*next_pow2((bits+7)/8);
|
||||
switch (size) {
|
||||
case 8: return t_u8;
|
||||
case 16: return t_u16;
|
||||
case 32: return t_u32;
|
||||
case 64: return t_u64;
|
||||
default: GB_PANIC("Too big of a bit size!"); break;
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
Type *default_type(Type *type) {
|
||||
if (type == nullptr) {
|
||||
return t_invalid;
|
||||
@@ -2259,9 +2191,6 @@ Type *default_type(Type *type) {
|
||||
case Basic_UntypedRune: return t_rune;
|
||||
}
|
||||
}
|
||||
if (type->kind == Type_BitFieldValue) {
|
||||
return default_bit_field_value_type(type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@@ -2428,7 +2357,6 @@ Selection lookup_field_from_index(Type *type, i64 index) {
|
||||
switch (type->kind) {
|
||||
case Type_Struct: max_count = type->Struct.fields.count; break;
|
||||
case Type_Tuple: max_count = type->Tuple.variables.count; break;
|
||||
case Type_BitField: max_count = type->BitField.fields.count; break;
|
||||
}
|
||||
|
||||
if (index >= max_count) {
|
||||
@@ -2458,13 +2386,6 @@ Selection lookup_field_from_index(Type *type, i64 index) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_BitField: {
|
||||
auto sel_array = array_make<i32>(a, 1);
|
||||
sel_array[0] = cast(i32)index;
|
||||
return make_selection(type->BitField.fields[cast(isize)index], sel_array, false);
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
GB_PANIC("Illegal index");
|
||||
@@ -2592,22 +2513,6 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
|
||||
else if (field_name == "a") mapped_field_name = str_lit("w");
|
||||
return lookup_field_with_selection(type, mapped_field_name, is_type, sel, allow_blank_ident);
|
||||
}
|
||||
|
||||
} else if (type->kind == Type_BitField) {
|
||||
for_array(i, type->BitField.fields) {
|
||||
Entity *f = type->BitField.fields[i];
|
||||
if (f->kind != Entity_Variable ||
|
||||
(f->flags & EntityFlag_BitFieldValue) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String str = f->token.string;
|
||||
if (field_name == str) {
|
||||
selection_add_index(&sel, i); // HACK(bill): Leaky memory
|
||||
sel.entity = f;
|
||||
return sel;
|
||||
}
|
||||
}
|
||||
} else if (type->kind == Type_Basic) {
|
||||
switch (type->Basic.kind) {
|
||||
case Basic_any: {
|
||||
@@ -3022,14 +2927,6 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
}
|
||||
} break;
|
||||
|
||||
case Type_BitField: {
|
||||
i64 align = 1;
|
||||
if (t->BitField.custom_align > 0) {
|
||||
align = t->BitField.custom_align;
|
||||
}
|
||||
return gb_clamp(next_pow2(align), 1, build_context.max_align);
|
||||
} break;
|
||||
|
||||
case Type_BitSet: {
|
||||
if (t->BitSet.underlying != nullptr) {
|
||||
return type_align_of(t->BitSet.underlying);
|
||||
@@ -3299,18 +3196,6 @@ i64 type_size_of_internal(Type *t, TypePath *path) {
|
||||
}
|
||||
} break;
|
||||
|
||||
case Type_BitField: {
|
||||
i64 align = 8*type_align_of_internal(t, path);
|
||||
i64 end = 0;
|
||||
if (t->BitField.fields.count > 0) {
|
||||
i64 last = t->BitField.fields.count-1;
|
||||
end = t->BitField.offsets[cast(isize)last] + t->BitField.sizes[cast(isize)last];
|
||||
}
|
||||
i64 bits = align_formula(end, align);
|
||||
GB_ASSERT((bits%8) == 0);
|
||||
return bits/8;
|
||||
} break;
|
||||
|
||||
case Type_BitSet: {
|
||||
if (t->BitSet.underlying != nullptr) {
|
||||
return type_size_of(t->BitSet.underlying);
|
||||
@@ -3761,31 +3646,6 @@ gbString write_type_to_string(gbString str, Type *type) {
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_BitField:
|
||||
str = gb_string_appendc(str, "bit_field ");
|
||||
if (type->BitField.custom_align != 0) {
|
||||
str = gb_string_append_fmt(str, "#align %d ", cast(int)type->BitField.custom_align);
|
||||
}
|
||||
str = gb_string_append_rune(str, '{');
|
||||
|
||||
for_array(i, type->BitField.fields) {
|
||||
Entity *f = type->BitField.fields[i];
|
||||
GB_ASSERT(f->kind == Entity_Variable);
|
||||
GB_ASSERT(f->type != nullptr && f->type->kind == Type_BitFieldValue);
|
||||
if (i > 0) {
|
||||
str = gb_string_appendc(str, ", ");
|
||||
}
|
||||
str = gb_string_append_length(str, f->token.string.text, f->token.string.len);
|
||||
str = gb_string_appendc(str, ": ");
|
||||
str = gb_string_append_fmt(str, "%lld", cast(long long)f->type->BitFieldValue.bits);
|
||||
}
|
||||
str = gb_string_append_rune(str, '}');
|
||||
break;
|
||||
|
||||
case Type_BitFieldValue:
|
||||
str = gb_string_append_fmt(str, "(bit field value with %d bits)", cast(int)type->BitFieldValue.bits);
|
||||
break;
|
||||
|
||||
case Type_BitSet:
|
||||
str = gb_string_appendc(str, "bit_set[");
|
||||
str = write_type_to_string(str, type->BitSet.elem);
|
||||
|
||||
Reference in New Issue
Block a user