mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-27 07:51:49 -07:00
Add #soa pointer type to aid with refactoring to #soa data types
a: #soa[16]Foo p := &a[6] #assert(type_of(p) == #soa^#soa[16]Foo) p^.x = 123 p.x = 123
This commit is contained in:
+1
-1
@@ -320,7 +320,7 @@ void check_type_decl(CheckerContext *ctx, Entity *e, Ast *init_expr, Type *def)
|
||||
} else if (is_type_any(e->type)) {
|
||||
error(init_expr, "'distinct' cannot be applied to 'any'");
|
||||
is_distinct = false;
|
||||
} else if (is_type_simd_vector(e->type)) {
|
||||
} else if (is_type_simd_vector(e->type) || is_type_soa_pointer(e->type)) {
|
||||
gbString str = type_to_string(e->type);
|
||||
error(init_expr, "'distinct' cannot be applied to '%s'", str);
|
||||
gb_string_free(str);
|
||||
|
||||
+17
-5
@@ -2052,7 +2052,7 @@ bool check_is_not_addressable(CheckerContext *c, Operand *o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return o->mode != Addressing_Variable;
|
||||
return o->mode != Addressing_Variable && o->mode != Addressing_SoaVariable;
|
||||
}
|
||||
|
||||
void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) {
|
||||
@@ -2069,9 +2069,6 @@ void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) {
|
||||
error(op, "Cannot take the pointer address of '%s' which is a procedure parameter", str);
|
||||
} else {
|
||||
switch (o->mode) {
|
||||
case Addressing_SoaVariable:
|
||||
error(op, "Cannot take the pointer address of '%s' as it is an indirect index of an SOA struct", str);
|
||||
break;
|
||||
case Addressing_Constant:
|
||||
error(op, "Cannot take the pointer address of '%s' which is a constant", str);
|
||||
break;
|
||||
@@ -2099,7 +2096,19 @@ void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) {
|
||||
return;
|
||||
}
|
||||
|
||||
o->type = alloc_type_pointer(o->type);
|
||||
if (o->mode == Addressing_SoaVariable) {
|
||||
ast_node(ue, UnaryExpr, node);
|
||||
if (ast_node_expect(ue->expr, Ast_IndexExpr)) {
|
||||
ast_node(ie, IndexExpr, ue->expr);
|
||||
Type *soa_type = type_of_expr(ie->expr);
|
||||
GB_ASSERT(is_type_soa_struct(soa_type));
|
||||
o->type = alloc_type_soa_pointer(soa_type);
|
||||
} else {
|
||||
o->type = alloc_type_pointer(o->type);
|
||||
}
|
||||
} else {
|
||||
o->type = alloc_type_pointer(o->type);
|
||||
}
|
||||
|
||||
switch (o->mode) {
|
||||
case Addressing_OptionalOk:
|
||||
@@ -9378,6 +9387,9 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
||||
if (t->kind == Type_Pointer && !is_type_empty_union(t->Pointer.elem)) {
|
||||
o->mode = Addressing_Variable;
|
||||
o->type = t->Pointer.elem;
|
||||
} else if (t->kind == Type_SoaPointer) {
|
||||
o->mode = Addressing_SoaVariable;
|
||||
o->type = type_deref(t);
|
||||
} else if (t->kind == Type_RelativePointer) {
|
||||
if (o->mode != Addressing_Variable) {
|
||||
gbString str = expr_to_string(o->expr);
|
||||
|
||||
+24
-4
@@ -2693,9 +2693,12 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
|
||||
case_ast_node(ue, UnaryExpr, e);
|
||||
switch (ue->op.kind) {
|
||||
case Token_Pointer:
|
||||
*type = alloc_type_pointer(check_type(ctx, ue->expr));
|
||||
set_base_type(named_type, *type);
|
||||
return true;
|
||||
{
|
||||
Type *elem = check_type(ctx, ue->expr);
|
||||
*type = alloc_type_pointer(elem);
|
||||
set_base_type(named_type, *type);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
case_end;
|
||||
|
||||
@@ -2721,7 +2724,24 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
|
||||
elem = o.type;
|
||||
}
|
||||
|
||||
*type = alloc_type_pointer(elem);
|
||||
if (pt->tag != nullptr) {
|
||||
GB_ASSERT(pt->tag->kind == Ast_BasicDirective);
|
||||
String name = pt->tag->BasicDirective.name.string;
|
||||
if (name == "soa") {
|
||||
// TODO(bill): generic #soa pointers
|
||||
if (is_type_soa_struct(elem)) {
|
||||
*type = alloc_type_soa_pointer(elem);
|
||||
} else {
|
||||
error(pt->tag, "#soa pointers require an #soa record type as the element");
|
||||
*type = alloc_type_pointer(elem);
|
||||
}
|
||||
} else {
|
||||
error(pt->tag, "Invalid tag applied to pointer, got #%.*s", LIT(name));
|
||||
*type = alloc_type_pointer(elem);
|
||||
}
|
||||
} else {
|
||||
*type = alloc_type_pointer(elem);
|
||||
}
|
||||
set_base_type(named_type, *type);
|
||||
return true;
|
||||
case_end;
|
||||
|
||||
@@ -1947,6 +1947,11 @@ void add_type_info_type_internal(CheckerContext *c, Type *t) {
|
||||
add_type_info_type_internal(c, bt->Matrix.elem);
|
||||
break;
|
||||
|
||||
case Type_SoaPointer:
|
||||
add_type_info_type_internal(c, bt->SoaPointer.elem);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
GB_PANIC("Unhandled type: %*.s %d", LIT(type_strings[bt->kind]), bt->kind);
|
||||
break;
|
||||
@@ -2164,6 +2169,10 @@ void add_min_dep_type_info(Checker *c, Type *t) {
|
||||
add_min_dep_type_info(c, bt->Matrix.elem);
|
||||
break;
|
||||
|
||||
case Type_SoaPointer:
|
||||
add_min_dep_type_info(c, bt->SoaPointer.elem);
|
||||
break;
|
||||
|
||||
default:
|
||||
GB_PANIC("Unhandled type: %*.s", LIT(type_strings[bt->kind]));
|
||||
break;
|
||||
@@ -2756,6 +2765,7 @@ void init_core_type_info(Checker *c) {
|
||||
t_type_info_relative_pointer = find_core_type(c, str_lit("Type_Info_Relative_Pointer"));
|
||||
t_type_info_relative_slice = find_core_type(c, str_lit("Type_Info_Relative_Slice"));
|
||||
t_type_info_matrix = find_core_type(c, str_lit("Type_Info_Matrix"));
|
||||
t_type_info_soa_pointer = find_core_type(c, str_lit("Type_Info_Soa_Pointer"));
|
||||
|
||||
t_type_info_named_ptr = alloc_type_pointer(t_type_info_named);
|
||||
t_type_info_integer_ptr = alloc_type_pointer(t_type_info_integer);
|
||||
@@ -2784,6 +2794,7 @@ void init_core_type_info(Checker *c) {
|
||||
t_type_info_relative_pointer_ptr = alloc_type_pointer(t_type_info_relative_pointer);
|
||||
t_type_info_relative_slice_ptr = alloc_type_pointer(t_type_info_relative_slice);
|
||||
t_type_info_matrix_ptr = alloc_type_pointer(t_type_info_matrix);
|
||||
t_type_info_soa_pointer_ptr = alloc_type_pointer(t_type_info_soa_pointer);
|
||||
}
|
||||
|
||||
void init_mem_allocator(Checker *c) {
|
||||
|
||||
@@ -83,6 +83,7 @@ enum OdinDocTypeKind : u32 {
|
||||
OdinDocType_RelativeSlice = 21,
|
||||
OdinDocType_MultiPointer = 22,
|
||||
OdinDocType_Matrix = 23,
|
||||
OdinDocType_SoaPointer = 24,
|
||||
};
|
||||
|
||||
enum OdinDocTypeFlag_Basic : u32 {
|
||||
|
||||
@@ -532,6 +532,10 @@ OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) {
|
||||
doc_type.kind = OdinDocType_MultiPointer;
|
||||
doc_type.types = odin_doc_type_as_slice(w, type->MultiPointer.elem);
|
||||
break;
|
||||
case Type_SoaPointer:
|
||||
doc_type.kind = OdinDocType_SoaPointer;
|
||||
doc_type.types = odin_doc_type_as_slice(w, type->SoaPointer.elem);
|
||||
break;
|
||||
case Type_Array:
|
||||
doc_type.kind = OdinDocType_Array;
|
||||
doc_type.elem_count_len = 1;
|
||||
|
||||
@@ -2803,7 +2803,15 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
|
||||
return {};
|
||||
}
|
||||
|
||||
lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue const &addr, lbValue const &index) {
|
||||
lbAddr v = lb_add_local_generated(p, type, false);
|
||||
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
|
||||
lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
|
||||
lb_emit_store(p, ptr, addr);
|
||||
lb_emit_store(p, idx, index);
|
||||
|
||||
return lb_addr_load(p, v);
|
||||
}
|
||||
|
||||
lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) {
|
||||
ast_node(ue, UnaryExpr, expr);
|
||||
@@ -2842,7 +2850,17 @@ lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) {
|
||||
lb_emit_store(p, gep1, ok);
|
||||
return lb_addr_load(p, res);
|
||||
|
||||
} if (ue_expr->kind == Ast_CompoundLit) {
|
||||
} else if (is_type_soa_pointer(tv.type)) {
|
||||
ast_node(ie, IndexExpr, ue_expr);
|
||||
lbValue addr = lb_build_addr_ptr(p, ie->expr);
|
||||
lbValue index = lb_build_expr(p, ie->index);
|
||||
|
||||
if (!build_context.no_bounds_check) {
|
||||
// TODO(bill): soa bounds checking
|
||||
}
|
||||
|
||||
return lb_make_soa_pointer(p, tv.type, addr, index);
|
||||
} else if (ue_expr->kind == Ast_CompoundLit) {
|
||||
lbValue v = lb_build_expr(p, ue->expr);
|
||||
|
||||
Type *type = v.type;
|
||||
@@ -3604,6 +3622,7 @@ lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
||||
// NOTE(bill): just patch the index in place
|
||||
sel.index[0] = addr.swizzle.indices[sel.index[0]];
|
||||
}
|
||||
|
||||
lbValue a = lb_addr_get_ptr(p, addr);
|
||||
a = lb_emit_deep_field_gep(p, a, sel);
|
||||
return lb_addr(a);
|
||||
@@ -4093,10 +4112,16 @@ lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(de, DerefExpr, expr);
|
||||
if (is_type_relative_pointer(type_of_expr(de->expr))) {
|
||||
Type *t = type_of_expr(de->expr);
|
||||
if (is_type_relative_pointer(t)) {
|
||||
lbAddr addr = lb_build_addr(p, de->expr);
|
||||
addr.relative.deref = true;
|
||||
return addr;\
|
||||
return addr;
|
||||
} else if (is_type_soa_pointer(t)) {
|
||||
lbValue value = lb_build_expr(p, de->expr);
|
||||
lbValue ptr = lb_emit_struct_ev(p, value, 0);
|
||||
lbValue idx = lb_emit_struct_ev(p, value, 1);
|
||||
return lb_addr_soa_variable(ptr, idx, nullptr);
|
||||
}
|
||||
lbValue addr = lb_build_expr(p, de->expr);
|
||||
return lb_addr(addr);
|
||||
|
||||
@@ -916,7 +916,13 @@ lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
||||
Type *t = vt->MultiPointer.elem;
|
||||
LLVMValueRef v = LLVMBuildLoad2(p->builder, llvm_addr_type(value), value.value, "");
|
||||
return lbValue{v, t};
|
||||
} else if (is_type_soa_pointer(value.type)) {
|
||||
lbValue ptr = lb_emit_struct_ev(p, value, 0);
|
||||
lbValue idx = lb_emit_struct_ev(p, value, 1);
|
||||
lbAddr addr = lb_addr_soa_variable(ptr, idx, nullptr);
|
||||
return lb_addr_load(p, addr);
|
||||
}
|
||||
|
||||
GB_ASSERT(is_type_pointer(value.type));
|
||||
Type *t = type_deref(value.type);
|
||||
LLVMValueRef v = LLVMBuildLoad2(p->builder, llvm_addr_type(value), value.value, "");
|
||||
@@ -2055,6 +2061,15 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
m->internal_type_level += 1;
|
||||
return t;
|
||||
}
|
||||
|
||||
case Type_SoaPointer:
|
||||
{
|
||||
unsigned field_count = 2;
|
||||
LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count);
|
||||
fields[0] = LLVMPointerType(lb_type(m, type->Pointer.elem), 0);
|
||||
fields[1] = LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size);
|
||||
return LLVMStructTypeInContext(ctx, fields, field_count, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ lbValue lb_typeid(lbModule *m, Type *type) {
|
||||
case Type_SimdVector: kind = Typeid_Simd_Vector; break;
|
||||
case Type_RelativePointer: kind = Typeid_Relative_Pointer; break;
|
||||
case Type_RelativeSlice: kind = Typeid_Relative_Slice; break;
|
||||
case Type_SoaPointer: kind = Typeid_SoaPointer; break;
|
||||
}
|
||||
|
||||
if (is_type_cstring(type)) {
|
||||
@@ -445,6 +446,20 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
case Type_SoaPointer: {
|
||||
tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_soa_pointer_ptr);
|
||||
lbValue gep = lb_get_type_info_ptr(m, t->SoaPointer.elem);
|
||||
|
||||
LLVMValueRef vals[1] = {
|
||||
gep.value,
|
||||
};
|
||||
|
||||
lbValue res = {};
|
||||
res.type = type_deref(tag.type);
|
||||
res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals));
|
||||
lb_emit_store(p, tag, res);
|
||||
break;
|
||||
}
|
||||
case Type_Array: {
|
||||
tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_array_ptr);
|
||||
i64 ez = type_size_of(t->Array.elem);
|
||||
|
||||
@@ -1007,6 +1007,11 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
||||
case 0: result_type = t->RelativeSlice.base_integer; break;
|
||||
case 1: result_type = t->RelativeSlice.base_integer; break;
|
||||
}
|
||||
} else if (is_type_soa_pointer(t)) {
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break;
|
||||
case 1: result_type = t_int; break;
|
||||
}
|
||||
} else {
|
||||
GB_PANIC("TODO(bill): struct_gep type: %s, %d", type_to_string(s.type), index);
|
||||
}
|
||||
@@ -1137,6 +1142,13 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
|
||||
result_type = t->Array.elem;
|
||||
break;
|
||||
|
||||
case Type_SoaPointer:
|
||||
switch (index) {
|
||||
case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break;
|
||||
case 1: result_type = t_int; break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
GB_PANIC("TODO(bill): struct_ev type: %s, %d", type_to_string(s.type), index);
|
||||
break;
|
||||
@@ -1164,7 +1176,28 @@ lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) {
|
||||
}
|
||||
type = core_type(type);
|
||||
|
||||
if (is_type_quaternion(type)) {
|
||||
if (type->kind == Type_SoaPointer) {
|
||||
lbValue addr = lb_emit_struct_ep(p, e, 0);
|
||||
lbValue index = lb_emit_struct_ep(p, e, 1);
|
||||
addr = lb_emit_load(p, addr);
|
||||
index = lb_emit_load(p, index);
|
||||
|
||||
i32 first_index = sel.index[0];
|
||||
Selection sub_sel = sel;
|
||||
sub_sel.index.data += 1;
|
||||
sub_sel.index.count -= 1;
|
||||
|
||||
lbValue arr = lb_emit_struct_ep(p, addr, first_index);
|
||||
|
||||
Type *t = base_type(type_deref(addr.type));
|
||||
GB_ASSERT(is_type_soa_struct(t));
|
||||
|
||||
if (t->Struct.soa_kind == StructSoa_Fixed) {
|
||||
e = lb_emit_array_ep(p, arr, index);
|
||||
} else {
|
||||
e = lb_emit_ptr_offset(p, lb_emit_load(p, arr), index);
|
||||
}
|
||||
} else if (is_type_quaternion(type)) {
|
||||
e = lb_emit_struct_ep(p, e, index);
|
||||
} else if (is_type_raw_union(type)) {
|
||||
type = get_struct_field_type(type, index);
|
||||
|
||||
+4
-2
@@ -356,6 +356,7 @@ Ast *clone_ast(Ast *node) {
|
||||
break;
|
||||
case Ast_PointerType:
|
||||
n->PointerType.type = clone_ast(n->PointerType.type);
|
||||
n->PointerType.tag = clone_ast(n->PointerType.tag);
|
||||
break;
|
||||
case Ast_MultiPointerType:
|
||||
n->MultiPointerType.type = clone_ast(n->MultiPointerType.type);
|
||||
@@ -2167,10 +2168,11 @@ Ast *parse_operand(AstFile *f, bool lhs) {
|
||||
Ast *original_type = parse_type(f);
|
||||
Ast *type = unparen_expr(original_type);
|
||||
switch (type->kind) {
|
||||
case Ast_ArrayType: type->ArrayType.tag = tag; break;
|
||||
case Ast_ArrayType: type->ArrayType.tag = tag; break;
|
||||
case Ast_DynamicArrayType: type->DynamicArrayType.tag = tag; break;
|
||||
case Ast_PointerType: type->PointerType.tag = tag; break;
|
||||
default:
|
||||
syntax_error(type, "Expected an array type after #%.*s, got %.*s", LIT(name.string), LIT(ast_strings[type->kind]));
|
||||
syntax_error(type, "Expected an array or pointer type after #%.*s, got %.*s", LIT(name.string), LIT(ast_strings[type->kind]));
|
||||
break;
|
||||
}
|
||||
return original_type;
|
||||
|
||||
+2
-1
@@ -650,7 +650,8 @@ AST_KIND(_TypeBegin, "", bool) \
|
||||
}) \
|
||||
AST_KIND(PointerType, "pointer type", struct { \
|
||||
Token token; \
|
||||
Ast *type; \
|
||||
Ast *type; \
|
||||
Ast *tag; \
|
||||
}) \
|
||||
AST_KIND(RelativeType, "relative type", struct { \
|
||||
Ast *tag; \
|
||||
|
||||
+51
-5
@@ -278,7 +278,8 @@ struct TypeProc {
|
||||
Type *generic_row_count; \
|
||||
Type *generic_column_count; \
|
||||
i64 stride_in_bytes; \
|
||||
})
|
||||
}) \
|
||||
TYPE_KIND(SoaPointer, struct { Type *elem; })
|
||||
|
||||
|
||||
enum TypeKind {
|
||||
@@ -350,6 +351,7 @@ enum Typeid_Kind : u8 {
|
||||
Typeid_Relative_Pointer,
|
||||
Typeid_Relative_Slice,
|
||||
Typeid_Matrix,
|
||||
Typeid_SoaPointer,
|
||||
};
|
||||
|
||||
// IMPORTANT NOTE(bill): This must match the same as the in core.odin
|
||||
@@ -644,6 +646,7 @@ gb_global Type *t_type_info_simd_vector = nullptr;
|
||||
gb_global Type *t_type_info_relative_pointer = nullptr;
|
||||
gb_global Type *t_type_info_relative_slice = nullptr;
|
||||
gb_global Type *t_type_info_matrix = nullptr;
|
||||
gb_global Type *t_type_info_soa_pointer = nullptr;
|
||||
|
||||
gb_global Type *t_type_info_named_ptr = nullptr;
|
||||
gb_global Type *t_type_info_integer_ptr = nullptr;
|
||||
@@ -672,6 +675,7 @@ gb_global Type *t_type_info_simd_vector_ptr = nullptr;
|
||||
gb_global Type *t_type_info_relative_pointer_ptr = nullptr;
|
||||
gb_global Type *t_type_info_relative_slice_ptr = nullptr;
|
||||
gb_global Type *t_type_info_matrix_ptr = nullptr;
|
||||
gb_global Type *t_type_info_soa_pointer_ptr = nullptr;
|
||||
|
||||
gb_global Type *t_allocator = nullptr;
|
||||
gb_global Type *t_allocator_ptr = nullptr;
|
||||
@@ -735,6 +739,7 @@ Type * bit_set_to_int(Type *t);
|
||||
bool are_types_identical(Type *x, Type *y);
|
||||
|
||||
bool is_type_pointer(Type *t);
|
||||
bool is_type_soa_pointer(Type *t);
|
||||
bool is_type_proc(Type *t);
|
||||
bool is_type_slice(Type *t);
|
||||
bool is_type_integer(Type *t);
|
||||
@@ -917,6 +922,13 @@ Type *alloc_type_multi_pointer(Type *elem) {
|
||||
return t;
|
||||
}
|
||||
|
||||
Type *alloc_type_soa_pointer(Type *elem) {
|
||||
Type *t = alloc_type(Type_SoaPointer);
|
||||
t->SoaPointer.elem = elem;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
Type *alloc_type_array(Type *elem, i64 count, Type *generic_count = nullptr) {
|
||||
if (generic_count != nullptr) {
|
||||
Type *t = alloc_type(Type_Array);
|
||||
@@ -1109,11 +1121,17 @@ Type *type_deref(Type *t) {
|
||||
if (bt == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
if (bt->kind == Type_Pointer) {
|
||||
switch (bt->kind) {
|
||||
case Type_Pointer:
|
||||
return bt->Pointer.elem;
|
||||
}
|
||||
if (bt->kind == Type_RelativePointer) {
|
||||
case Type_RelativePointer:
|
||||
return type_deref(bt->RelativePointer.pointer_type);
|
||||
case Type_SoaPointer:
|
||||
{
|
||||
Type *elem = base_type(bt->SoaPointer.elem);
|
||||
GB_ASSERT(elem->kind == Type_Struct && elem->Struct.soa_kind != StructSoa_None);
|
||||
return elem->Struct.soa_elem;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
@@ -1327,6 +1345,10 @@ bool is_type_pointer(Type *t) {
|
||||
}
|
||||
return t->kind == Type_Pointer;
|
||||
}
|
||||
bool is_type_soa_pointer(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_SoaPointer;
|
||||
}
|
||||
bool is_type_multi_pointer(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_MultiPointer;
|
||||
@@ -1804,7 +1826,7 @@ bool is_type_dereferenceable(Type *t) {
|
||||
if (is_type_rawptr(t)) {
|
||||
return false;
|
||||
}
|
||||
return is_type_pointer(t);
|
||||
return is_type_pointer(t) || is_type_soa_pointer(t);
|
||||
}
|
||||
|
||||
|
||||
@@ -2079,6 +2101,9 @@ bool is_type_polymorphic(Type *t, bool or_specialized=false) {
|
||||
case Type_Pointer:
|
||||
return is_type_polymorphic(t->Pointer.elem, or_specialized);
|
||||
|
||||
case Type_SoaPointer:
|
||||
return is_type_polymorphic(t->SoaPointer.elem, or_specialized);
|
||||
|
||||
case Type_EnumeratedArray:
|
||||
if (is_type_polymorphic(t->EnumeratedArray.index, or_specialized)) {
|
||||
return true;
|
||||
@@ -2196,6 +2221,7 @@ bool type_has_nil(Type *t) {
|
||||
case Type_Slice:
|
||||
case Type_Proc:
|
||||
case Type_Pointer:
|
||||
case Type_SoaPointer:
|
||||
case Type_MultiPointer:
|
||||
case Type_DynamicArray:
|
||||
case Type_Map:
|
||||
@@ -2262,6 +2288,8 @@ bool is_type_comparable(Type *t) {
|
||||
return true;
|
||||
case Type_Pointer:
|
||||
return true;
|
||||
case Type_SoaPointer:
|
||||
return true;
|
||||
case Type_MultiPointer:
|
||||
return true;
|
||||
case Type_Enum:
|
||||
@@ -2335,6 +2363,7 @@ bool is_type_simple_compare(Type *t) {
|
||||
|
||||
case Type_Pointer:
|
||||
case Type_MultiPointer:
|
||||
case Type_SoaPointer:
|
||||
case Type_Proc:
|
||||
case Type_BitSet:
|
||||
return true;
|
||||
@@ -2558,6 +2587,12 @@ bool are_types_identical_internal(Type *x, Type *y, bool check_tuple_names) {
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_SoaPointer:
|
||||
if (y->kind == Type_SoaPointer) {
|
||||
return are_types_identical(x->SoaPointer.elem, y->SoaPointer.elem);
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_Named:
|
||||
if (y->kind == Type_Named) {
|
||||
return x->Named.type_name == y->Named.type_name;
|
||||
@@ -3475,6 +3510,9 @@ i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
return type_align_of_internal(t->RelativePointer.base_integer, path);
|
||||
case Type_RelativeSlice:
|
||||
return type_align_of_internal(t->RelativeSlice.base_integer, path);
|
||||
|
||||
case Type_SoaPointer:
|
||||
return build_context.word_size;
|
||||
}
|
||||
|
||||
// return gb_clamp(next_pow2(type_size_of(t)), 1, build_context.max_align);
|
||||
@@ -3580,6 +3618,9 @@ i64 type_size_of_internal(Type *t, TypePath *path) {
|
||||
case Type_MultiPointer:
|
||||
return build_context.word_size;
|
||||
|
||||
case Type_SoaPointer:
|
||||
return build_context.word_size*2;
|
||||
|
||||
case Type_Array: {
|
||||
i64 count, align, size, alignment;
|
||||
count = t->Array.count;
|
||||
@@ -4017,6 +4058,11 @@ gbString write_type_to_string(gbString str, Type *type, bool shorthand=false) {
|
||||
str = write_type_to_string(str, type->Pointer.elem);
|
||||
break;
|
||||
|
||||
case Type_SoaPointer:
|
||||
str = gb_string_appendc(str, "#soa ^");
|
||||
str = write_type_to_string(str, type->SoaPointer.elem);
|
||||
break;
|
||||
|
||||
case Type_MultiPointer:
|
||||
str = gb_string_appendc(str, "[^]");
|
||||
str = write_type_to_string(str, type->Pointer.elem);
|
||||
|
||||
Reference in New Issue
Block a user