mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Support using of a bit_field within a struct
This commit is contained in:
@@ -89,6 +89,8 @@ gb_internal bool does_field_type_allow_using(Type *t) {
|
|||||||
return true;
|
return true;
|
||||||
} else if (is_type_array(t)) {
|
} else if (is_type_array(t)) {
|
||||||
return t->Array.count <= 4;
|
return t->Array.count <= 4;
|
||||||
|
} else if (is_type_bit_field(t)) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4679,12 +4679,20 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
|||||||
GB_ASSERT(sel.entity != nullptr);
|
GB_ASSERT(sel.entity != nullptr);
|
||||||
if (sel.is_bit_field) {
|
if (sel.is_bit_field) {
|
||||||
lbAddr addr = lb_build_addr(p, se->expr);
|
lbAddr addr = lb_build_addr(p, se->expr);
|
||||||
Type *bf_type = base_type(type_deref(lb_addr_type(addr)));
|
|
||||||
|
|
||||||
|
Selection sub_sel = sel;
|
||||||
|
sub_sel.index.count -= 1;
|
||||||
|
|
||||||
|
Type *bf_type = type_from_selection(type, sub_sel);
|
||||||
|
bf_type = base_type(type_deref(bf_type));
|
||||||
GB_ASSERT(bf_type->kind == Type_BitField);
|
GB_ASSERT(bf_type->kind == Type_BitField);
|
||||||
|
|
||||||
lbValue a = lb_addr_get_ptr(p, addr);
|
lbValue a = lb_addr_get_ptr(p, addr);
|
||||||
Selection sub_sel = sel;
|
if (sub_sel.index.count > 0) {
|
||||||
sub_sel.index.count -= 1;
|
a = lb_emit_deep_field_gep(p, a, sub_sel);
|
||||||
|
}
|
||||||
|
|
||||||
i32 index = sel.index[sel.index.count-1];
|
i32 index = sel.index[sel.index.count-1];
|
||||||
|
|
||||||
Entity *f = bf_type->BitField.fields[index];
|
Entity *f = bf_type->BitField.fields[index];
|
||||||
|
|||||||
@@ -1332,7 +1332,7 @@ gb_internal lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection
|
|||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
type = t_rawptr;
|
type = t_rawptr;
|
||||||
} else if (index == 1) {
|
} else if (index == 1) {
|
||||||
type = t_type_info_ptr;
|
type = t_typeid;
|
||||||
}
|
}
|
||||||
e = lb_emit_struct_ep(p, e, index);
|
e = lb_emit_struct_ep(p, e, index);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+69
-2
@@ -385,6 +385,9 @@ enum : int {
|
|||||||
|
|
||||||
gb_internal bool is_type_comparable(Type *t);
|
gb_internal bool is_type_comparable(Type *t);
|
||||||
gb_internal bool is_type_simple_compare(Type *t);
|
gb_internal bool is_type_simple_compare(Type *t);
|
||||||
|
gb_internal Type *type_deref(Type *t, bool allow_multi_pointer=false);
|
||||||
|
gb_internal Type *base_type(Type *t);
|
||||||
|
gb_internal Type *alloc_type_multi_pointer(Type *elem);
|
||||||
|
|
||||||
gb_internal u32 type_info_flags_of_type(Type *type) {
|
gb_internal u32 type_info_flags_of_type(Type *type) {
|
||||||
if (type == nullptr) {
|
if (type == nullptr) {
|
||||||
@@ -762,7 +765,6 @@ gb_internal bool is_type_proc(Type *t);
|
|||||||
gb_internal bool is_type_slice(Type *t);
|
gb_internal bool is_type_slice(Type *t);
|
||||||
gb_internal bool is_type_integer(Type *t);
|
gb_internal bool is_type_integer(Type *t);
|
||||||
gb_internal bool type_set_offsets(Type *t);
|
gb_internal bool type_set_offsets(Type *t);
|
||||||
gb_internal Type *base_type(Type *t);
|
|
||||||
|
|
||||||
gb_internal i64 type_size_of_internal(Type *t, TypePath *path);
|
gb_internal i64 type_size_of_internal(Type *t, TypePath *path);
|
||||||
gb_internal i64 type_align_of_internal(Type *t, TypePath *path);
|
gb_internal i64 type_align_of_internal(Type *t, TypePath *path);
|
||||||
@@ -1157,7 +1159,7 @@ gb_internal Type *alloc_type_simd_vector(i64 count, Type *elem, Type *generic_co
|
|||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
gb_internal Type *type_deref(Type *t, bool allow_multi_pointer=false) {
|
gb_internal Type *type_deref(Type *t, bool allow_multi_pointer) {
|
||||||
if (t != nullptr) {
|
if (t != nullptr) {
|
||||||
Type *bt = base_type(t);
|
Type *bt = base_type(t);
|
||||||
if (bt == nullptr) {
|
if (bt == nullptr) {
|
||||||
@@ -4261,6 +4263,71 @@ gb_internal Type *alloc_type_proc_from_types(Type **param_types, unsigned param_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gb_internal Type *type_from_selection(Type *type, Selection const &sel) {
|
||||||
|
for (i32 index : sel.index) {
|
||||||
|
Type *bt = base_type(type_deref(type));
|
||||||
|
switch (bt->kind) {
|
||||||
|
case Type_Struct:
|
||||||
|
type = bt->Struct.fields[index]->type;
|
||||||
|
break;
|
||||||
|
case Type_Tuple:
|
||||||
|
type = bt->Tuple.variables[index]->type;
|
||||||
|
break;
|
||||||
|
case Type_BitField:
|
||||||
|
type = bt->BitField.fields[index]->type;
|
||||||
|
break;
|
||||||
|
case Type_Array:
|
||||||
|
type = bt->Array.elem;
|
||||||
|
break;
|
||||||
|
case Type_EnumeratedArray:
|
||||||
|
type = bt->Array.elem;
|
||||||
|
break;
|
||||||
|
case Type_Slice:
|
||||||
|
switch (index) {
|
||||||
|
case 0: type = alloc_type_multi_pointer(bt->Slice.elem); break;
|
||||||
|
case 1: type = t_int; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type_DynamicArray:
|
||||||
|
switch (index) {
|
||||||
|
case 0: type = alloc_type_multi_pointer(bt->DynamicArray.elem); break;
|
||||||
|
case 1: type = t_int; break;
|
||||||
|
case 2: type = t_int; break;
|
||||||
|
case 3: type = t_allocator; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type_Map:
|
||||||
|
switch (index) {
|
||||||
|
case 0: type = t_uintptr; break;
|
||||||
|
case 1: type = t_int; break;
|
||||||
|
case 2: type = t_allocator; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Type_Basic:
|
||||||
|
if (is_type_complex_or_quaternion(bt)) {
|
||||||
|
type = base_complex_elem_type(bt);
|
||||||
|
} else {
|
||||||
|
switch (type->Basic.kind) {
|
||||||
|
case Basic_any:
|
||||||
|
switch (index) {
|
||||||
|
case 0: type = t_rawptr; break;
|
||||||
|
case 1: type = t_typeid; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Basic_string:
|
||||||
|
switch (index) {
|
||||||
|
case 0: type = t_u8_multi_ptr; break;
|
||||||
|
case 1: type = t_int; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gb_internal gbString write_type_to_string(gbString str, Type *type, bool shorthand=false) {
|
gb_internal gbString write_type_to_string(gbString str, Type *type, bool shorthand=false) {
|
||||||
if (type == nullptr) {
|
if (type == nullptr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user