From d2d243cca8954e686a82f15a37a149c7938362d2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 16 Jul 2023 23:41:51 +0100 Subject: Mock out `cg_emit_conv` --- src/types.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/types.cpp') diff --git a/src/types.cpp b/src/types.cpp index 385ca926d..98be2b6cf 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -3952,6 +3952,7 @@ gb_internal i64 type_offset_of(Type *t, i32 index) { case -1: return align_formula(t->Union.variant_block_size, build_context.ptr_size); // __type_info } } + GB_ASSERT(index == 0); return 0; } -- cgit v1.2.3 From 45b3ae31af0cf4805af2a226ebf0610c7c97bf17 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Jul 2023 00:31:44 +0100 Subject: Mock out more of the `ep` procedures --- src/tilde_backend.hpp | 9 ++ src/tilde_expr.cpp | 45 ++++------ src/tilde_stmt.cpp | 238 +++++++++++++++++++++++++++++++++++++++++++++++++- src/types.cpp | 77 +++++++++++----- 4 files changed, 316 insertions(+), 53 deletions(-) (limited to 'src/types.cpp') diff --git a/src/tilde_backend.hpp b/src/tilde_backend.hpp index 6449bf49f..073e81f5d 100644 --- a/src/tilde_backend.hpp +++ b/src/tilde_backend.hpp @@ -211,6 +211,8 @@ gb_internal cgAddr cg_addr(cgValue const &value); gb_internal cgValue cg_const_value(cgProcedure *p, Type *type, ExactValue const &value); gb_internal cgValue cg_const_nil(cgProcedure *p, Type *type); +gb_internal cgValue cg_flatten_value(cgProcedure *p, cgValue value); + gb_internal void cg_build_stmt(cgProcedure *p, Ast *stmt); gb_internal void cg_build_stmt_list(cgProcedure *p, Slice const &stmts); gb_internal void cg_build_when_stmt(cgProcedure *p, AstWhenStmt *ws); @@ -227,6 +229,7 @@ gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_vol gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue const &src, bool is_volatile=false); gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero_init); +gb_internal cgValue cg_address_from_load_or_generate_local(cgProcedure *p, cgValue value); gb_internal cgValue cg_build_call_expr(cgProcedure *p, Ast *expr); @@ -237,3 +240,9 @@ gb_internal TB_DebugType *cg_debug_type(cgModule *m, Type *type); gb_internal String cg_get_entity_name(cgModule *m, Entity *e); gb_internal cgValue cg_typeid(cgModule *m, Type *t); + +gb_internal cgValue cg_emit_ptr_offset(cgProcedure *p, cgValue ptr, cgValue index); +gb_internal cgValue cg_emit_array_ep(cgProcedure *p, cgValue s, cgValue index); +gb_internal cgValue cg_emit_array_epi(cgProcedure *p, cgValue s, i64 index); +gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index); +gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection const &sel); \ No newline at end of file diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 26c52f1bb..4e43089b2 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -790,11 +790,6 @@ gb_internal cgAddr cg_build_addr_slice_expr(cgProcedure *p, Ast *expr) { tb_inst_store(p->func, TB_TYPE_PTR, data_ptr, offset, cast(TB_CharUnits)build_context.ptr_size, false); tb_inst_store(p->func, TB_TYPE_INT, len_ptr, len, cast(TB_CharUnits)build_context.int_size, false); - - // LLVMValueRef gep0 = cg_emit_struct_ep(p, res.addr, 0).value; - // LLVMValueRef gep1 = cg_emit_struct_ep(p, res.addr, 1).value; - // LLVMBuildStore(p->builder, ptr, gep0); - // LLVMBuildStore(p->builder, len, gep1); return res; } } @@ -1256,10 +1251,8 @@ gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) { cgAddr addr = cg_build_addr(p, se->expr); if (addr.kind == cgAddr_Map) { cgValue v = cg_addr_load(p, addr); - cgValue a = {}; GB_PANIC("TODO(bill): cg_address_from_load_or_generate_local"); - // cgValue a = cg_address_from_load_or_generate_local(p, v); - GB_PANIC("TODO(bill): cg_emit_deep_field_gep"); - // a = cg_emit_deep_field_gep(p, a, sel); + cgValue a = cg_address_from_load_or_generate_local(p, v); + a = cg_emit_deep_field_gep(p, a, sel); return cg_addr(a); } else if (addr.kind == cgAddr_Context) { GB_ASSERT(sel.index.count > 0); @@ -1271,34 +1264,33 @@ gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) { return addr; } else if (addr.kind == cgAddr_SoaVariable) { cgValue index = addr.soa.index; - i32 first_index = sel.index[0]; + i64 first_index = sel.index[0]; Selection sub_sel = sel; sub_sel.index.data += 1; sub_sel.index.count -= 1; - cgValue arr = {}; GB_PANIC("TODO(bill): cg_emit_struct_ep"); - gb_unused(first_index); - // cgValue arr = cg_emit_struct_ep(p, addr.addr, first_index); + cgValue arr = cg_emit_struct_ep(p, addr.addr, first_index); - // Type *t = base_type(type_deref(addr.addr.type)); - // GB_ASSERT(is_type_soa_struct(t)); + Type *t = base_type(type_deref(addr.addr.type)); + GB_ASSERT(is_type_soa_struct(t)); + // TODO(bill): bounds checking for soa variable // if (addr.soa.index_expr != nullptr && (!cg_is_const(addr.soa.index) || t->Struct.soa_kind != StructSoa_Fixed)) { // cgValue len = cg_soa_struct_len(p, addr.addr); // cg_emit_bounds_check(p, ast_token(addr.soa.index_expr), addr.soa.index, len); // } - // cgValue item = {}; + cgValue item = {}; - // if (t->Struct.soa_kind == StructSoa_Fixed) { - // item = cg_emit_array_ep(p, arr, index); - // } else { - // item = cg_emit_ptr_offset(p, cg_emit_load(p, arr), index); - // } - // if (sub_sel.index.count > 0) { - // item = cg_emit_deep_field_gep(p, item, sub_sel); - // } - // return cg_addr(item); + if (t->Struct.soa_kind == StructSoa_Fixed) { + item = cg_emit_array_ep(p, arr, index); + } else { + item = cg_emit_ptr_offset(p, cg_emit_load(p, arr), index); + } + if (sub_sel.index.count > 0) { + item = cg_emit_deep_field_gep(p, item, sub_sel); + } + return cg_addr(item); } else if (addr.kind == cgAddr_Swizzle) { GB_ASSERT(sel.index.count > 0); // NOTE(bill): just patch the index in place @@ -1310,8 +1302,7 @@ gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) { } cgValue a = cg_addr_get_ptr(p, addr); - GB_PANIC("TODO(bill): cg_emit_deep_field_gep"); - // a = cg_emit_deep_field_gep(p, a, sel); + a = cg_emit_deep_field_gep(p, a, sel); return cg_addr(a); } case_end; diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index f70dba115..a38886c2e 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -253,13 +253,13 @@ gb_internal cgValue cg_addr_get_ptr(cgProcedure *p, cgAddr const &addr) { } offset = cg_emit_conv(p, offset, t_uintptr); - GB_PANIC("TODO(bill): cg_addr_get_ptr cgAddr_RelativePointer"); - // cgValue absolute_ptr = cg_emit_arith(p, Token_Add, ptr, offset, t_uintptr); - // absolute_ptr = cg_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type); + cgValue absolute_ptr = cg_emit_arith(p, Token_Add, ptr, offset, t_uintptr); + absolute_ptr = cg_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type); + GB_PANIC("TODO(bill): cg_addr_get_ptr cgAddr_RelativePointer"); // cgValue cond = cg_emit_comp(p, Token_CmpEq, offset, cg_const_nil(p->module, rel_ptr->RelativePointer.base_integer)); - // // NOTE(bill): nil check + // NOTE(bill): nil check // cgValue nil_ptr = cg_const_nil(p->module, rel_ptr->RelativePointer.pointer_type); // cgValue final_ptr = cg_emit_select(p, cond, nil_ptr, absolute_ptr); // return final_ptr; @@ -283,6 +283,219 @@ gb_internal cgValue cg_addr_get_ptr(cgProcedure *p, cgAddr const &addr) { return addr.addr; } +gb_internal cgValue cg_emit_ptr_offset(cgProcedure *p, cgValue ptr, cgValue index) { + GB_ASSERT(ptr.kind == cgValue_Value); + GB_ASSERT(index.kind == cgValue_Value); + GB_ASSERT(is_type_pointer(ptr.type) || is_type_multi_pointer(ptr.type)); + GB_ASSERT(is_type_integer(index.type)); + + Type *elem = type_deref(ptr.type, true); + i64 stride = type_size_of(elem); + ptr.node = tb_inst_array_access(p->func, ptr.node, index.node, stride); + return ptr; +} +gb_internal cgValue cg_emit_array_ep(cgProcedure *p, cgValue s, cgValue index) { + GB_ASSERT(s.kind == cgValue_Value); + GB_ASSERT(index.kind == cgValue_Value); + + Type *t = s.type; + GB_ASSERT_MSG(is_type_pointer(t), "%s", type_to_string(t)); + Type *st = base_type(type_deref(t)); + GB_ASSERT_MSG(is_type_array(st) || is_type_enumerated_array(st) || is_type_matrix(st), "%s", type_to_string(st)); + GB_ASSERT_MSG(is_type_integer(core_type(index.type)), "%s", type_to_string(index.type)); + + + Type *elem = base_array_type(st); + i64 stride = type_size_of(elem); + s.node = tb_inst_array_access(p->func, s.node, index.node, stride); + return s; +} +gb_internal cgValue cg_emit_array_epi(cgProcedure *p, cgValue s, i64 index) { + return cg_emit_array_ep(p, s, cg_const_int(p, t_int, index)); +} + + +gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index) { + s = cg_flatten_value(p, s); + + GB_ASSERT(is_type_pointer(s.type)); + Type *t = base_type(type_deref(s.type)); + Type *result_type = nullptr; + + if (is_type_relative_pointer(t)) { + s = cg_addr_get_ptr(p, cg_addr(s)); + } + + if (is_type_struct(t)) { + result_type = get_struct_field_type(t, index); + } else if (is_type_union(t)) { + GB_ASSERT(index == -1); + GB_PANIC("TODO(bill): cg_emit_union_tag_ptr"); + // return cg_emit_union_tag_ptr(p, s); + } else if (is_type_tuple(t)) { + GB_PANIC("TODO(bill): cg_emit_tuple_ep"); + // return cg_emit_tuple_ep(p, s, index); + // return cg_emit_tuple_ep(p, s, index); + } else if (is_type_complex(t)) { + Type *ft = base_complex_elem_type(t); + switch (index) { + case 0: result_type = ft; break; + case 1: result_type = ft; break; + } + } else if (is_type_quaternion(t)) { + Type *ft = base_complex_elem_type(t); + switch (index) { + case 0: result_type = ft; break; + case 1: result_type = ft; break; + case 2: result_type = ft; break; + case 3: result_type = ft; break; + } + } else if (is_type_slice(t)) { + switch (index) { + case 0: result_type = alloc_type_pointer(t->Slice.elem); break; + case 1: result_type = t_int; break; + } + } else if (is_type_string(t)) { + switch (index) { + case 0: result_type = t_u8_ptr; break; + case 1: result_type = t_int; break; + } + } else if (is_type_any(t)) { + switch (index) { + case 0: result_type = t_rawptr; break; + case 1: result_type = t_typeid; break; + } + } else if (is_type_dynamic_array(t)) { + switch (index) { + case 0: result_type = alloc_type_pointer(t->DynamicArray.elem); break; + case 1: result_type = t_int; break; + case 2: result_type = t_int; break; + case 3: result_type = t_allocator; break; + } + } else if (is_type_map(t)) { + init_map_internal_types(t); + Type *itp = alloc_type_pointer(t_raw_map); + s = cg_emit_transmute(p, s, itp); + + switch (index) { + case 0: result_type = get_struct_field_type(t_raw_map, 0); break; + case 1: result_type = get_struct_field_type(t_raw_map, 1); break; + case 2: result_type = get_struct_field_type(t_raw_map, 2); break; + } + } else if (is_type_array(t)) { + return cg_emit_array_epi(p, s, index); + } else if (is_type_relative_slice(t)) { + switch (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); + } + + GB_ASSERT_MSG(result_type != nullptr, "%s %d", type_to_string(t), index); + + GB_PANIC("TODO(bill): cg_emit_struct_ep_internal"); + // return cg_emit_struct_ep_internal(p, s, index, result_type); + return {}; +} + +gb_internal cgValue cg_emit_deep_field_gep(cgProcedure *p, cgValue e, Selection const &sel) { + GB_ASSERT(sel.index.count > 0); + Type *type = type_deref(e.type); + + for_array(i, sel.index) { + i64 index = sel.index[i]; + if (is_type_pointer(type)) { + type = type_deref(type); + e = cg_emit_load(p, e); + } + type = core_type(type); + + if (type->kind == Type_SoaPointer) { + cgValue addr = cg_emit_struct_ep(p, e, 0); + cgValue index = cg_emit_struct_ep(p, e, 1); + addr = cg_emit_load(p, addr); + index = cg_emit_load(p, index); + + i64 first_index = sel.index[0]; + Selection sub_sel = sel; + sub_sel.index.data += 1; + sub_sel.index.count -= 1; + + cgValue arr = cg_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 = cg_emit_array_ep(p, arr, index); + } else { + e = cg_emit_ptr_offset(p, cg_emit_load(p, arr), index); + } + } else if (is_type_quaternion(type)) { + e = cg_emit_struct_ep(p, e, index); + } else if (is_type_raw_union(type)) { + type = get_struct_field_type(type, index); + GB_ASSERT(is_type_pointer(e.type)); + e = cg_emit_transmute(p, e, alloc_type_pointer(type)); + } else if (is_type_struct(type)) { + type = get_struct_field_type(type, index); + e = cg_emit_struct_ep(p, e, index); + } else if (type->kind == Type_Union) { + GB_ASSERT(index == -1); + type = t_type_info_ptr; + e = cg_emit_struct_ep(p, e, index); + } else if (type->kind == Type_Tuple) { + type = type->Tuple.variables[index]->type; + e = cg_emit_struct_ep(p, e, index); + } else if (type->kind == Type_Basic) { + switch (type->Basic.kind) { + case Basic_any: { + if (index == 0) { + type = t_rawptr; + } else if (index == 1) { + type = t_type_info_ptr; + } + e = cg_emit_struct_ep(p, e, index); + break; + } + + case Basic_string: + e = cg_emit_struct_ep(p, e, index); + break; + + default: + GB_PANIC("un-gep-able type %s", type_to_string(type)); + break; + } + } else if (type->kind == Type_Slice) { + e = cg_emit_struct_ep(p, e, index); + } else if (type->kind == Type_DynamicArray) { + e = cg_emit_struct_ep(p, e, index); + } else if (type->kind == Type_Array) { + e = cg_emit_array_epi(p, e, index); + } else if (type->kind == Type_Map) { + e = cg_emit_struct_ep(p, e, index); + } else if (type->kind == Type_RelativePointer) { + e = cg_emit_struct_ep(p, e, index); + } else { + GB_PANIC("un-gep-able type %s", type_to_string(type)); + } + } + + return e; +} + + + + + @@ -369,6 +582,23 @@ gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero return addr; } +gb_internal cgValue cg_address_from_load_or_generate_local(cgProcedure *p, cgValue value) { + switch (value.kind) { + case cgValue_Value: + if (value.node->type == TB_LOAD) { + TB_Node *ptr = value.node->inputs[1]; + return cg_value(ptr, alloc_type_pointer(value.type)); + } + break; + case cgValue_Addr: + return cg_value(value.node, alloc_type_pointer(value.type)); + } + + cgAddr res = cg_add_local(p, value.type, nullptr, false); + cg_addr_store(p, res, value); + return res.addr; +} + gb_internal void cg_scope_open(cgProcedure *p, Scope *scope) { // TODO(bill): cg_scope_open diff --git a/src/types.cpp b/src/types.cpp index 98be2b6cf..a0881b3d1 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -725,7 +725,7 @@ struct TypePath; gb_internal i64 type_size_of (Type *t); gb_internal i64 type_align_of (Type *t); -gb_internal i64 type_offset_of (Type *t, i32 index); +gb_internal i64 type_offset_of (Type *t, i32 index, Type **field_type_=nullptr); gb_internal gbString type_to_string (Type *type, bool shorthand=true); gb_internal gbString type_to_string (Type *type, gbAllocator allocator, bool shorthand=true); gb_internal i64 type_size_of_internal(Type *t, TypePath *path); @@ -3907,50 +3907,83 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) { return build_context.ptr_size; } -gb_internal i64 type_offset_of(Type *t, i32 index) { +gb_internal i64 type_offset_of(Type *t, i32 index, Type **field_type_) { t = base_type(t); - if (t->kind == Type_Struct) { + switch (t->kind) { + case Type_Struct: type_set_offsets(t); if (gb_is_between(index, 0, t->Struct.fields.count-1)) { GB_ASSERT(t->Struct.offsets != nullptr); + if (field_type_) *field_type_ = t->Struct.fields[index]->type; return t->Struct.offsets[index]; } - } else if (t->kind == Type_Tuple) { + break; + case Type_Tuple: type_set_offsets(t); if (gb_is_between(index, 0, t->Tuple.variables.count-1)) { GB_ASSERT(t->Tuple.offsets != nullptr); + if (field_type_) *field_type_ = t->Tuple.variables[index]->type; return t->Tuple.offsets[index]; } - } else if (t->kind == Type_Basic) { + break; + case Type_Basic: if (t->Basic.kind == Basic_string) { switch (index) { - case 0: return 0; // data - case 1: return build_context.int_size; // len + case 0: + if (field_type_) *field_type_ = t_u8_ptr; + return 0; // data + case 1: + if (field_type_) *field_type_ = t_int; + return build_context.int_size; // len } } else if (t->Basic.kind == Basic_any) { switch (index) { - case 0: return 0; // type_info - case 1: return build_context.ptr_size; // data + case 0: + if (field_type_) *field_type_ = t_rawptr; + return 0; // data + case 1: + if (field_type_) *field_type_ = t_typeid; + return build_context.ptr_size; // id } } - } else if (t->kind == Type_Slice) { + break; + case Type_Slice: switch (index) { - case 0: return 0; // data - case 1: return 1*build_context.int_size; // len - case 2: return 2*build_context.int_size; // cap + case 0: + if (field_type_) *field_type_ = alloc_type_multi_pointer(t->Slice.elem); + return 0; // data + case 1: + if (field_type_) *field_type_ = t_int; + return 1*build_context.int_size; // len } - } else if (t->kind == Type_DynamicArray) { + break; + case Type_DynamicArray: switch (index) { - case 0: return 0; // data - case 1: return 1*build_context.int_size; // len - case 2: return 2*build_context.int_size; // cap - case 3: return 3*build_context.int_size; // allocator + case 0: + if (field_type_) *field_type_ = alloc_type_multi_pointer(t->DynamicArray.elem); + return 0; // data + case 1: + if (field_type_) *field_type_ = t_int; + return 1*build_context.int_size; // len + case 2: + if (field_type_) *field_type_ = t_int; + return 2*build_context.int_size; // cap + case 3: + if (field_type_) *field_type_ = t_allocator; + return 3*build_context.int_size; // allocator } - } else if (t->kind == Type_Union) { - /* i64 s = */ type_size_of(t); - switch (index) { - case -1: return align_formula(t->Union.variant_block_size, build_context.ptr_size); // __type_info + break; + case Type_Union: + if (!is_type_union_maybe_pointer(t)) { + /* i64 s = */ type_size_of(t); + switch (index) { + case -1: + if (field_type_) *field_type_ = union_tag_type(t); + union_tag_size(t); + return t->Union.variant_block_size; + } } + break; } GB_ASSERT(index == 0); return 0; -- cgit v1.2.3 From 921530dd01e940600692caba0b19185399daa2e0 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Jul 2023 12:43:56 +0100 Subject: Fix to allow procedure groups on objective-c types --- src/check_decl.cpp | 124 +++++++++++++------------ src/check_expr.cpp | 170 ++++++++++++++++++++++------------ src/checker.cpp | 48 ++++++++++ src/llvm_backend_expr.cpp | 3 +- src/types.cpp | 2 +- vendor/darwin/Metal/MetalClasses.odin | 4 +- 6 files changed, 229 insertions(+), 122 deletions(-) (limited to 'src/types.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index b651e33e6..2b2fb867c 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -757,6 +757,66 @@ gb_internal String handle_link_name(CheckerContext *ctx, Token token, String lin return link_name; } +gb_internal void check_objc_methods(CheckerContext *ctx, Entity *e, AttributeContext const &ac) { + if (!(ac.objc_name.len || ac.objc_is_class_method || ac.objc_type)) { + return; + } + if (ac.objc_name.len == 0 && ac.objc_is_class_method) { + error(e->token, "@(objc_name) is required with @(objc_is_class_method)"); + } else if (ac.objc_type == nullptr) { + error(e->token, "@(objc_name) requires that @(objc_type) to be set"); + } else if (ac.objc_name.len == 0 && ac.objc_type) { + error(e->token, "@(objc_name) is required with @(objc_type)"); + } else { + Type *t = ac.objc_type; + if (t->kind == Type_Named) { + Entity *tn = t->Named.type_name; + + GB_ASSERT(tn->kind == Entity_TypeName); + + if (tn->scope != e->scope) { + error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope"); + } else { + mutex_lock(&global_type_name_objc_metadata_mutex); + defer (mutex_unlock(&global_type_name_objc_metadata_mutex)); + + if (!tn->TypeName.objc_metadata) { + tn->TypeName.objc_metadata = create_type_name_obj_c_metadata(); + } + auto *md = tn->TypeName.objc_metadata; + mutex_lock(md->mutex); + defer (mutex_unlock(md->mutex)); + + if (!ac.objc_is_class_method) { + bool ok = true; + for (TypeNameObjCMetadataEntry const &entry : md->value_entries) { + if (entry.name == ac.objc_name) { + error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name)); + ok = false; + break; + } + } + if (ok) { + array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e}); + } + } else { + bool ok = true; + for (TypeNameObjCMetadataEntry const &entry : md->type_entries) { + if (entry.name == ac.objc_name) { + error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name)); + ok = false; + break; + } + } + if (ok) { + array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e}); + } + } + } + } + } +} + gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { GB_ASSERT(e->type == nullptr); if (d->proc_lit->kind != Ast_ProcLit) { @@ -840,62 +900,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) { } e->Procedure.optimization_mode = cast(ProcedureOptimizationMode)ac.optimization_mode; - if (ac.objc_name.len || ac.objc_is_class_method || ac.objc_type) { - if (ac.objc_name.len == 0 && ac.objc_is_class_method) { - error(e->token, "@(objc_name) is required with @(objc_is_class_method)"); - } else if (ac.objc_type == nullptr) { - error(e->token, "@(objc_name) requires that @(objc_type) to be set"); - } else if (ac.objc_name.len == 0 && ac.objc_type) { - error(e->token, "@(objc_name) is required with @(objc_type)"); - } else { - Type *t = ac.objc_type; - if (t->kind == Type_Named) { - Entity *tn = t->Named.type_name; - - GB_ASSERT(tn->kind == Entity_TypeName); - - if (tn->scope != e->scope) { - error(e->token, "@(objc_name) attribute may only be applied to procedures and types within the same scope"); - } else { - mutex_lock(&global_type_name_objc_metadata_mutex); - defer (mutex_unlock(&global_type_name_objc_metadata_mutex)); - - if (!tn->TypeName.objc_metadata) { - tn->TypeName.objc_metadata = create_type_name_obj_c_metadata(); - } - auto *md = tn->TypeName.objc_metadata; - mutex_lock(md->mutex); - defer (mutex_unlock(md->mutex)); - - if (!ac.objc_is_class_method) { - bool ok = true; - for (TypeNameObjCMetadataEntry const &entry : md->value_entries) { - if (entry.name == ac.objc_name) { - error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name)); - ok = false; - break; - } - } - if (ok) { - array_add(&md->value_entries, TypeNameObjCMetadataEntry{ac.objc_name, e}); - } - } else { - bool ok = true; - for (TypeNameObjCMetadataEntry const &entry : md->type_entries) { - if (entry.name == ac.objc_name) { - error(e->token, "Previous declaration of @(objc_name=\"%.*s\")", LIT(ac.objc_name)); - ok = false; - break; - } - } - if (ok) { - array_add(&md->type_entries, TypeNameObjCMetadataEntry{ac.objc_name, e}); - } - } - } - } - } - } + check_objc_methods(ctx, e, ac); if (ac.require_target_feature.len != 0 && ac.enable_target_feature.len != 0) { error(e->token, "Attributes @(require_target_feature=...) and @(enable_target_feature=...) cannot be used together"); @@ -1241,7 +1246,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed"); } -gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, DeclInfo *d) { +gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, DeclInfo *d) { GB_ASSERT(pg_entity->kind == Entity_ProcGroup); auto *pge = &pg_entity->ProcGroup; String proc_group_name = pg_entity->token.string; @@ -1366,6 +1371,11 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *&pg_entity, } } + AttributeContext ac = {}; + check_decl_attributes(ctx, d->attributes, proc_group_attribute, &ac); + check_objc_methods(ctx, pg_entity, ac); + + } gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, Type *named_type) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index b662c231f..bb953ee2e 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -6328,9 +6328,46 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, print_argument_types(); } + if (procs.count == 0) { + procs = proc_group_entities_cloned(c, *operand); + } if (procs.count > 0) { error_line("Did you mean to use one of the following:\n"); } + isize max_name_length = 0; + isize max_type_length = 0; + for (Entity *proc : procs) { + Type *t = base_type(proc->type); + if (t == t_invalid) continue; + String prefix = {}; + String prefix_sep = {}; + if (proc->pkg) { + prefix = proc->pkg->name; + prefix_sep = str_lit("."); + } + String name = proc->token.string; + max_name_length = gb_max(max_name_length, prefix.len + prefix_sep.len + name.len); + + + + gbString pt; + if (t->Proc.node != nullptr) { + pt = expr_to_string(t->Proc.node); + } else { + pt = type_to_string(t); + } + + max_type_length = gb_max(max_type_length, gb_string_length(pt)); + gb_string_free(pt); + } + + isize max_spaces = gb_max(max_name_length, max_type_length); + char *spaces = gb_alloc_array(temporary_allocator(), char, max_spaces+1); + for (isize i = 0; i < max_spaces; i++) { + spaces[i] = ' '; + } + spaces[max_spaces] = 0; + for (Entity *proc : procs) { TokenPos pos = proc->token.pos; Type *t = base_type(proc->type); @@ -6350,12 +6387,23 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, prefix_sep = str_lit("."); } String name = proc->token.string; + isize len = prefix.len + prefix_sep.len + name.len; + + int name_padding = cast(int)gb_max(max_name_length - len, 0); + int type_padding = cast(int)gb_max(max_type_length - gb_string_length(pt), 0); char const *sep = "::"; if (proc->kind == Entity_Variable) { sep = ":="; } - error_line("\t%.*s%.*s%.*s %s %s at %s\n", LIT(prefix), LIT(prefix_sep), LIT(name), sep, pt, token_pos_to_string(pos)); + error_line("\t%.*s%.*s%.*s %.*s%s %s %.*sat %s\n", + LIT(prefix), LIT(prefix_sep), LIT(name), + name_padding, spaces, + sep, + pt, + type_padding, spaces, + token_pos_to_string(pos) + ); } if (procs.count > 0) { error_line("\n"); @@ -9315,13 +9363,13 @@ gb_internal ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast ExprKind kind = check_expr_base(c, &x, se->expr, nullptr); c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; - if (x.mode == Addressing_Invalid || x.type == t_invalid) { + if (x.mode == Addressing_Invalid || (x.type == t_invalid && x.mode != Addressing_ProcGroup)) { o->mode = Addressing_Invalid; o->type = t_invalid; o->expr = node; return kind; } - if (!is_type_proc(x.type)) { + if (!is_type_proc(x.type) && x.mode != Addressing_ProcGroup) { gbString type_str = type_to_string(x.type); error(se->call, "Selector call expressions expect a procedure type for the call, got '%s'", type_str); gb_string_free(type_str); @@ -9344,76 +9392,76 @@ gb_internal ExprKind check_selector_call_expr(CheckerContext *c, Operand *o, Ast first_arg->state_flags |= StateFlag_SelectorCallExpr; } - Type *pt = base_type(x.type); - GB_ASSERT(pt->kind == Type_Proc); - Type *first_type = nullptr; - String first_arg_name = {}; - if (pt->Proc.param_count > 0) { - Entity *f = pt->Proc.params->Tuple.variables[0]; - first_type = f->type; - first_arg_name = f->token.string; - } - if (first_arg_name.len == 0) { - first_arg_name = str_lit("_"); - } + if (e->kind != Entity_ProcGroup) { + Type *pt = base_type(x.type); + GB_ASSERT_MSG(pt->kind == Type_Proc, "%.*s %.*s %s", LIT(e->token.string), LIT(entity_strings[e->kind]), type_to_string(x.type)); + Type *first_type = nullptr; + String first_arg_name = {}; + if (pt->Proc.param_count > 0) { + Entity *f = pt->Proc.params->Tuple.variables[0]; + first_type = f->type; + first_arg_name = f->token.string; + } + if (first_arg_name.len == 0) { + first_arg_name = str_lit("_"); + } - if (first_type == nullptr) { - error(se->call, "Selector call expressions expect a procedure type for the call with at least 1 parameter"); - o->mode = Addressing_Invalid; - o->type = t_invalid; - o->expr = node; - return Expr_Stmt; - } + if (first_type == nullptr) { + error(se->call, "Selector call expressions expect a procedure type for the call with at least 1 parameter"); + o->mode = Addressing_Invalid; + o->type = t_invalid; + o->expr = node; + return Expr_Stmt; + } - Operand y = {}; - y.mode = first_arg->tav.mode; - y.type = first_arg->tav.type; - y.value = first_arg->tav.value; + Operand y = {}; + y.mode = first_arg->tav.mode; + y.type = first_arg->tav.type; + y.value = first_arg->tav.value; - if (check_is_assignable_to(c, &y, first_type)) { - // Do nothing, it's valid - } else { - Operand z = y; - z.type = type_deref(y.type); - if (check_is_assignable_to(c, &z, first_type)) { - // NOTE(bill): AST GENERATION HACK! - Token op = {Token_Pointer}; - first_arg = ast_deref_expr(first_arg->file(), first_arg, op); - } else if (y.mode == Addressing_Variable) { - Operand w = y; - w.type = alloc_type_pointer(y.type); - if (check_is_assignable_to(c, &w, first_type)) { + if (check_is_assignable_to(c, &y, first_type)) { + // Do nothing, it's valid + } else { + Operand z = y; + z.type = type_deref(y.type); + if (check_is_assignable_to(c, &z, first_type)) { // NOTE(bill): AST GENERATION HACK! - Token op = {Token_And}; - first_arg = ast_unary_expr(first_arg->file(), op, first_arg); + Token op = {Token_Pointer}; + first_arg = ast_deref_expr(first_arg->file(), first_arg, op); + } else if (y.mode == Addressing_Variable) { + Operand w = y; + w.type = alloc_type_pointer(y.type); + if (check_is_assignable_to(c, &w, first_type)) { + // NOTE(bill): AST GENERATION HACK! + Token op = {Token_And}; + first_arg = ast_unary_expr(first_arg->file(), op, first_arg); + } } } - } - if (ce->args.count > 0) { - bool fail = false; - bool first_is_field_value = (ce->args[0]->kind == Ast_FieldValue); - for (Ast *arg : ce->args) { - bool mix = false; - if (first_is_field_value) { - mix = arg->kind != Ast_FieldValue; - } else { - mix = arg->kind == Ast_FieldValue; + if (ce->args.count > 0) { + bool fail = false; + bool first_is_field_value = (ce->args[0]->kind == Ast_FieldValue); + for (Ast *arg : ce->args) { + bool mix = false; + if (first_is_field_value) { + mix = arg->kind != Ast_FieldValue; + } else { + mix = arg->kind == Ast_FieldValue; + } + if (mix) { + fail = true; + break; + } } - if (mix) { - fail = true; - break; + if (!fail && first_is_field_value) { + Token op = {Token_Eq}; + AstFile *f = first_arg->file(); + first_arg = ast_field_value(f, ast_ident(f, make_token_ident(first_arg_name)), first_arg, op); } } - if (!fail && first_is_field_value) { - Token op = {Token_Eq}; - AstFile *f = first_arg->file(); - first_arg = ast_field_value(f, ast_ident(f, make_token_ident(first_arg_name)), first_arg, op); - } } - - auto modified_args = slice_make(heap_allocator(), ce->args.count+1); modified_args[0] = first_arg; slice_copy(&modified_args, ce->args, 1); diff --git a/src/checker.cpp b/src/checker.cpp index 396a04d7a..2a2cb5c42 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2935,6 +2935,54 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) { return false; } +gb_internal DECL_ATTRIBUTE_PROC(proc_group_attribute) { + if (name == ATTRIBUTE_USER_TAG_NAME) { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind != ExactValue_String) { + error(elem, "Expected a string value for '%.*s'", LIT(name)); + } + return true; + } else if (name == "objc_name") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind == ExactValue_String) { + if (string_is_valid_identifier(ev.value_string)) { + ac->objc_name = ev.value_string; + } else { + error(elem, "Invalid identifier for '%.*s', got '%.*s'", LIT(name), LIT(ev.value_string)); + } + } else { + error(elem, "Expected a string value for '%.*s'", LIT(name)); + } + return true; + } else if (name == "objc_is_class_method") { + ExactValue ev = check_decl_attribute_value(c, value); + if (ev.kind == ExactValue_Bool) { + ac->objc_is_class_method = ev.value_bool; + } else { + error(elem, "Expected a boolean value for '%.*s'", LIT(name)); + } + return true; + } else if (name == "objc_type") { + if (value == nullptr) { + error(elem, "Expected a type for '%.*s'", LIT(name)); + } else { + Type *objc_type = check_type(c, value); + if (objc_type != nullptr) { + if (!has_type_got_objc_class_attribute(objc_type)) { + gbString t = type_to_string(objc_type); + error(value, "'%.*s' expected a named type with the attribute @(obj_class=), got type %s", LIT(name), t); + gb_string_free(t); + } else { + ac->objc_type = objc_type; + } + } + } + return true; + } + return false; +} + + gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) { if (name == ATTRIBUTE_USER_TAG_NAME) { ExactValue ev = check_decl_attribute_value(c, value); diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index c9d30af7a..5e6831fc2 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -4519,8 +4519,9 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { Selection sel = lookup_field(type, selector, false); GB_ASSERT(sel.entity != nullptr); if (sel.pseudo_field) { - GB_ASSERT(sel.entity->kind == Entity_Procedure); + GB_ASSERT(sel.entity->kind == Entity_Procedure || sel.entity->kind == Entity_ProcGroup); Entity *e = entity_of_node(sel_node); + GB_ASSERT(e->kind == Entity_Procedure); return lb_addr(lb_find_value_from_entity(p->module, e)); } diff --git a/src/types.cpp b/src/types.cpp index 385ca926d..847aea9f3 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -3081,7 +3081,7 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name mutex_lock(md->mutex); defer (mutex_unlock(md->mutex)); for (TypeNameObjCMetadataEntry const &entry : md->value_entries) { - GB_ASSERT(entry.entity->kind == Entity_Procedure); + GB_ASSERT(entry.entity->kind == Entity_Procedure || entry.entity->kind == Entity_ProcGroup); if (entry.name == field_name) { sel.entity = entry.entity; sel.pseudo_field = true; diff --git a/vendor/darwin/Metal/MetalClasses.odin b/vendor/darwin/Metal/MetalClasses.odin index 17f22e1d3..9239182db 100644 --- a/vendor/darwin/Metal/MetalClasses.odin +++ b/vendor/darwin/Metal/MetalClasses.odin @@ -5388,8 +5388,8 @@ Device_newBufferWithLength :: #force_inline proc "c" (self: ^Device, length: NS. @(objc_type=Device, objc_name="newBuffer") Device_newBuffer :: proc{ - Device_newBufferWithBytes, - Device_newBufferWithBytesNoCopy, + // Device_newBufferWithBytes, + // Device_newBufferWithBytesNoCopy, Device_newBufferWithSlice, Device_newBufferWithSliceNoCopy, Device_newBufferWithLength, -- cgit v1.2.3 From c61e7c05daffc3ba8854170d5f293ddf1e758d4e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 20 Jul 2023 00:34:24 +0100 Subject: Begin working on global constants --- src/tilde_const.cpp | 297 ++++++++++++++++++++++++++++++++++++++-------------- src/types.cpp | 13 ++- 2 files changed, 227 insertions(+), 83 deletions(-) (limited to 'src/types.cpp') diff --git a/src/tilde_const.cpp b/src/tilde_const.cpp index ef3f38f09..d89e43c2f 100644 --- a/src/tilde_const.cpp +++ b/src/tilde_const.cpp @@ -139,9 +139,192 @@ gb_internal TB_Global *cg_global_const_string(cgModule *m, String const &str, Ty return global; } -gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, Ast *value_compound, bool allow_local); +gb_internal bool cg_elem_type_can_be_constant(Type *t) { + t = base_type(t); + if (t == t_invalid) { + return false; + } + if (is_type_dynamic_array(t) || is_type_map(t)) { + return false; + } + return true; +} + + +gb_internal bool cg_is_elem_const(Ast *elem, Type *elem_type) { + if (!cg_elem_type_can_be_constant(elem_type)) { + return false; + } + if (elem->kind == Ast_FieldValue) { + elem = elem->FieldValue.value; + } + TypeAndValue tav = type_and_value_of_expr(elem); + GB_ASSERT_MSG(tav.mode != Addressing_Invalid, "%s %s", expr_to_string(elem), type_to_string(tav.type)); + return tav.value.kind != ExactValue_Invalid; +} + +gb_internal bool cg_is_nested_possibly_constant(Type *ft, Selection const &sel, Ast *elem) { + GB_ASSERT(!sel.indirect); + for (i32 index : sel.index) { + Type *bt = base_type(ft); + switch (bt->kind) { + case Type_Struct: + // if (bt->Struct.is_raw_union) { + // return false; + // } + ft = bt->Struct.fields[index]->type; + break; + case Type_Array: + ft = bt->Array.elem; + break; + default: + return false; + } + } + return cg_is_elem_const(elem, ft); +} -gb_internal bool cg_global_const_add_region(cgModule *m, TB_Global *global, ExactValue const &value, Type *type, i64 offset, bool allow_local) { +gb_internal i64 cg_global_const_calculate_region_count_from_basic_type(Type *type) { + type = core_type(type); + + switch (type->kind) { + case Type_Basic: + switch (type->Basic.kind) { + case Basic_string: // ^u8 + int + case Basic_any: // rawptr + typeid + return 2; + } + return 1; + case Type_Pointer: + case Type_MultiPointer: + case Type_Proc: + return true; + case Type_Slice: + return 2; + case Type_DynamicArray: + return 5; + case Type_Map: + return 4; + + case Type_Enum: + case Type_BitSet: + return 1; + + case Type_RelativePointer: + return 1; + case Type_RelativeSlice: + return 1; // technically 1 + case Type_Matrix: + return 1; + + default: + GB_PANIC("TODO(bill): %s", type_to_string(type)); + break; + } + return -1; +} +gb_internal isize cg_global_const_calculate_region_count(ExactValue const &value, Type *type) { + isize count = 0; + switch (value.kind) { + case ExactValue_Invalid: + break; + case ExactValue_Bool: + case ExactValue_Integer: + case ExactValue_Float: + case ExactValue_Pointer: + case ExactValue_Typeid: + case ExactValue_Complex: + case ExactValue_Quaternion: + count += 1; + break; + + case ExactValue_Procedure: + count += 1; + break; + + case ExactValue_String: + if (is_type_cstring(type) || is_type_array_like(type)) { + count += 1; + } else { + count += 2; + } + break; + + case ExactValue_Compound: { + ast_node(cl, CompoundLit, value.value_compound); + Type *bt = base_type(type); + if (bt->kind == Type_Struct) { + if (cl->elems[0]->kind == Ast_FieldValue) { + isize elem_count = cl->elems.count; + for (isize i = 0; i < elem_count; i++) { + ast_node(fv, FieldValue, cl->elems[i]); + String name = fv->field->Ident.token.string; + + Selection sel = lookup_field(type, name, false); + GB_ASSERT(!sel.indirect); + + Entity *f = bt->Struct.fields[sel.index[0]]; + + if (!cg_elem_type_can_be_constant(f->type)) { + continue; + } + + if (sel.index.count == 1) { + count += cg_global_const_calculate_region_count(fv->value->tav.value, f->type); + } else { + TEMPORARY_ALLOCATOR_GUARD(); + isize idx_list_len = sel.index.count-1; + isize *idx_list = gb_alloc_array(temporary_allocator(), isize, idx_list_len); + + count += 1; // just in case + if (cg_is_nested_possibly_constant(type, sel, fv->value)) { + Type *cv_type = f->type; + for (isize j = 1; j < sel.index.count; j++) { + i32 index = sel.index[j]; + Type *cvt = base_type(cv_type); + + idx_list[j-1] = index; + if (cvt->kind == Type_Struct) { + cv_type = cvt->Struct.fields[index]->type; + } else if (cvt->kind == Type_Array) { + cv_type = cvt->Array.elem; + } else { + GB_PANIC("UNKNOWN TYPE: %s", type_to_string(cv_type)); + } + } + + count += cg_global_const_calculate_region_count(fv->value->tav.value, cv_type); + } + } + } + } else { + for_array(i, cl->elems) { + i64 field_index = i; + Ast *elem = cl->elems[i]; + TypeAndValue tav = elem->tav; + Entity *f = bt->Struct.fields[field_index]; + if (!cg_elem_type_can_be_constant(f->type)) { + continue; + } + + ExactValue value = {}; + if (tav.mode != Addressing_Invalid) { + value = tav.value; + } + count += cg_global_const_calculate_region_count(value, type); + } + } + } else { + GB_PANIC("TODO(bill): %s", type_to_string(type)); + } + }break; + } + return count; +} + +gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, ExactValue const &value, TB_Global *global, i64 base_offset); + +gb_internal bool cg_global_const_add_region(cgModule *m, TB_Global *global, ExactValue const &value, Type *type, i64 offset) { GB_ASSERT(is_type_endian_little(type)); GB_ASSERT(!is_type_different_to_arch_endianness(type)); @@ -198,8 +381,8 @@ gb_internal bool cg_global_const_add_region(cgModule *m, TB_Global *global, Exac case ExactValue_Compound: { - TB_Global *nested_global = cg_global_const_comp_literal(m, type, value.value_compound, allow_local); - tb_global_add_symbol_reloc(m->mod, global, offset, cast(TB_Symbol *)nested_global); + TB_Global *out_global = cg_global_const_comp_literal(m, type, value, global, offset); + GB_ASSERT(out_global == global); } break; @@ -269,32 +452,36 @@ gb_internal bool cg_global_const_add_region(cgModule *m, TB_Global *global, Exac } -gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, Ast *value_compound, bool allow_local) { - Type *original_type = type; - if (is_type_struct(type)) { - ast_node(cl, CompoundLit, value_compound); +gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *original_type, ExactValue const &value, TB_Global *global, i64 base_offset) { + GB_ASSERT(value.kind == ExactValue_Compound); + Ast *value_compound = value.value_compound; + ast_node(cl, CompoundLit, value_compound); - Type *bt = base_type(type); + TEMPORARY_ALLOCATOR_GUARD(); + if (global == nullptr) { char name[32] = {}; gb_snprintf(name, 31, "complit$%u", 1+m->const_nil_guid.fetch_add(1)); - TB_Global *global = tb_global_create(m->mod, -1, name, cg_debug_type(m, original_type), TB_LINKAGE_PRIVATE); + global = tb_global_create(m->mod, -1, name, cg_debug_type(m, original_type), TB_LINKAGE_PRIVATE); i64 size = type_size_of(original_type); i64 align = type_align_of(original_type); // READ ONLY? TB_ModuleSection *section = tb_module_get_rdata(m->mod); - if (cl->elems.count == 0/* || bt->Struct.is_raw_union*/) { + if (cl->elems.count == 0) { tb_global_set_storage(m->mod, section, global, size, align, 0); return global; } - TEMPORARY_ALLOCATOR_GUARD(); - isize value_count = bt->Struct.fields.count; - // cgValue * values = gb_alloc_array(temporary_allocator(), cgValue, value_count); - bool * visited = gb_alloc_array(temporary_allocator(), bool, value_count); - tb_global_set_storage(m->mod, section, global, size, align, value_count); + isize global_region_count = cg_global_const_calculate_region_count(value, original_type); + tb_global_set_storage(m->mod, section, global, size, align, global_region_count); + gb_printf_err("global_region_count %td\n", global_region_count); + } + + + Type *bt = base_type(original_type); + if (bt->kind == Type_Struct) { if (cl->elems[0]->kind == Ast_FieldValue) { isize elem_count = cl->elems.count; for (isize i = 0; i < elem_count; i++) { @@ -303,65 +490,18 @@ gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, Ast TypeAndValue tav = fv->value->tav; GB_ASSERT(tav.mode != Addressing_Invalid); + ExactValue value = tav.value; - Selection sel = lookup_field(type, name, false); + Selection sel = lookup_field(bt, name, false); GB_ASSERT(!sel.indirect); - Entity *f = bt->Struct.fields[sel.index[0]]; - i64 index = f->Variable.field_index; - if (elem_type_can_be_constant(f->type)) { - if (sel.index.count == 1) { - i64 offset = bt->Struct.offsets[index]; - if (cg_global_const_add_region(m, global, fv->value->tav.value, f->type, offset, allow_local)) { - visited[i] = true; - continue; - } - } else { - // if (!visited[index]) { - GB_PANIC("using struct fields"); - // values[index] = lb_const_value(m, f->type, {}, false).value; - // visited[index] = true; - // } - // unsigned idx_list_len = cast(unsigned)sel.index.count-1; - // unsigned *idx_list = gb_alloc_array(temporary_allocator(), unsigned, idx_list_len); - - // if (lb_is_nested_possibly_constant(type, sel, fv->value)) { - // bool is_constant = true; - // Type *cv_type = f->type; - // for (isize j = 1; j < sel.index.count; j++) { - // i32 index = sel.index[j]; - // Type *cvt = base_type(cv_type); - - // if (cvt->kind == Type_Struct) { - // if (cvt->Struct.is_raw_union) { - // // sanity check which should have been caught by `lb_is_nested_possibly_constant` - // is_constant = false; - // break; - // } - // cv_type = cvt->Struct.fields[index]->type; - - // if (is_type_struct(cvt)) { - // auto cv_field_remapping = lb_get_struct_remapping(m, cvt); - // unsigned remapped_index = cast(unsigned)cv_field_remapping[index]; - // idx_list[j-1] = remapped_index; - // } else { - // idx_list[j-1] = cast(unsigned)index; - // } - // } else if (cvt->kind == Type_Array) { - // cv_type = cvt->Array.elem; - - // idx_list[j-1] = cast(unsigned)index; - // } else { - // GB_PANIC("UNKNOWN TYPE: %s", type_to_string(cv_type)); - // } - // } - // if (is_constant) { - // LLVMValueRef elem_value = lb_const_value(m, tav.type, tav.value, allow_local).value; - // GB_ASSERT(LLVMIsConstant(elem_value)); - // values[index] = LLVMConstInsertValue(values[index], elem_value, idx_list, idx_list_len); - // } - // } - } + if (!cg_is_nested_possibly_constant(bt, sel, fv->value)) { + continue; + } + + i64 offset = type_offset_of_from_selection(bt, sel); + if (cg_global_const_add_region(m, global, value, sel.entity->type, base_offset+offset)) { + continue; } } } else { @@ -370,7 +510,7 @@ gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, Ast Ast *elem = cl->elems[i]; TypeAndValue tav = elem->tav; Entity *f = bt->Struct.fields[field_index]; - if (!elem_type_can_be_constant(f->type)) { + if (!cg_elem_type_can_be_constant(f->type)) { continue; } @@ -380,8 +520,7 @@ gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, Ast if (tav.mode != Addressing_Invalid) { value = tav.value; } - if (cg_global_const_add_region(m, global, value, f->type, offset, allow_local)) { - visited[i] = true; + if (cg_global_const_add_region(m, global, value, f->type, base_offset+offset)) { continue; } } @@ -390,16 +529,14 @@ gb_internal TB_Global *cg_global_const_comp_literal(cgModule *m, Type *type, Ast return global; } - GB_PANIC("TODO(bill): constant compound literal for %s", type_to_string(type)); + GB_PANIC("TODO(bill): constant compound literal for %s", type_to_string(original_type)); return nullptr; } -gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, ExactValue const &value, bool allow_local_ = true) { +gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, ExactValue const &value) { TB_Node *node = nullptr; - bool allow_local = allow_local_ && p != nullptr; - TB_DataType dt = cg_data_type(type); switch (value.kind) { @@ -470,7 +607,7 @@ gb_internal cgValue cg_const_value(cgModule *m, cgProcedure *p, Type *type, Exac case ExactValue_Compound: { - TB_Symbol *symbol = cast(TB_Symbol *)cg_global_const_comp_literal(m, type, value.value_compound, allow_local); + TB_Symbol *symbol = cast(TB_Symbol *)cg_global_const_comp_literal(m, type, value, nullptr, 0); if (p) { TB_Node *node = tb_inst_get_symbol_address(p->func, symbol); return cg_lvalue_addr(node, type); diff --git a/src/types.cpp b/src/types.cpp index ff8c42d83..f513f23d9 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -725,7 +725,7 @@ struct TypePath; gb_internal i64 type_size_of (Type *t); gb_internal i64 type_align_of (Type *t); -gb_internal i64 type_offset_of (Type *t, i32 index, Type **field_type_=nullptr); +gb_internal i64 type_offset_of (Type *t, i64 index, Type **field_type_=nullptr); gb_internal gbString type_to_string (Type *type, bool shorthand=true); gb_internal gbString type_to_string (Type *type, gbAllocator allocator, bool shorthand=true); gb_internal i64 type_size_of_internal(Type *t, TypePath *path); @@ -3907,7 +3907,7 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) { return build_context.ptr_size; } -gb_internal i64 type_offset_of(Type *t, i32 index, Type **field_type_) { +gb_internal i64 type_offset_of(Type *t, i64 index, Type **field_type_) { t = base_type(t); switch (t->kind) { case Type_Struct: @@ -3926,6 +3926,11 @@ gb_internal i64 type_offset_of(Type *t, i32 index, Type **field_type_) { return t->Tuple.offsets[index]; } break; + + case Type_Array: + GB_ASSERT(0 <= index && index < t->Array.count); + return index * type_size_of(t->Array.elem); + case Type_Basic: if (t->Basic.kind == Basic_string) { switch (index) { @@ -3999,8 +4004,10 @@ gb_internal i64 type_offset_of_from_selection(Type *type, Selection sel) { i32 index = sel.index[i]; t = base_type(t); offset += type_offset_of(t, index); - if (t->kind == Type_Struct && !t->Struct.is_raw_union) { + if (t->kind == Type_Struct) { t = t->Struct.fields[index]->type; + } else if (t->kind == Type_Array) { + t = t->Array.elem; } else { // NOTE(bill): No need to worry about custom types, just need the alignment switch (t->kind) { -- cgit v1.2.3 From eec3b3009f0005090ddd5a7901e5f3c38cf31ce1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 22 Jul 2023 10:16:28 +0100 Subject: Begin work on builtin procedures --- src/checker.cpp | 1 + src/tilde.cpp | 1 + src/tilde.hpp | 7 +- src/tilde_builtin.cpp | 147 +++++++++++++++ src/tilde_expr.cpp | 486 +++++++++++++++++++++++++++++++++++++++++++++++++- src/tilde_proc.cpp | 3 +- src/types.cpp | 1 + 7 files changed, 637 insertions(+), 9 deletions(-) create mode 100644 src/tilde_builtin.cpp (limited to 'src/types.cpp') diff --git a/src/checker.cpp b/src/checker.cpp index 2a2cb5c42..01b8b6b2a 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1114,6 +1114,7 @@ gb_internal void init_universal(void) { t_u8_ptr = alloc_type_pointer(t_u8); + t_u8_multi_ptr = alloc_type_multi_pointer(t_u8); t_int_ptr = alloc_type_pointer(t_int); t_i64_ptr = alloc_type_pointer(t_i64); t_f64_ptr = alloc_type_pointer(t_f64); diff --git a/src/tilde.cpp b/src/tilde.cpp index 78aa3640d..1969deaec 100644 --- a/src/tilde.cpp +++ b/src/tilde.cpp @@ -669,6 +669,7 @@ gb_internal String cg_get_entity_name(cgModule *m, Entity *e) { #include "tilde_const.cpp" #include "tilde_debug.cpp" #include "tilde_expr.cpp" +#include "tilde_builtin.cpp" #include "tilde_proc.cpp" #include "tilde_stmt.cpp" diff --git a/src/tilde.hpp b/src/tilde.hpp index 45eceeb7b..f0e45bb97 100644 --- a/src/tilde.hpp +++ b/src/tilde.hpp @@ -272,6 +272,7 @@ gb_internal void cg_build_when_stmt(cgProcedure *p, AstWhenStmt *ws); gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr); gb_internal cgAddr cg_build_addr(cgProcedure *p, Ast *expr); +gb_internal cgValue cg_build_addr_ptr(cgProcedure *p, Ast *expr); gb_internal Type * cg_addr_type(cgAddr const &addr); gb_internal cgValue cg_addr_load(cgProcedure *p, cgAddr addr); @@ -311,4 +312,8 @@ gb_internal bool cg_emit_goto(cgProcedure *p, TB_Node *control_region); gb_internal TB_Node *cg_control_region(cgProcedure *p, char const *name); -gb_internal isize cg_append_tuple_values(cgProcedure *p, Array *dst_values, cgValue src_value); \ No newline at end of file +gb_internal isize cg_append_tuple_values(cgProcedure *p, Array *dst_values, cgValue src_value); + + +gb_internal cgValue cg_builtin_len(cgProcedure *p, cgValue value); +gb_internal cgValue cg_builtin_raw_data(cgProcedure *p, cgValue const &x); \ No newline at end of file diff --git a/src/tilde_builtin.cpp b/src/tilde_builtin.cpp new file mode 100644 index 000000000..08c3f7bdd --- /dev/null +++ b/src/tilde_builtin.cpp @@ -0,0 +1,147 @@ +gb_internal cgValue cg_builtin_len(cgProcedure *p, cgValue value) { + Type *t = base_type(value.type); + + switch (t->kind) { + case Type_Basic: + switch (t->Basic.kind) { + case Basic_string: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue len_ptr = cg_emit_struct_ep(p, ptr, 1); + return cg_emit_load(p, len_ptr); + } + case Basic_cstring: + break; + } + break; + case Type_Array: + return cg_const_int(p, t_int, t->Array.count); + case Type_EnumeratedArray: + return cg_const_int(p, t_int, t->EnumeratedArray.count); + case Type_Slice: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue len_ptr = cg_emit_struct_ep(p, ptr, 1); + return cg_emit_load(p, len_ptr); + } + case Type_DynamicArray: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue len_ptr = cg_emit_struct_ep(p, ptr, 1); + return cg_emit_load(p, len_ptr); + } + case Type_Map: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue len_ptr = cg_emit_struct_ep(p, ptr, 1); + return cg_emit_conv(p, cg_emit_load(p, len_ptr), t_int); + } + case Type_Struct: + GB_ASSERT(is_type_soa_struct(t)); + break; + case Type_RelativeSlice: + break; + } + + GB_PANIC("TODO(bill): cg_builtin_len %s", type_to_string(t)); + return {}; +} + +gb_internal cgValue cg_builtin_raw_data(cgProcedure *p, cgValue const &value) { + Type *t = base_type(value.type); + cgValue res = {}; + switch (t->kind) { + case Type_Slice: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue data_ptr = cg_emit_struct_ep(p, ptr, 0); + res = cg_emit_load(p, data_ptr); + } + break; + case Type_DynamicArray: + { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue data_ptr = cg_emit_struct_ep(p, ptr, 0); + res = cg_emit_load(p, data_ptr); + } + break; + case Type_Basic: + if (t->Basic.kind == Basic_string) { + GB_ASSERT(value.kind == cgValue_Addr); + cgValue ptr = cg_value(value.node, alloc_type_pointer(value.type)); + cgValue data_ptr = cg_emit_struct_ep(p, ptr, 0); + res = cg_emit_load(p, data_ptr); + } else if (t->Basic.kind == Basic_cstring) { + res = cg_emit_conv(p, value, t_u8_multi_ptr); + } + break; + case Type_Pointer: + case Type_MultiPointer: + GB_PANIC("TODO(bill) %s", type_to_string(value.type)); + // res = cg_emit_conv(p, value, tv.type); + break; + } + GB_ASSERT(res.node != nullptr); + return res; +} + +gb_internal cgValue cg_build_builtin(cgProcedure *p, BuiltinProcId id, Ast *expr) { + ast_node(ce, CallExpr, expr); + + if (BuiltinProc__simd_begin < id && id < BuiltinProc__simd_end) { + GB_PANIC("TODO(bill): cg_build_builtin_simd_proc"); + // return cg_build_builtin_simd_proc(p, expr, tv, id); + } + + String builtin_name = builtin_procs[id].name; + + switch (id) { + case BuiltinProc_DIRECTIVE: { + ast_node(bd, BasicDirective, ce->proc); + String name = bd->name.string; + GB_ASSERT(name == "location"); + String procedure = p->entity->token.string; + TokenPos pos = ast_token(ce->proc).pos; + if (ce->args.count > 0) { + Ast *ident = unselector_expr(ce->args[0]); + GB_ASSERT(ident->kind == Ast_Ident); + Entity *e = entity_of_node(ident); + GB_ASSERT(e != nullptr); + + if (e->parent_proc_decl != nullptr && e->parent_proc_decl->entity != nullptr) { + procedure = e->parent_proc_decl->entity->token.string; + } else { + procedure = str_lit(""); + } + pos = e->token.pos; + + } + GB_PANIC("TODO(bill): cg_emit_source_code_location_as_global"); + // return cg_emit_source_code_location_as_global(p, procedure, pos); + } break; + + case BuiltinProc_len: { + cgValue v = cg_build_expr(p, ce->args[0]); + Type *t = base_type(v.type); + if (is_type_pointer(t)) { + // IMPORTANT TODO(bill): Should there be a nil pointer check? + v = cg_emit_load(p, v); + t = type_deref(t); + } + return cg_builtin_len(p, v); + } + + + } + + + GB_PANIC("TODO(bill): builtin procs %d %.*s", id, LIT(builtin_name)); + return {}; +} + diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 2d4b11336..c0ddc4e70 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -179,7 +179,7 @@ gb_internal cgValue cg_emit_transmute(cgProcedure *p, cgValue value, Type *type) TB_DataType dt = cg_data_type(type); switch (value.kind) { case cgValue_Value: - GB_ASSERT(!TB_IS_VOID_TYPE(dt)); + GB_ASSERT_MSG(!TB_IS_VOID_TYPE(dt), "%s", type_to_string(type)); value.type = type; if (value.node->dt.raw != dt.raw) { value.node = tb_inst_bitcast(p->func, value.node, dt); @@ -1959,6 +1959,255 @@ gb_internal cgValue cg_build_expr(cgProcedure *p, Ast *expr) { } +gb_internal cgValue cg_find_ident(cgProcedure *p, Entity *e, Ast *expr) { + cgAddr *found_addr = map_get(&p->variable_map, e); + if (found_addr) { + return cg_addr_load(p, *found_addr); + } + + cgValue *found = nullptr; + rw_mutex_shared_lock(&p->module->values_mutex); + found = map_get(&p->module->values, e); + rw_mutex_shared_unlock(&p->module->values_mutex); + + if (found) { + + auto v = *found; + // NOTE(bill): This is because pointers are already pointers in LLVM + if (is_type_proc(v.type)) { + return v; + } + return cg_emit_load(p, v); + } else if (e != nullptr && e->kind == Entity_Variable) { + return cg_addr_load(p, cg_build_addr(p, expr)); + } + + if (e->kind == Entity_Procedure) { + return cg_find_procedure_value_from_entity(p->module, e); + } + + String pkg = {}; + if (e->pkg) { + pkg = e->pkg->name; + } + gb_printf_err("Error in: %s\n", token_pos_to_string(ast_token(expr).pos)); + GB_PANIC("nullptr value for expression from identifier: %.*s.%.*s (%p) : %s @ %p", LIT(pkg), LIT(e->token.string), e, type_to_string(e->type), expr); + return {}; +} + +gb_internal cgValue cg_build_unary_and(cgProcedure *p, Ast *expr) { + ast_node(ue, UnaryExpr, expr); + auto tv = type_and_value_of_expr(expr); + + + Ast *ue_expr = unparen_expr(ue->expr); + if (ue_expr->kind == Ast_IndexExpr && tv.mode == Addressing_OptionalOkPtr && is_type_tuple(tv.type)) { + GB_PANIC("TODO(bill): &m[k]"); + // Type *tuple = tv.type; + + // Type *map_type = type_of_expr(ue_expr->IndexExpr.expr); + // Type *ot = base_type(map_type); + // Type *t = base_type(type_deref(ot)); + // bool deref = t != ot; + // GB_ASSERT(t->kind == Type_Map); + // ast_node(ie, IndexExpr, ue_expr); + + // lbValue map_val = lb_build_addr_ptr(p, ie->expr); + // if (deref) { + // map_val = lb_emit_load(p, map_val); + // } + + // lbValue key = lb_build_expr(p, ie->index); + // key = lb_emit_conv(p, key, t->Map.key); + + // lbAddr addr = lb_addr_map(map_val, key, t, alloc_type_pointer(t->Map.value)); + // lbValue ptr = lb_addr_get_ptr(p, addr); + + // lbValue ok = lb_emit_comp_against_nil(p, Token_NotEq, ptr); + // ok = lb_emit_conv(p, ok, tuple->Tuple.variables[1]->type); + + // lbAddr res = lb_add_local_generated(p, tuple, false); + // lbValue gep0 = lb_emit_struct_ep(p, res.addr, 0); + // lbValue gep1 = lb_emit_struct_ep(p, res.addr, 1); + // lb_emit_store(p, gep0, ptr); + // lb_emit_store(p, gep1, ok); + // return lb_addr_load(p, res); + + } else if (is_type_soa_pointer(tv.type)) { + GB_PANIC("TODO(bill): &soa[i]"); + // 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) { + cgValue v = cg_build_expr(p, ue->expr); + + Type *type = v.type; + cgAddr addr = {}; + // if (p->is_startup) { + // addr = cg_add_global_generated(p->module, type, v); + // } else { + addr = cg_add_local(p, type, nullptr, false); + // } + cg_addr_store(p, addr, v); + return addr.addr; + + } else if (ue_expr->kind == Ast_TypeAssertion) { + GB_PANIC("TODO(bill): &v.(T)"); + // if (is_type_tuple(tv.type)) { + // Type *tuple = tv.type; + // Type *ptr_type = tuple->Tuple.variables[0]->type; + // Type *ok_type = tuple->Tuple.variables[1]->type; + + // ast_node(ta, TypeAssertion, ue_expr); + // TokenPos pos = ast_token(expr).pos; + // Type *type = type_of_expr(ue_expr); + // GB_ASSERT(!is_type_tuple(type)); + + // lbValue e = lb_build_expr(p, ta->expr); + // Type *t = type_deref(e.type); + // if (is_type_union(t)) { + // lbValue v = e; + // if (!is_type_pointer(v.type)) { + // v = lb_address_from_load_or_generate_local(p, v); + // } + // Type *src_type = type_deref(v.type); + // Type *dst_type = type; + + // lbValue src_tag = {}; + // lbValue dst_tag = {}; + // if (is_type_union_maybe_pointer(src_type)) { + // src_tag = lb_emit_comp_against_nil(p, Token_NotEq, v); + // dst_tag = lb_const_bool(p->module, t_bool, true); + // } else { + // src_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, v)); + // dst_tag = lb_const_union_tag(p->module, src_type, dst_type); + // } + + // lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); + + // lbValue data_ptr = lb_emit_conv(p, v, ptr_type); + // lbAddr res = lb_add_local_generated(p, tuple, true); + // lbValue gep0 = lb_emit_struct_ep(p, res.addr, 0); + // lbValue gep1 = lb_emit_struct_ep(p, res.addr, 1); + // lb_emit_store(p, gep0, lb_emit_select(p, ok, data_ptr, lb_const_nil(p->module, ptr_type))); + // lb_emit_store(p, gep1, lb_emit_conv(p, ok, ok_type)); + // return lb_addr_load(p, res); + // } else if (is_type_any(t)) { + // lbValue v = e; + // if (is_type_pointer(v.type)) { + // v = lb_emit_load(p, v); + // } + + // lbValue data_ptr = lb_emit_conv(p, lb_emit_struct_ev(p, v, 0), ptr_type); + // lbValue any_id = lb_emit_struct_ev(p, v, 1); + // lbValue id = lb_typeid(p->module, type); + + // lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id); + + // lbAddr res = lb_add_local_generated(p, tuple, false); + // lbValue gep0 = lb_emit_struct_ep(p, res.addr, 0); + // lbValue gep1 = lb_emit_struct_ep(p, res.addr, 1); + // lb_emit_store(p, gep0, lb_emit_select(p, ok, data_ptr, lb_const_nil(p->module, ptr_type))); + // lb_emit_store(p, gep1, lb_emit_conv(p, ok, ok_type)); + // return lb_addr_load(p, res); + // } else { + // GB_PANIC("TODO(bill): type assertion %s", type_to_string(type)); + // } + + // } else { + // GB_ASSERT(is_type_pointer(tv.type)); + + // ast_node(ta, TypeAssertion, ue_expr); + // TokenPos pos = ast_token(expr).pos; + // Type *type = type_of_expr(ue_expr); + // GB_ASSERT(!is_type_tuple(type)); + + // lbValue e = lb_build_expr(p, ta->expr); + // Type *t = type_deref(e.type); + // if (is_type_union(t)) { + // lbValue v = e; + // if (!is_type_pointer(v.type)) { + // v = lb_address_from_load_or_generate_local(p, v); + // } + // Type *src_type = type_deref(v.type); + // Type *dst_type = type; + + + // if ((p->state_flags & StateFlag_no_type_assert) == 0) { + // lbValue src_tag = {}; + // lbValue dst_tag = {}; + // if (is_type_union_maybe_pointer(src_type)) { + // src_tag = lb_emit_comp_against_nil(p, Token_NotEq, v); + // dst_tag = lb_const_bool(p->module, t_bool, true); + // } else { + // src_tag = lb_emit_load(p, lb_emit_union_tag_ptr(p, v)); + // dst_tag = lb_const_union_tag(p->module, src_type, dst_type); + // } + + + // isize arg_count = 6; + // if (build_context.no_rtti) { + // arg_count = 4; + // } + + // lbValue ok = lb_emit_comp(p, Token_CmpEq, src_tag, dst_tag); + // auto args = array_make(permanent_allocator(), arg_count); + // args[0] = ok; + + // args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); + // args[2] = lb_const_int(p->module, t_i32, pos.line); + // args[3] = lb_const_int(p->module, t_i32, pos.column); + + // if (!build_context.no_rtti) { + // args[4] = lb_typeid(p->module, src_type); + // args[5] = lb_typeid(p->module, dst_type); + // } + // lb_emit_runtime_call(p, "type_assertion_check", args); + // } + + // lbValue data_ptr = v; + // return lb_emit_conv(p, data_ptr, tv.type); + // } else if (is_type_any(t)) { + // lbValue v = e; + // if (is_type_pointer(v.type)) { + // v = lb_emit_load(p, v); + // } + // lbValue data_ptr = lb_emit_struct_ev(p, v, 0); + // if ((p->state_flags & StateFlag_no_type_assert) == 0) { + // GB_ASSERT(!build_context.no_rtti); + + // lbValue any_id = lb_emit_struct_ev(p, v, 1); + + // lbValue id = lb_typeid(p->module, type); + // lbValue ok = lb_emit_comp(p, Token_CmpEq, any_id, id); + // auto args = array_make(permanent_allocator(), 6); + // args[0] = ok; + + // args[1] = lb_find_or_add_entity_string(p->module, get_file_path_string(pos.file_id)); + // args[2] = lb_const_int(p->module, t_i32, pos.line); + // args[3] = lb_const_int(p->module, t_i32, pos.column); + + // args[4] = any_id; + // args[5] = id; + // lb_emit_runtime_call(p, "type_assertion_check", args); + // } + + // return lb_emit_conv(p, data_ptr, tv.type); + // } else { + // GB_PANIC("TODO(bill): type assertion %s", type_to_string(type)); + // } + // } + } + + return cg_build_addr_ptr(p, ue->expr); +} + gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { expr = unparen_expr(expr); @@ -2016,9 +2265,7 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { if (addr) { return cg_addr_load(p, *addr); } - // return cg_find_ident(p, m, e, expr); - GB_PANIC("TODO: cg_find_ident"); - return {}; + return cg_find_ident(p, e, expr); case_end; case_ast_node(i, Implicit, expr); @@ -2151,8 +2398,7 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { case_ast_node(ue, UnaryExpr, expr); if (ue->op.kind == Token_And) { - GB_PANIC("TODO(bill): cg_build_unary_and"); - // return cg_build_unary_and(p, expr); + return cg_build_unary_and(p, expr); } cgValue v = cg_build_expr(p, ue->expr); return cg_emit_unary_arith(p, ue->op.kind, v, type); @@ -2166,6 +2412,10 @@ gb_internal cgValue cg_build_expr_internal(cgProcedure *p, Ast *expr) { } +gb_internal cgValue cg_build_addr_ptr(cgProcedure *p, Ast *expr) { + cgAddr addr = cg_build_addr(p, expr); + return cg_addr_get_ptr(p, addr); +} gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr); gb_internal cgAddr cg_build_addr(cgProcedure *p, Ast *expr) { @@ -2193,6 +2443,225 @@ gb_internal cgAddr cg_build_addr(cgProcedure *p, Ast *expr) { return addr; } +gb_internal cgAddr cg_build_addr_index_expr(cgProcedure *p, Ast *expr) { + ast_node(ie, IndexExpr, expr); + + Type *t = base_type(type_of_expr(ie->expr)); + + bool deref = is_type_pointer(t); + t = base_type(type_deref(t)); + if (is_type_soa_struct(t)) { + GB_PANIC("TODO(bill): #soa"); + // // SOA STRUCTURES!!!! + // lbValue val = cg_build_addr_ptr(p, ie->expr); + // if (deref) { + // val = cg_emit_load(p, val); + // } + + // cgValue index = cg_build_expr(p, ie->index); + // return cg_addr_soa_variable(val, index, ie->index); + } + + if (ie->expr->tav.mode == Addressing_SoaVariable) { + GB_PANIC("TODO(bill): #soa"); + // // SOA Structures for slices/dynamic arrays + // GB_ASSERT(is_type_pointer(type_of_expr(ie->expr))); + + // lbValue field = lb_build_expr(p, ie->expr); + // lbValue index = lb_build_expr(p, ie->index); + + + // if (!build_context.no_bounds_check) { + // // TODO HACK(bill): Clean up this hack to get the length for bounds checking + // // GB_ASSERT(LLVMIsALoadInst(field.value)); + + // // lbValue a = {}; + // // a.value = LLVMGetOperand(field.value, 0); + // // a.type = alloc_type_pointer(field.type); + + // // irInstr *b = &a->Instr; + // // GB_ASSERT(b->kind == irInstr_StructElementPtr); + // // lbValue base_struct = b->StructElementPtr.address; + + // // GB_ASSERT(is_type_soa_struct(type_deref(ir_type(base_struct)))); + // // lbValue len = ir_soa_struct_len(p, base_struct); + // // lb_emit_bounds_check(p, ast_token(ie->index), index, len); + // } + // lbValue val = lb_emit_ptr_offset(p, field, index); + // return lb_addr(val); + } + + GB_ASSERT_MSG(is_type_indexable(t), "%s %s", type_to_string(t), expr_to_string(expr)); + + if (is_type_map(t)) { + GB_PANIC("TODO(bill): map indexing"); + // lbAddr map_addr = lb_build_addr(p, ie->expr); + // lbValue key = lb_build_expr(p, ie->index); + // key = lb_emit_conv(p, key, t->Map.key); + + // Type *result_type = type_of_expr(expr); + // lbValue map_ptr = lb_addr_get_ptr(p, map_addr); + // if (is_type_pointer(type_deref(map_ptr.type))) { + // map_ptr = lb_emit_load(p, map_ptr); + // } + // return lb_addr_map(map_ptr, key, t, result_type); + } + + switch (t->kind) { + case Type_Array: { + cgValue array = {}; + array = cg_build_addr_ptr(p, ie->expr); + if (deref) { + array = cg_emit_load(p, array); + } + cgValue index = cg_build_expr(p, ie->index); + index = cg_emit_conv(p, index, t_int); + cgValue elem = cg_emit_array_ep(p, array, index); + + auto index_tv = type_and_value_of_expr(ie->index); + if (index_tv.mode != Addressing_Constant) { + // cgValue len = cg_const_int(p->module, t_int, t->Array.count); + // cg_emit_bounds_check(p, ast_token(ie->index), index, len); + } + return cg_addr(elem); + } + + case Type_EnumeratedArray: { + cgValue array = {}; + array = cg_build_addr_ptr(p, ie->expr); + if (deref) { + array = cg_emit_load(p, array); + } + + Type *index_type = t->EnumeratedArray.index; + + auto index_tv = type_and_value_of_expr(ie->index); + + cgValue index = {}; + if (compare_exact_values(Token_NotEq, *t->EnumeratedArray.min_value, exact_value_i64(0))) { + if (index_tv.mode == Addressing_Constant) { + ExactValue idx = exact_value_sub(index_tv.value, *t->EnumeratedArray.min_value); + index = cg_const_value(p, index_type, idx); + } else { + index = cg_emit_arith(p, Token_Sub, + cg_build_expr(p, ie->index), + cg_const_value(p, index_type, *t->EnumeratedArray.min_value), + index_type); + index = cg_emit_conv(p, index, t_int); + } + } else { + index = cg_emit_conv(p, cg_build_expr(p, ie->index), t_int); + } + + cgValue elem = cg_emit_array_ep(p, array, index); + + if (index_tv.mode != Addressing_Constant) { + // cgValue len = cg_const_int(p->module, t_int, t->EnumeratedArray.count); + // cg_emit_bounds_check(p, ast_token(ie->index), index, len); + } + return cg_addr(elem); + } + + case Type_Slice: { + cgValue slice = {}; + slice = cg_build_expr(p, ie->expr); + if (deref) { + slice = cg_emit_load(p, slice); + } + cgValue elem = cg_builtin_raw_data(p, slice); + cgValue index = cg_emit_conv(p, cg_build_expr(p, ie->index), t_int); + // cgValue len = cg_builtin_len(p, slice); + // cg_emit_bounds_check(p, ast_token(ie->index), index, len); + cgValue v = cg_emit_ptr_offset(p, elem, index); + return cg_addr(v); + } + + case Type_MultiPointer: { + cgValue multi_ptr = {}; + multi_ptr = cg_build_expr(p, ie->expr); + if (deref) { + multi_ptr = cg_emit_load(p, multi_ptr); + } + cgValue index = cg_build_expr(p, ie->index); + index = cg_emit_conv(p, index, t_int); + + return cg_addr(cg_emit_ptr_offset(p, multi_ptr, index)); + } + + case Type_RelativeSlice: { + GB_PANIC("TODO(bill): relative slice"); + // lbAddr slice_addr = {}; + // if (deref) { + // slice_addr = lb_addr(lb_build_expr(p, ie->expr)); + // } else { + // slice_addr = lb_build_addr(p, ie->expr); + // } + // lbValue slice = lb_addr_load(p, slice_addr); + + // lbValue elem = lb_slice_elem(p, slice); + // lbValue index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int); + // lbValue len = lb_slice_len(p, slice); + // lb_emit_bounds_check(p, ast_token(ie->index), index, len); + // lbValue v = lb_emit_ptr_offset(p, elem, index); + // return lb_addr(v); + } + + case Type_DynamicArray: { + cgValue dynamic_array = {}; + dynamic_array = cg_build_expr(p, ie->expr); + if (deref) { + dynamic_array = cg_emit_load(p, dynamic_array); + } + cgValue elem = cg_builtin_raw_data(p, dynamic_array); + cgValue index = cg_emit_conv(p, cg_build_expr(p, ie->index), t_int); + // cgValue len = cg_dynamic_array_len(p, dynamic_array); + // cg_emit_bounds_check(p, ast_token(ie->index), index, len); + cgValue v = cg_emit_ptr_offset(p, elem, index); + return cg_addr(v); + } + + case Type_Matrix: { + GB_PANIC("TODO(bill): matrix"); + // lbValue matrix = {}; + // matrix = lb_build_addr_ptr(p, ie->expr); + // if (deref) { + // matrix = lb_emit_load(p, matrix); + // } + // lbValue index = lb_build_expr(p, ie->index); + // index = lb_emit_conv(p, index, t_int); + // lbValue elem = lb_emit_matrix_ep(p, matrix, lb_const_int(p->module, t_int, 0), index); + // elem = lb_emit_conv(p, elem, alloc_type_pointer(type_of_expr(expr))); + + // auto index_tv = type_and_value_of_expr(ie->index); + // if (index_tv.mode != Addressing_Constant) { + // lbValue len = lb_const_int(p->module, t_int, t->Matrix.column_count); + // lb_emit_bounds_check(p, ast_token(ie->index), index, len); + // } + // return lb_addr(elem); + } + + + case Type_Basic: { // Basic_string + cgValue str; + cgValue elem; + cgValue len; + cgValue index; + + str = cg_build_expr(p, ie->expr); + if (deref) { + str = cg_emit_load(p, str); + } + elem = cg_builtin_raw_data(p, str); + len = cg_builtin_len(p, str); + + index = cg_emit_conv(p, cg_build_expr(p, ie->index), t_int); + // cg_emit_bounds_check(p, ast_token(ie->index), index, len); + + return cg_addr(cg_emit_ptr_offset(p, elem, index)); + } + } + return {}; +} gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) { switch (expr->kind) { @@ -2218,6 +2687,10 @@ gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) { return cg_build_addr_from_entity(p, e, expr); case_end; + case_ast_node(ie, IndexExpr, expr); + return cg_build_addr_index_expr(p, expr); + case_end; + case_ast_node(se, SliceExpr, expr); return cg_build_addr_slice_expr(p, expr); case_end; @@ -2350,6 +2823,5 @@ gb_internal cgAddr cg_build_addr_internal(cgProcedure *p, Ast *expr) { LIT(ast_strings[expr->kind]), token_pos_to_string(token_pos)); - return {}; } \ No newline at end of file diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index 0deb4af45..8016e4dba 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -607,7 +607,8 @@ gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr) { } return {}; } - GB_PANIC("TODO(bill): builtin procs %d %.*s", id, LIT(builtin_procs[id].name)); + + return cg_build_builtin(p, id, expr); } // NOTE(bill): Regular call diff --git a/src/types.cpp b/src/types.cpp index f513f23d9..17945b109 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -594,6 +594,7 @@ gb_global Type *t_untyped_uninit = &basic_types[Basic_UntypedUninit]; gb_global Type *t_u8_ptr = nullptr; +gb_global Type *t_u8_multi_ptr = nullptr; gb_global Type *t_int_ptr = nullptr; gb_global Type *t_i64_ptr = nullptr; gb_global Type *t_f64_ptr = nullptr; -- cgit v1.2.3 From 0f217c715ecd9fc265b1c6a3d579b99ecf849139 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 25 Jul 2023 15:15:35 +0100 Subject: Fix dependency issue; Allow polymorphic procedures in tilde --- src/check_expr.cpp | 3 +- src/tilde.hpp | 3 +- src/tilde_debug.cpp | 11 ++- src/tilde_expr.cpp | 278 ++++++++++++++++++++++++++-------------------------- src/tilde_proc.cpp | 55 +++++++---- src/tilde_stmt.cpp | 28 ++++++ src/types.cpp | 30 ++++-- 7 files changed, 233 insertions(+), 175 deletions(-) (limited to 'src/types.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 98154f33d..d5e5f7952 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5985,8 +5985,8 @@ gb_internal bool check_call_arguments_single(CheckerContext *c, Ast *call, Opera } Entity *entity_to_use = data->gen_entity != nullptr ? data->gen_entity : e; + add_entity_use(c, ident, entity_to_use); if (!return_on_failure && entity_to_use != nullptr) { - add_entity_use(c, ident, entity_to_use); update_untyped_expr_type(c, operand->expr, entity_to_use->type, true); add_type_and_value(c, operand->expr, operand->mode, entity_to_use->type, operand->value); } @@ -7174,6 +7174,7 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c c->decl->defer_used += 1; } } + add_entity_use(c, operand->expr, initial_entity); } if (operand->mode != Addressing_ProcGroup) { diff --git a/src/tilde.hpp b/src/tilde.hpp index 72d5048bb..7f2ee8076 100644 --- a/src/tilde.hpp +++ b/src/tilde.hpp @@ -309,7 +309,8 @@ gb_internal cgValue cg_addr_get_ptr(cgProcedure *p, cgAddr const &addr); gb_internal cgValue cg_emit_load(cgProcedure *p, cgValue const &ptr, bool is_volatile=false); gb_internal void cg_emit_store(cgProcedure *p, cgValue dst, cgValue src, bool is_volatile=false); -gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero_init); +gb_internal cgAddr cg_add_local (cgProcedure *p, Type *type, Entity *e, bool zero_init); +gb_internal cgAddr cg_add_global(cgProcedure *p, Type *type, Entity *e); gb_internal cgValue cg_address_from_load_or_generate_local(cgProcedure *p, cgValue value); gb_internal cgValue cg_copy_value_to_ptr(cgProcedure *p, cgValue value, Type *original_type, isize min_alignment); diff --git a/src/tilde_debug.cpp b/src/tilde_debug.cpp index e6e60be96..708476377 100644 --- a/src/tilde_debug.cpp +++ b/src/tilde_debug.cpp @@ -76,9 +76,18 @@ gb_internal TB_DebugType *cg_debug_type_internal_record(cgModule *m, Type *type, type_set_offsets(bt); TB_DebugType *record = tb_debug_create_struct(m->mod, 0, ""); - TB_DebugType **fields = tb_debug_record_begin(record, bt->Tuple.variables.count); + isize record_count = 0; + for (Entity *e : bt->Tuple.variables) { + if (e->kind == Entity_Variable) { + record_count += 1; + } + } + TB_DebugType **fields = tb_debug_record_begin(record, record_count); for_array(i, bt->Tuple.variables) { Entity *e = bt->Tuple.variables[i]; + if (e->kind != Entity_Variable) { + continue; + } Type *type = e->type; if (is_type_proc(type)) { type = t_rawptr; diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index 96f17bfcf..1966dcd8e 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -2399,7 +2399,12 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) { Type *type = type_of_expr(expr); Type *bt = base_type(type); - cgAddr v = cg_add_local(p, type, nullptr, true); + cgAddr v = {}; + if (p->is_startup) { + v = cg_add_global(p, type, nullptr); + } else { + v = cg_add_local(p, type, nullptr, true); + } if (cl->elems.count == 0) { // No need to create it @@ -2424,8 +2429,6 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) { } TokenPos pos = ast_token(expr).pos; - if (cl->elems.count == 0) { - } switch (bt->kind) { default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break; @@ -2493,21 +2496,22 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) { return v; } - // case Type_Map: { - // GB_ASSERT(!build_context.no_dynamic_literals); + case Type_Map: { + GB_ASSERT(!build_context.no_dynamic_literals); + GB_PANIC("TODO(bill): map literals"); - // cgValue err = cg_dynamic_map_reserve(p, v.addr, 2*cl->elems.count, pos); - // gb_unused(err); + // cgValue err = cg_dynamic_map_reserve(p, v.addr, 2*cl->elems.count, pos); + // gb_unused(err); - // for (Ast *elem : cl->elems) { - // ast_node(fv, FieldValue, elem); + // for (Ast *elem : cl->elems) { + // ast_node(fv, FieldValue, elem); - // cgValue key = cg_build_expr(p, fv->field); - // cgValue value = cg_build_expr(p, fv->value); - // cg_internal_dynamic_map_set(p, v.addr, type, key, value, elem); - // } - // break; - // } + // cgValue key = cg_build_expr(p, fv->field); + // cgValue value = cg_build_expr(p, fv->value); + // cg_internal_dynamic_map_set(p, v.addr, type, key, value, elem); + // } + break; + } case Type_Array: { auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); @@ -2523,23 +2527,21 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) { assign_array(p, temp_data); break; } - // case Type_EnumeratedArray: { - // cg_addr_store(p, v, cg_const_value(p->module, type, exact_value_compound(expr))); - - // auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); + case Type_EnumeratedArray: { + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); - // populate(p, cl->elems, &temp_data, type); + populate(p, cl->elems, &temp_data, type); - // cgValue dst_ptr = cg_addr_get_ptr(p, v); - // i64 index_offset = exact_value_to_i64(*bt->EnumeratedArray.min_value); - // for_array(i, temp_data) { - // i32 index = cast(i32)(temp_data[i].elem_index - index_offset); - // temp_data[i].gep = cg_emit_array_epi(p, dst_ptr, index); - // } + cgValue dst_ptr = cg_addr_get_ptr(p, v); + i64 index_offset = exact_value_to_i64(*bt->EnumeratedArray.min_value); + for_array(i, temp_data) { + i32 index = cast(i32)(temp_data[i].elem_index - index_offset); + temp_data[i].gep = cg_emit_array_epi(p, dst_ptr, index); + } - // assign_array(p, temp_data); - // break; - // } + assign_array(p, temp_data); + break; + } case Type_Slice: { isize count = gb_max(cl->elems.count, cl->max_count); @@ -2570,88 +2572,89 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) { return v; } - // case Type_DynamicArray: { - // GB_ASSERT(!build_context.no_dynamic_literals); + case Type_DynamicArray: { + GB_ASSERT(!build_context.no_dynamic_literals); - // Type *et = bt->DynamicArray.elem; - // cgValue size = cg_const_int(p->module, t_int, type_size_of(et)); - // cgValue align = cg_const_int(p->module, t_int, type_align_of(et)); + Type *et = bt->DynamicArray.elem; + cgValue size = cg_const_int(p, t_int, type_size_of(et)); + cgValue align = cg_const_int(p, t_int, type_align_of(et)); - // i64 item_count = gb_max(cl->max_count, cl->elems.count); - // { + i64 item_count = gb_max(cl->max_count, cl->elems.count); + { - // auto args = array_make(temporary_allocator(), 5); - // args[0] = cg_emit_conv(p, cg_addr_get_ptr(p, v), t_rawptr); - // args[1] = size; - // args[2] = align; - // args[3] = cg_const_int(p->module, t_int, item_count); - // args[4] = cg_emit_source_code_location_as_global(p, proc_name, pos); - // cg_emit_runtime_call(p, "__dynamic_array_reserve", args); - // } + auto args = slice_make(temporary_allocator(), 5); + args[0] = cg_emit_conv(p, cg_addr_get_ptr(p, v), t_rawptr); + args[1] = size; + args[2] = align; + args[3] = cg_const_int(p, t_int, item_count); + args[4] = cg_emit_source_code_location_as_global(p, proc_name, pos); + cg_emit_runtime_call(p, "__dynamic_array_reserve", args); + } - // cgValue items = cg_generate_local_array(p, et, item_count); + Type *array_type = alloc_type_array(et, item_count); + cgAddr items_addr = cg_add_local(p, array_type, nullptr, true); + cgValue items = cg_addr_get_ptr(p, items_addr); - // auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); - // populate(p, cl->elems, &temp_data, type); + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); + populate(p, cl->elems, &temp_data, type); - // for_array(i, temp_data) { - // temp_data[i].gep = cg_emit_array_epi(p, items, temp_data[i].elem_index); - // } - // assign_array(p, temp_data); - - // { - // auto args = array_make(temporary_allocator(), 6); - // args[0] = cg_emit_conv(p, v.addr, t_rawptr); - // args[1] = size; - // args[2] = align; - // args[3] = cg_emit_conv(p, items, t_rawptr); - // args[4] = cg_const_int(p->module, t_int, item_count); - // args[5] = cg_emit_source_code_location_as_global(p, proc_name, pos); - // cg_emit_runtime_call(p, "__dynamic_array_append", args); - // } - // break; - // } + for_array(i, temp_data) { + temp_data[i].gep = cg_emit_array_epi(p, items, temp_data[i].elem_index); + } + assign_array(p, temp_data); - // case Type_Basic: { - // GB_ASSERT(is_type_any(bt)); - // cg_addr_store(p, v, cg_const_value(p->module, type, exact_value_compound(expr))); - // String field_names[2] = { - // str_lit("data"), - // str_lit("id"), - // }; - // Type *field_types[2] = { - // t_rawptr, - // t_typeid, - // }; - - // for_array(field_index, cl->elems) { - // Ast *elem = cl->elems[field_index]; - - // cgValue field_expr = {}; - // isize index = field_index; - - // if (elem->kind == Ast_FieldValue) { - // ast_node(fv, FieldValue, elem); - // Selection sel = lookup_field(bt, fv->field->Ident.token.string, false); - // index = sel.index[0]; - // elem = fv->value; - // } else { - // TypeAndValue tav = type_and_value_of_expr(elem); - // Selection sel = lookup_field(bt, field_names[field_index], false); - // index = sel.index[0]; - // } - - // field_expr = cg_build_expr(p, elem); - - // GB_ASSERT(field_expr.type->kind != Type_Tuple); - - // Type *ft = field_types[index]; - // cgValue fv = cg_emit_conv(p, field_expr, ft); - // cgValue gep = cg_emit_struct_ep(p, cg_addr_get_ptr(p, v), cast(i32)index); - // cg_emit_store(p, gep, fv); - // } - // break; - // } + { + auto args = slice_make(temporary_allocator(), 6); + args[0] = cg_emit_conv(p, v.addr, t_rawptr); + args[1] = size; + args[2] = align; + args[3] = cg_emit_conv(p, items, t_rawptr); + args[4] = cg_const_int(p, t_int, item_count); + args[5] = cg_emit_source_code_location_as_global(p, proc_name, pos); + cg_emit_runtime_call(p, "__dynamic_array_append", args); + } + break; + } + + case Type_Basic: { + GB_ASSERT(is_type_any(bt)); + String field_names[2] = { + str_lit("data"), + str_lit("id"), + }; + Type *field_types[2] = { + t_rawptr, + t_typeid, + }; + + for_array(field_index, cl->elems) { + Ast *elem = cl->elems[field_index]; + + cgValue field_expr = {}; + isize index = field_index; + + if (elem->kind == Ast_FieldValue) { + ast_node(fv, FieldValue, elem); + Selection sel = lookup_field(bt, fv->field->Ident.token.string, false); + index = sel.index[0]; + elem = fv->value; + } else { + TypeAndValue tav = type_and_value_of_expr(elem); + Selection sel = lookup_field(bt, field_names[field_index], false); + index = sel.index[0]; + } + + field_expr = cg_build_expr(p, elem); + + GB_ASSERT(field_expr.type->kind != Type_Tuple); + + Type *ft = field_types[index]; + cgValue fv = cg_emit_conv(p, field_expr, ft); + cgValue gep = cg_emit_struct_ep(p, cg_addr_get_ptr(p, v), index); + cg_emit_store(p, gep, fv); + } + break; + } case Type_BitSet: { i64 sz = type_size_of(type); @@ -2679,48 +2682,41 @@ cgAddr cg_build_addr_compound_lit(cgProcedure *p, Ast *expr) { return v; } - // case Type_Matrix: { - // cg_addr_store(p, v, cg_const_value(p->module, type, exact_value_compound(expr))); + case Type_Matrix: { + auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); - // auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); + populate(p, cl->elems, &temp_data, type); - // populate(p, cl->elems, &temp_data, type); + cgValue dst_ptr = cg_addr_get_ptr(p, v); + for_array(i, temp_data) { + temp_data[i].gep = cg_emit_array_epi(p, dst_ptr, temp_data[i].elem_index); + } - // cgValue dst_ptr = cg_addr_get_ptr(p, v); - // for_array(i, temp_data) { - // temp_data[i].gep = cg_emit_array_epi(p, dst_ptr, temp_data[i].elem_index); - // } + assign_array(p, temp_data); + break; + } - // assign_array(p, temp_data); - // break; - // } + case Type_SimdVector: { + // auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); - // case Type_SimdVector: { - // cgValue vector_value = cg_const_value(p->module, type, exact_value_compound(expr)); - // defer (cg_addr_store(p, v, vector_value)); - - // auto temp_data = array_make(temporary_allocator(), 0, cl->elems.count); - - // populate(p, cl->elems, &temp_data, type); - - // // TODO(bill): reduce the need for individual `insertelement` if a `shufflevector` - // // might be a better option - // for (auto const &td : temp_data) { - // if (td.value.value != nullptr) { - // if (td.elem_length > 0) { - // for (i64 k = 0; k < td.elem_length; k++) { - // LLVMValueRef index = cg_const_int(p->module, t_u32, td.elem_index + k).value; - // vector_value.value = LLVMBuildInsertElement(p->builder, vector_value.value, td.value.value, index, ""); - // } - // } else { - // LLVMValueRef index = cg_const_int(p->module, t_u32, td.elem_index).value; - // vector_value.value = LLVMBuildInsertElement(p->builder, vector_value.value, td.value.value, index, ""); - - // } - // } - // } - // break; - // } + // populate(p, cl->elems, &temp_data, type); + + // // TODO(bill): reduce the need for individual `insertelement` if a `shufflevector` + // // might be a better option + // for (auto const &td : temp_data) if (td.value.node != nullptr) { + // if (td.elem_length > 0) { + // for (i64 k = 0; k < td.elem_length; k++) { + // LLVMValueRef index = cg_const_int(p->module, t_u32, td.elem_index + k).value; + // vector_value.value = LLVMBuildInsertElement(p->builder, vector_value.value, td.value.value, index, ""); + // } + // } else { + // LLVMValueRef index = cg_const_int(p->module, t_u32, td.elem_index).value; + // vector_value.value = LLVMBuildInsertElement(p->builder, vector_value.value, td.value.value, index, ""); + + // } + // } + break; + } } return v; diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp index 80948adea..7e751ac82 100644 --- a/src/tilde_proc.cpp +++ b/src/tilde_proc.cpp @@ -582,8 +582,13 @@ gb_internal cgValue cg_emit_call(cgProcedure * p, cgValue value, Slice params[param_index++] = local; } } + isize param_entity_index = 0; for_array(i, args) { - Type *param_type = param_entities[i]->type; + Entity *param_entity = nullptr; + do { + param_entity = param_entities[param_entity_index++]; + } while (param_entity->kind != Entity_Variable); + Type *param_type = param_entity->type; cgValue arg = args[i]; arg = cg_emit_conv(p, arg, param_type); arg = cg_flatten_value(p, arg); @@ -839,7 +844,15 @@ gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr) { GB_ASSERT(ce->split_args != nullptr); - auto args = array_make(temporary_allocator(), 0, pt->param_count); + isize internal_param_count = 0; + if (pt->params) for (Entity *e : pt->params->Tuple.variables) { + if (e->kind == Entity_Variable) { + internal_param_count += 1; + } + } + GB_ASSERT(internal_param_count <= pt->param_count); + + auto args = array_make(temporary_allocator(), 0, internal_param_count); bool vari_expand = (ce->ellipsis.pos.line != 0); bool is_c_vararg = pt->c_vararg; @@ -918,7 +931,7 @@ gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr) { } if (!is_c_vararg) { - array_resize(&args, pt->param_count); + array_resize(&args, internal_param_count); } for (Ast *arg : ce->split_args->named) { @@ -938,39 +951,39 @@ gb_internal cgValue cg_build_call_expr_internal(cgProcedure *p, Ast *expr) { if (pt->params != nullptr) { - isize min_count = pt->params->Tuple.variables.count; + isize min_count = internal_param_count; if (is_c_vararg) { min_count -= 1; } - GB_ASSERT(args.count >= min_count); - for_array(arg_index, pt->params->Tuple.variables) { - Entity *e = pt->params->Tuple.variables[arg_index]; - if (pt->variadic && arg_index == pt->variadic_index) { + GB_ASSERT_MSG(args.count >= min_count, "in %.*s", LIT(p->name)); + isize arg_index = 0; + for_array(param_index, pt->params->Tuple.variables) { + Entity *e = pt->params->Tuple.variables[param_index]; + if (e->kind == Entity_TypeName) { + continue; + } else if (e->kind == Entity_Constant) { + continue; + } + GB_ASSERT(e->kind == Entity_Variable); + + if (pt->variadic && param_index == pt->variadic_index) { if (!is_c_vararg && args[arg_index].node == nullptr) { - args[arg_index] = cg_const_nil(p, e->type); + args[arg_index++] = cg_const_nil(p, e->type); } continue; } cgValue arg = args[arg_index]; if (arg.node == nullptr) { - switch (e->kind) { - case Entity_TypeName: - case Entity_Constant: - break; - case Entity_Variable: - args[arg_index] = cg_handle_param_value(p, e->type, e->Variable.param_value, pos); - break; - default: - GB_PANIC("Unknown entity kind %.*s\n", LIT(entity_strings[e->kind])); - } + GB_ASSERT(e->kind == Entity_Variable); + args[arg_index++] = cg_handle_param_value(p, e->type, e->Variable.param_value, pos); } else { - args[arg_index] = cg_emit_conv(p, arg, e->type); + args[arg_index++] = cg_emit_conv(p, arg, e->type); } } } - isize final_count = is_c_vararg ? args.count : pt->param_count; + isize final_count = is_c_vararg ? args.count : internal_param_count; auto call_args = slice(args, 0, final_count); return cg_emit_call(p, value, call_args); diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index 88c266689..0b5f122d4 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -747,6 +747,34 @@ gb_internal cgAddr cg_add_local(cgProcedure *p, Type *type, Entity *e, bool zero return addr; } +gb_internal cgAddr cg_add_global(cgProcedure *p, Type *type, Entity *e) { + GB_ASSERT(type != nullptr); + + isize size = type_size_of(type); + TB_CharUnits alignment = cast(TB_CharUnits)type_align_of(type); + if (is_type_matrix(type)) { + alignment *= 2; // NOTE(bill): Just in case + } + + TB_Global *global = tb_global_create(p->module->mod, 0, "", nullptr, TB_LINKAGE_PRIVATE); + tb_global_set_storage(p->module->mod, tb_module_get_data(p->module->mod), global, size, alignment, 0); + TB_Node *local = tb_inst_get_symbol_address(p->func, cast(TB_Symbol *)global); + + if (e != nullptr && e->token.string.len > 0 && e->token.string != "_") { + // NOTE(bill): for debugging purposes only + String name = e->token.string; + TB_DebugType *debug_type = cg_debug_type(p->module, type); + tb_node_append_attrib(local, tb_function_attrib_variable(p->func, name.len, cast(char const *)name.text, debug_type)); + } + + cgAddr addr = cg_addr(cg_value(local, alloc_type_pointer(type))); + if (e) { + map_set(&p->variable_map, e, addr); + } + return addr; +} + + gb_internal cgValue cg_copy_value_to_ptr(cgProcedure *p, cgValue value, Type *original_type, isize min_alignment) { TB_CharUnits size = cast(TB_CharUnits)type_size_of(original_type); TB_CharUnits align = cast(TB_CharUnits)gb_max(type_align_of(original_type), min_alignment); diff --git a/src/types.cpp b/src/types.cpp index 17945b109..f6e377cdc 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -3646,18 +3646,26 @@ gb_internal i64 *type_set_offsets_of(Slice const &fields, bool is_pack } } else if (is_packed) { for_array(i, fields) { - i64 size = type_size_of(fields[i]->type); - offsets[i] = curr_offset; - curr_offset += size; + if (fields[i]->kind != Entity_Variable) { + offsets[i] = -1; + } else { + i64 size = type_size_of(fields[i]->type); + offsets[i] = curr_offset; + curr_offset += size; + } } } else { for_array(i, fields) { - Type *t = fields[i]->type; - i64 align = gb_max(type_align_of(t), 1); - i64 size = gb_max(type_size_of( t), 0); - curr_offset = align_formula(curr_offset, align); - offsets[i] = curr_offset; - curr_offset += size; + if (fields[i]->kind != Entity_Variable) { + offsets[i] = -1; + } else { + Type *t = fields[i]->type; + i64 align = gb_max(type_align_of(t), 1); + i64 size = gb_max(type_size_of( t), 0); + curr_offset = align_formula(curr_offset, align); + offsets[i] = curr_offset; + curr_offset += size; + } } } return offsets; @@ -3924,7 +3932,9 @@ gb_internal i64 type_offset_of(Type *t, i64 index, Type **field_type_) { if (gb_is_between(index, 0, t->Tuple.variables.count-1)) { GB_ASSERT(t->Tuple.offsets != nullptr); if (field_type_) *field_type_ = t->Tuple.variables[index]->type; - return t->Tuple.offsets[index]; + i64 offset = t->Tuple.offsets[index]; + GB_ASSERT(offset >= 0); + return offset; } break; -- cgit v1.2.3 From a99da47b0d06adbe23144938135e95b6e531b9ba Mon Sep 17 00:00:00 2001 From: ryuukk <44361234+ryuukk@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:13:55 +0200 Subject: Assign element to Slice not Array when alloc a Type_Slice --- src/types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/types.cpp') diff --git a/src/types.cpp b/src/types.cpp index 847aea9f3..d11c27be6 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -988,7 +988,7 @@ gb_internal Type *alloc_type_enumerated_array(Type *elem, Type *index, ExactValu gb_internal Type *alloc_type_slice(Type *elem) { Type *t = alloc_type(Type_Slice); - t->Array.elem = elem; + t->Slice.elem = elem; return t; } -- cgit v1.2.3 From 65206fe33e52a707134c919c01a0f8ae2d19c2d8 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 1 Aug 2023 11:39:04 +0100 Subject: Go through loads of `TODO`s --- src/check_decl.cpp | 13 +++++++------ src/check_expr.cpp | 30 +++--------------------------- src/check_stmt.cpp | 11 +++++------ src/checker.cpp | 5 ----- src/checker.hpp | 2 -- src/entity.cpp | 7 +++---- src/exact_value.cpp | 7 ++----- src/llvm_backend_general.cpp | 3 +-- src/llvm_backend_proc.cpp | 5 +---- src/llvm_backend_stmt.cpp | 5 +---- src/llvm_backend_type.cpp | 1 - src/parser.cpp | 2 -- src/types.cpp | 22 +++++++++++++--------- 13 files changed, 36 insertions(+), 77 deletions(-) (limited to 'src/types.cpp') diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 4a1a636f8..587d749b4 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -7,13 +7,15 @@ gb_internal Type *check_init_variable(CheckerContext *ctx, Entity *e, Operand *o e->type == t_invalid) { if (operand->mode == Addressing_Builtin) { + ERROR_BLOCK(); gbString expr_str = expr_to_string(operand->expr); - // TODO(bill): is this a good enough error message? error(operand->expr, - "Cannot assign built-in procedure '%s' in %.*s", - expr_str, - LIT(context_name)); + "Cannot assign built-in procedure '%s' in %.*s", + expr_str, + LIT(context_name)); + + error_line("\tBuilt-in procedures are implemented by the compiler and might not be actually instantiated procedure\n"); operand->mode = Addressing_Invalid; @@ -159,9 +161,8 @@ gb_internal void check_init_constant(CheckerContext *ctx, Entity *e, Operand *op } if (operand->mode != Addressing_Constant) { - // TODO(bill): better error gbString str = expr_to_string(operand->expr); - error(operand->expr, "'%s' is not a constant", str); + error(operand->expr, "'%s' is not a compile-time known constant", str); gb_string_free(str); if (e->type == nullptr) { e->type = t_invalid; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 40bf729c1..d2616ca72 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -462,7 +462,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E { - // LEAK TODO(bill): This is technically a memory leak as it has to generate the type twice + // LEAK NOTE(bill): This is technically a memory leak as it has to generate the type twice bool prev_no_polymorphic_errors = nctx.no_polymorphic_errors; defer (nctx.no_polymorphic_errors = prev_no_polymorphic_errors); nctx.no_polymorphic_errors = false; @@ -470,7 +470,7 @@ gb_internal bool find_or_generate_polymorphic_procedure(CheckerContext *old_c, E // NOTE(bill): Reset scope from the failed procedure type scope_reset(scope); - // LEAK TODO(bill): Cloning this AST may be leaky + // LEAK NOTE(bill): Cloning this AST may be leaky but this is not really an issue due to arena-based allocation Ast *cloned_proc_type_node = clone_ast(pt->node); success = check_procedure_type(&nctx, final_proc_type, cloned_proc_type_node, &operands); if (!success) { @@ -778,16 +778,6 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand } } - // ^T <- rawptr -#if 0 - // TODO(bill): Should C-style (not C++) pointer cast be allowed? - if (is_type_pointer(dst) && is_type_rawptr(src)) { - return true; - } -#endif -#if 1 - - // rawptr <- ^T if (are_types_identical(type, t_rawptr) && is_type_pointer(src)) { return 5; @@ -808,7 +798,6 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand return 4; } } -#endif if (is_type_polymorphic(dst) && !is_type_polymorphic(src)) { bool modify_type = !c->no_polymorphic_errors; @@ -824,7 +813,6 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand } } - // TODO(bill): Determine which rule is a better on in practice if (dst->Union.variants.count == 1) { Type *vt = dst->Union.variants[0]; i64 score = check_distance_between_types(c, operand, vt); @@ -1093,7 +1081,7 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ // TODO(bill): is this a good enough error message? error(operand->expr, - "Cannot assign overloaded procedure '%s' to '%s' in %.*s", + "Cannot assign overloaded procedure group '%s' to '%s' in %.*s", expr_str, op_type_str, LIT(context_name)); @@ -1120,7 +1108,6 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ switch (operand->mode) { case Addressing_Builtin: - // TODO(bill): Actually allow built in procedures to be passed around and thus be created on use error(operand->expr, "Cannot assign built-in procedure '%s' in %.*s", expr_str, @@ -1412,9 +1399,6 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T return false; case Type_Proc: if (source->kind == Type_Proc) { - // return check_is_assignable_to(c, &o, poly); - // TODO(bill): Polymorphic type assignment - #if 1 TypeProc *x = &poly->Proc; TypeProc *y = &source->Proc; if (x->calling_convention != y->calling_convention) { @@ -1447,7 +1431,6 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T } return true; - #endif } return false; case Type_Map: @@ -1699,7 +1682,6 @@ gb_internal bool check_unary_op(CheckerContext *c, Operand *o, Token op) { gb_string_free(str); return false; } - // TODO(bill): Handle errors correctly Type *type = base_type(core_array_type(o->type)); gbString str = nullptr; switch (op.kind) { @@ -1743,7 +1725,6 @@ gb_internal bool check_unary_op(CheckerContext *c, Operand *o, Token op) { gb_internal bool check_binary_op(CheckerContext *c, Operand *o, Token op) { Type *main_type = o->type; - // TODO(bill): Handle errors correctly Type *type = base_type(core_array_type(main_type)); Type *ct = core_type(type); @@ -2775,8 +2756,6 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod gb_string_free(err_str); } - // TODO(bill): Should we support shifts for fixed arrays and #simd vectors? - if (!is_type_integer(x->type)) { gbString err_str = expr_to_string(x->expr); error(node, "Shift operand '%s' must be an integer", err_str); @@ -4437,7 +4416,6 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v case_end; default: - // TODO(bill): Should this be a general fallback? if (success_) *success_ = true; if (finish_) *finish_ = true; return empty_exact_value; @@ -4793,8 +4771,6 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod } if (entity == nullptr && selector->kind == Ast_Ident && is_type_array(type_deref(operand->type))) { - // TODO(bill): Simd_Vector swizzling - String field_name = selector->Ident.token.string; if (1 < field_name.len && field_name.len <= 4) { u8 swizzles_xyzw[4] = {'x', 'y', 'z', 'w'}; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index b497c0afb..fa5f8f428 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -384,7 +384,6 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O } if (e != nullptr) { - // HACK TODO(bill): Should the entities be freed as it's technically a leak rhs->mode = Addressing_Value; rhs->type = e->type; rhs->proc_group = nullptr; @@ -394,7 +393,7 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O ast_node(i, Ident, node); e = scope_lookup(ctx->scope, i->token.string); if (e != nullptr && e->kind == Entity_Variable) { - used = (e->flags & EntityFlag_Used) != 0; // TODO(bill): Make backup just in case + used = (e->flags & EntityFlag_Used) != 0; // NOTE(bill): Make backup just in case } } @@ -888,7 +887,7 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags check_open_scope(ctx, node); defer (check_close_scope(ctx)); - check_label(ctx, ss->label, node); // TODO(bill): What should the label's "scope" be? + check_label(ctx, ss->label, node); if (ss->init != nullptr) { check_stmt(ctx, ss->init, 0); @@ -1125,7 +1124,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ check_open_scope(ctx, node); defer (check_close_scope(ctx)); - check_label(ctx, ss->label, node); // TODO(bill): What should the label's "scope" be? + check_label(ctx, ss->label, node); if (ss->tag->kind != Ast_AssignStmt) { error(ss->tag, "Expected an 'in' assignment for this type switch statement"); @@ -1960,7 +1959,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f Token token = ast_token(node); if (vd->type != nullptr && entity_count > 1) { error(token, "'using' can only be applied to one variable of the same type"); - // TODO(bill): Should a 'continue' happen here? + // NOTE(bill): `using` will only be applied to a single declaration } for (isize entity_index = 0; entity_index < 1; entity_index++) { @@ -2294,7 +2293,7 @@ gb_internal void check_for_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { mod_flags |= Stmt_BreakAllowed | Stmt_ContinueAllowed; check_open_scope(ctx, node); - check_label(ctx, fs->label, node); // TODO(bill): What should the label's "scope" be? + check_label(ctx, fs->label, node); if (fs->init != nullptr) { check_stmt(ctx, fs->init, 0); diff --git a/src/checker.cpp b/src/checker.cpp index 91c62c20c..da4fae76c 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -967,7 +967,6 @@ gb_internal void init_universal(void) { add_global_bool_constant("true", true); add_global_bool_constant("false", false); - // TODO(bill): Set through flags in the compiler add_global_string_constant("ODIN_VENDOR", bc->ODIN_VENDOR); add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION); add_global_string_constant("ODIN_ROOT", bc->ODIN_ROOT); @@ -1477,7 +1476,6 @@ gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMo if (ctx->decl) { mutex = &ctx->decl->type_and_value_mutex; } else if (ctx->pkg) { - // TODO(bill): is a per package mutex is a good idea here? mutex = &ctx->pkg->type_and_value_mutex; } @@ -2580,9 +2578,6 @@ gb_internal Array generate_entity_dependency_graph(CheckerInf } } - // TODO(bill): This could be multithreaded to improve performance - // This means that the entity graph node set will have to be thread safe - TIME_SECTION("generate_entity_dependency_graph: Calculate edges for graph M - Part 2"); auto G = array_make(allocator, 0, M.count); diff --git a/src/checker.hpp b/src/checker.hpp index 8a63f7e88..bf956393c 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -387,8 +387,6 @@ struct CheckerInfo { BlockingMutex foreign_mutex; // NOT recursive StringMap foreigns; - // NOTE(bill): These are actually MPSC queues - // TODO(bill): Convert them to be MPSC queues MPSCQueue definition_queue; MPSCQueue entity_queue; MPSCQueue required_global_variable_queue; diff --git a/src/entity.cpp b/src/entity.cpp index 649dd900d..291ae8c83 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -287,7 +287,6 @@ gb_internal bool is_entity_kind_exported(EntityKind kind, bool allow_builtin = f } gb_internal bool is_entity_exported(Entity *e, bool allow_builtin = false) { - // TODO(bill): Determine the actual exportation rules for imports of entities GB_ASSERT(e != nullptr); if (!is_entity_kind_exported(e->kind, allow_builtin)) { return false; @@ -401,7 +400,7 @@ gb_internal Entity *alloc_entity_array_elem(Scope *scope, Token token, Type *typ return entity; } -gb_internal Entity *alloc_entity_procedure(Scope *scope, Token token, Type *signature_type, u64 tags) { +gb_internal Entity *alloc_entity_procedure(Scope *scope, Token token, Type *signature_type, u64 tags=0) { Entity *entity = alloc_entity(Entity_Procedure, scope, token, signature_type); entity->Procedure.tags = tags; return entity; @@ -418,7 +417,7 @@ gb_internal Entity *alloc_entity_import_name(Scope *scope, Token token, Type *ty entity->ImportName.path = path; entity->ImportName.name = name; entity->ImportName.scope = import_scope; - entity->state = EntityState_Resolved; // TODO(bill): Is this correct? + entity->state = EntityState_Resolved; return entity; } @@ -427,7 +426,7 @@ gb_internal Entity *alloc_entity_library_name(Scope *scope, Token token, Type *t Entity *entity = alloc_entity(Entity_LibraryName, scope, token, type); entity->LibraryName.paths = paths; entity->LibraryName.name = name; - entity->state = EntityState_Resolved; // TODO(bill): Is this correct? + entity->state = EntityState_Resolved; return entity; } diff --git a/src/exact_value.cpp b/src/exact_value.cpp index ff940aabb..cd499272f 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -26,8 +26,8 @@ enum ExactValueKind { ExactValue_Complex = 5, ExactValue_Quaternion = 6, ExactValue_Pointer = 7, - ExactValue_Compound = 8, // TODO(bill): Is this good enough? - ExactValue_Procedure = 9, // TODO(bill): Is this good enough? + ExactValue_Compound = 8, + ExactValue_Procedure = 9, ExactValue_Typeid = 10, ExactValue_Count, @@ -101,7 +101,6 @@ gb_internal ExactValue exact_value_bool(bool b) { } gb_internal ExactValue exact_value_string(String string) { - // TODO(bill): Allow for numbers with underscores in them ExactValue result = {ExactValue_String}; result.value_string = string; return result; @@ -702,7 +701,6 @@ gb_internal void match_exact_values(ExactValue *x, ExactValue *y) { compiler_error("match_exact_values: How'd you get here? Invalid ExactValueKind %d", x->kind); } -// TODO(bill): Allow for pointer arithmetic? Or are pointer slices good enough? gb_internal ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, ExactValue y) { match_exact_values(&x, &y); @@ -943,7 +941,6 @@ gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y) case ExactValue_String: { String a = x.value_string; String b = y.value_string; - // TODO(bill): gb_memcompare is used because the strings are UTF-8 switch (op) { case Token_CmpEq: return a == b; case Token_NotEq: return a != b; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index ad8a1816a..eb6389763 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1895,8 +1895,8 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Type_SimdVector: return lb_type_internal(m, base); - // TODO(bill): Deal with this correctly. Can this be named? case Type_Proc: + // TODO(bill): Deal with this correctly. Can this be named? return lb_type_internal(m, base); case Type_Tuple: @@ -2869,7 +2869,6 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) { if (USE_SEPARATE_MODULES) { lbModule *other_module = lb_module_of_entity(m->gen, e); - // TODO(bill): correct this logic bool is_external = other_module != m; if (!is_external) { if (e->code_gen_module != nullptr) { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index c27c55337..a3156a7ed 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -362,7 +362,6 @@ gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name Type *pt = p->type; lbCallingConventionKind cc_kind = lbCallingConvention_C; - // TODO(bill): Clean up this logic if (!is_arch_wasm()) { cc_kind = lb_calling_convention_map[pt->Proc.calling_convention]; } @@ -1702,7 +1701,6 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu lbValue v = lb_build_expr(p, ce->args[0]); Type *t = base_type(v.type); if (is_type_pointer(t)) { - // IMPORTANT TODO(bill): Should there be a nil pointer check? v = lb_emit_load(p, v); t = type_deref(t); } @@ -1730,7 +1728,6 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu lbValue v = lb_build_expr(p, ce->args[0]); Type *t = base_type(v.type); if (is_type_pointer(t)) { - // IMPORTANT TODO(bill): Should there be a nil pointer check? v = lb_emit_load(p, v); t = type_deref(t); } @@ -3144,7 +3141,7 @@ gb_internal lbValue lb_build_call_expr(lbProcedure *p, Ast *expr) { lbValue res = lb_build_call_expr_internal(p, expr); - if (ce->optional_ok_one) { // TODO(bill): Minor hack for #optional_ok procedures + if (ce->optional_ok_one) { GB_ASSERT(is_type_tuple(res.type)); GB_ASSERT(res.type->Tuple.variables.count == 2); return lb_emit_struct_ev(p, res, 0); diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index 60420402a..9d688be6a 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1688,7 +1688,6 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss lb_add_entity(p->module, case_entity, ptr); lb_add_debug_local_variable(p, ptr.value, case_entity->type, case_entity->token); } else { - // TODO(bill): is the correct expected behaviour? lb_store_type_case_implicit(p, clause, parent_value); } @@ -2014,12 +2013,10 @@ gb_internal void lb_build_if_stmt(lbProcedure *p, Ast *node) { defer (lb_close_scope(p, lbDeferExit_Default, nullptr)); if (is->init != nullptr) { - // TODO(bill): Should this have a separate block to begin with? - #if 1 lbBlock *init = lb_create_block(p, "if.init"); lb_emit_jump(p, init); lb_start_block(p, init); - #endif + lb_build_stmt(p, is->init); } lbBlock *then = lb_create_block(p, "if.then"); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 4716733cc..c85840517 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -731,7 +731,6 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_set_offsets(t); // NOTE(bill): Just incase the offsets have not been set yet for (isize source_index = 0; source_index < count; source_index++) { - // TODO(bill): Order fields in source order not layout order Entity *f = t->Struct.fields[source_index]; lbValue tip = lb_type_info(m, f->type); i64 foffset = 0; diff --git a/src/parser.cpp b/src/parser.cpp index 1aa03033e..78120507d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -4968,7 +4968,6 @@ gb_internal bool init_parser(Parser *p) { gb_internal void destroy_parser(Parser *p) { GB_ASSERT(p != nullptr); - // TODO(bill): Fix memory leak for (AstPackage *pkg : p->packages) { for (AstFile *file : pkg->files) { destroy_ast_file(file); @@ -5012,7 +5011,6 @@ gb_internal WORKER_TASK_PROC(parser_worker_proc) { gb_internal void parser_add_file_to_process(Parser *p, AstPackage *pkg, FileInfo fi, TokenPos pos) { - // TODO(bill): Use a better allocator ImportedFile f = {pkg, fi, pos, p->file_to_process_count++}; auto wd = gb_alloc_item(permanent_allocator(), ParserWorkerData); wd->parser = p; diff --git a/src/types.cpp b/src/types.cpp index 847aea9f3..67f42adca 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -143,6 +143,7 @@ struct TypeStruct { Type * soa_elem; i32 soa_count; StructSoaKind soa_kind; + BlockingMutex mutex; // for settings offsets bool is_polymorphic; bool are_offsets_set : 1; @@ -244,6 +245,7 @@ struct TypeProc { TYPE_KIND(Tuple, struct { \ Slice variables; /* Entity_Variable */ \ i64 * offsets; \ + BlockingMutex mutex; /* for settings offsets */ \ bool are_offsets_being_processed; \ bool are_offsets_set; \ bool is_packed; \ @@ -821,6 +823,9 @@ gb_internal void type_path_pop(TypePath *tp) { #define FAILURE_ALIGNMENT 0 gb_internal bool type_ptr_set_update(PtrSet *s, Type *t) { + if (t == nullptr) { + return true; + } if (ptr_set_exists(s, t)) { return true; } @@ -829,13 +834,17 @@ gb_internal bool type_ptr_set_update(PtrSet *s, Type *t) { } gb_internal bool type_ptr_set_exists(PtrSet *s, Type *t) { + if (t == nullptr) { + return true; + } + if (ptr_set_exists(s, t)) { return true; } // TODO(bill, 2019-10-05): This is very slow and it's probably a lot // faster to cache types correctly - for (Type *f : *s) { + for (Type *f : *s) if (f->kind == t->kind) { if (are_types_identical(t, f)) { ptr_set_add(s, t); return true; @@ -2666,7 +2675,6 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple x->Struct.soa_kind == y->Struct.soa_kind && x->Struct.soa_count == y->Struct.soa_count && are_types_identical(x->Struct.soa_elem, y->Struct.soa_elem)) { - // TODO(bill); Fix the custom alignment rule for_array(i, x->Struct.fields) { Entity *xf = x->Struct.fields[i]; Entity *yf = y->Struct.fields[i]; @@ -2807,7 +2815,6 @@ gb_internal i64 union_tag_size(Type *u) { return 0; } - // TODO(bill): Is this an okay approach? i64 max_align = 1; if (u->Union.variants.count < 1ull<<8) { @@ -2817,7 +2824,7 @@ gb_internal i64 union_tag_size(Type *u) { } else if (u->Union.variants.count < 1ull<<32) { max_align = 4; } else { - GB_PANIC("how many variants do you have?!"); + compiler_error("how many variants do you have?! %lld", cast(long long)u->Union.variants.count); } for_array(i, u->Union.variants) { @@ -3136,8 +3143,6 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name switch (type->Basic.kind) { case Basic_any: { #if 1 - // IMPORTANT TODO(bill): Should these members be available to should I only allow them with - // `Raw_Any` type? String data_str = str_lit("data"); String id_str = str_lit("id"); gb_local_persist Entity *entity__any_data = alloc_entity_field(nullptr, make_token_ident(data_str), t_rawptr, false, 0); @@ -3663,10 +3668,9 @@ gb_internal i64 *type_set_offsets_of(Slice const &fields, bool is_pack } gb_internal bool type_set_offsets(Type *t) { - MUTEX_GUARD(&g_type_mutex); // TODO(bill): only per struct - t = base_type(t); if (t->kind == Type_Struct) { + MUTEX_GUARD(&t->Struct.mutex); if (!t->Struct.are_offsets_set) { t->Struct.are_offsets_being_processed = true; t->Struct.offsets = type_set_offsets_of(t->Struct.fields, t->Struct.is_packed, t->Struct.is_raw_union); @@ -3675,6 +3679,7 @@ gb_internal bool type_set_offsets(Type *t) { return true; } } else if (is_type_tuple(t)) { + MUTEX_GUARD(&t->Tuple.mutex); if (!t->Tuple.are_offsets_set) { t->Tuple.are_offsets_being_processed = true; t->Tuple.offsets = type_set_offsets_of(t->Tuple.variables, t->Tuple.is_packed, false); @@ -3849,7 +3854,6 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) { max = size; } } - // TODO(bill): Is this how it should work? return align_formula(max, align); } else { i64 count = 0, size = 0, align = 0; -- cgit v1.2.3 From 985e4eed6070995de854ed4b84981bbb89a81c45 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 4 Aug 2023 16:00:10 +0100 Subject: Fix #2697 --- src/types.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/types.cpp') diff --git a/src/types.cpp b/src/types.cpp index 3d865c713..a4856f767 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -845,7 +845,7 @@ gb_internal bool type_ptr_set_exists(PtrSet *s, Type *t) { // TODO(bill, 2019-10-05): This is very slow and it's probably a lot // faster to cache types correctly - for (Type *f : *s) if (f->kind == t->kind) { + for (Type *f : *s) { if (are_types_identical(t, f)) { ptr_set_add(s, t); return true; -- cgit v1.2.3 From c91898a8889604617140ad15c70f4d68494fa0a1 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 5 Aug 2023 16:05:39 +0100 Subject: Remove #relative slices; Replace with #relative multi-pointers --- core/encoding/json/marshal.odin | 2 +- core/fmt/fmt.odin | 27 +---- core/odin/doc-format/doc_format.odin | 50 ++++----- core/reflect/reflect.odin | 119 ++++++++++---------- core/reflect/types.odin | 15 ++- core/runtime/core.odin | 10 +- core/runtime/print.odin | 4 +- src/check_builtin.cpp | 2 +- src/check_expr.cpp | 43 ++++---- src/check_type.cpp | 8 +- src/checker.cpp | 16 +-- src/docs_format.cpp | 50 ++++----- src/docs_writer.cpp | 8 +- src/error.cpp | 4 +- src/llvm_backend.hpp | 1 - src/llvm_backend_debug.cpp | 17 +-- src/llvm_backend_expr.cpp | 39 ++++--- src/llvm_backend_general.cpp | 203 +++++++++++++++-------------------- src/llvm_backend_proc.cpp | 4 +- src/llvm_backend_type.cpp | 12 ++- src/llvm_backend_utility.cpp | 7 +- src/parser.cpp | 6 +- src/tilde_builtin.cpp | 4 - src/tilde_const.cpp | 6 +- src/tilde_debug.cpp | 16 +-- src/tilde_expr.cpp | 32 +++--- src/tilde_stmt.cpp | 15 --- src/tilde_type_info.cpp | 46 ++++---- src/types.cpp | 55 +++++----- 29 files changed, 368 insertions(+), 453 deletions(-) (limited to 'src/types.cpp') diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index d25015ac7..77a5bf8df 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -207,7 +207,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Relative_Pointer: return .Unsupported_Type - case runtime.Type_Info_Relative_Slice: + case runtime.Type_Info_Relative_Multi_Pointer: return .Unsupported_Type case runtime.Type_Info_Matrix: diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index e64b621bf..b380cac18 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -2535,32 +2535,11 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { fmt_value(fi, absolute_ptr, verb) - case runtime.Type_Info_Relative_Slice: + case runtime.Type_Info_Relative_Multi_Pointer: ptr := reflect.relative_pointer_to_absolute_raw(v.data, info.base_integer.id) + absolute_ptr := any{ptr, info.pointer.id} - if verb == 'p' { - fmt_pointer(fi, ptr, 'p') - } else if ptr == nil { - io.write_string(fi.writer, "[]", &fi.n) - } else { - len_ptr := uintptr(v.data) + uintptr(info.base_integer.size) - len_any := any{rawptr(len_ptr), info.base_integer.id} - len, _ := reflect.as_int(len_any) - slice_type := reflect.type_info_base(info.slice).variant.(runtime.Type_Info_Slice) - - fi.record_level += 1 - defer fi.record_level -= 1 - - io.write_byte(fi.writer, '[', &fi.n) - defer io.write_byte(fi.writer, ']', &fi.n) - - for i in 0.. 0 { io.write_string(fi.writer, ", ", &fi.n) } - - data := uintptr(ptr) + uintptr(i*slice_type.elem_size) - fmt_arg(fi, any{rawptr(data), slice_type.elem.id}, verb) - } - } + fmt_value(fi, absolute_ptr, verb) case runtime.Type_Info_Matrix: fmt_matrix(fi, v, verb, info) diff --git a/core/odin/doc-format/doc_format.odin b/core/odin/doc-format/doc_format.odin index 895fcf70d..d22dafd27 100644 --- a/core/odin/doc-format/doc_format.odin +++ b/core/odin/doc-format/doc_format.odin @@ -162,31 +162,31 @@ Attribute :: struct { } Type_Kind :: enum u32le { - Invalid = 0, - Basic = 1, - Named = 2, - Generic = 3, - Pointer = 4, - Array = 5, - Enumerated_Array = 6, - Slice = 7, - Dynamic_Array = 8, - Map = 9, - Struct = 10, - Union = 11, - Enum = 12, - Tuple = 13, - Proc = 14, - Bit_Set = 15, - Simd_Vector = 16, - SOA_Struct_Fixed = 17, - SOA_Struct_Slice = 18, - SOA_Struct_Dynamic = 19, - Relative_Pointer = 20, - Relative_Slice = 21, - Multi_Pointer = 22, - Matrix = 23, - Soa_Pointer = 24, + Invalid = 0, + Basic = 1, + Named = 2, + Generic = 3, + Pointer = 4, + Array = 5, + Enumerated_Array = 6, + Slice = 7, + Dynamic_Array = 8, + Map = 9, + Struct = 10, + Union = 11, + Enum = 12, + Tuple = 13, + Proc = 14, + Bit_Set = 15, + Simd_Vector = 16, + SOA_Struct_Fixed = 17, + SOA_Struct_Slice = 18, + SOA_Struct_Dynamic = 19, + Relative_Pointer = 20, + Relative_Multi_Pointer = 21, + Multi_Pointer = 22, + Matrix = 23, + Soa_Pointer = 24, } Type_Elems_Cap :: 4 diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index a88557e0e..24a826f04 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -8,35 +8,35 @@ _ :: intrinsics Type_Info :: runtime.Type_Info -Type_Info_Named :: runtime.Type_Info_Named -Type_Info_Integer :: runtime.Type_Info_Integer -Type_Info_Rune :: runtime.Type_Info_Rune -Type_Info_Float :: runtime.Type_Info_Float -Type_Info_Complex :: runtime.Type_Info_Complex -Type_Info_Quaternion :: runtime.Type_Info_Quaternion -Type_Info_String :: runtime.Type_Info_String -Type_Info_Boolean :: runtime.Type_Info_Boolean -Type_Info_Any :: runtime.Type_Info_Any -Type_Info_Type_Id :: runtime.Type_Info_Type_Id -Type_Info_Pointer :: runtime.Type_Info_Pointer -Type_Info_Multi_Pointer :: runtime.Type_Info_Multi_Pointer -Type_Info_Procedure :: runtime.Type_Info_Procedure -Type_Info_Array :: runtime.Type_Info_Array -Type_Info_Enumerated_Array :: runtime.Type_Info_Enumerated_Array -Type_Info_Dynamic_Array :: runtime.Type_Info_Dynamic_Array -Type_Info_Slice :: runtime.Type_Info_Slice -Type_Info_Parameters :: runtime.Type_Info_Parameters -Type_Info_Tuple :: runtime.Type_Info_Parameters -Type_Info_Struct :: runtime.Type_Info_Struct -Type_Info_Union :: runtime.Type_Info_Union -Type_Info_Enum :: runtime.Type_Info_Enum -Type_Info_Map :: runtime.Type_Info_Map -Type_Info_Bit_Set :: runtime.Type_Info_Bit_Set -Type_Info_Simd_Vector :: runtime.Type_Info_Simd_Vector -Type_Info_Relative_Pointer :: runtime.Type_Info_Relative_Pointer -Type_Info_Relative_Slice :: runtime.Type_Info_Relative_Slice -Type_Info_Matrix :: runtime.Type_Info_Matrix -Type_Info_Soa_Pointer :: runtime.Type_Info_Soa_Pointer +Type_Info_Named :: runtime.Type_Info_Named +Type_Info_Integer :: runtime.Type_Info_Integer +Type_Info_Rune :: runtime.Type_Info_Rune +Type_Info_Float :: runtime.Type_Info_Float +Type_Info_Complex :: runtime.Type_Info_Complex +Type_Info_Quaternion :: runtime.Type_Info_Quaternion +Type_Info_String :: runtime.Type_Info_String +Type_Info_Boolean :: runtime.Type_Info_Boolean +Type_Info_Any :: runtime.Type_Info_Any +Type_Info_Type_Id :: runtime.Type_Info_Type_Id +Type_Info_Pointer :: runtime.Type_Info_Pointer +Type_Info_Multi_Pointer :: runtime.Type_Info_Multi_Pointer +Type_Info_Procedure :: runtime.Type_Info_Procedure +Type_Info_Array :: runtime.Type_Info_Array +Type_Info_Enumerated_Array :: runtime.Type_Info_Enumerated_Array +Type_Info_Dynamic_Array :: runtime.Type_Info_Dynamic_Array +Type_Info_Slice :: runtime.Type_Info_Slice +Type_Info_Parameters :: runtime.Type_Info_Parameters +Type_Info_Tuple :: runtime.Type_Info_Parameters +Type_Info_Struct :: runtime.Type_Info_Struct +Type_Info_Union :: runtime.Type_Info_Union +Type_Info_Enum :: runtime.Type_Info_Enum +Type_Info_Map :: runtime.Type_Info_Map +Type_Info_Bit_Set :: runtime.Type_Info_Bit_Set +Type_Info_Simd_Vector :: runtime.Type_Info_Simd_Vector +Type_Info_Relative_Pointer :: runtime.Type_Info_Relative_Pointer +Type_Info_Relative_Multi_Pointer :: runtime.Type_Info_Relative_Multi_Pointer +Type_Info_Matrix :: runtime.Type_Info_Matrix +Type_Info_Soa_Pointer :: runtime.Type_Info_Soa_Pointer Type_Info_Enum_Value :: runtime.Type_Info_Enum_Value @@ -69,7 +69,7 @@ Type_Kind :: enum { Bit_Set, Simd_Vector, Relative_Pointer, - Relative_Slice, + Relative_Multi_Pointer, Matrix, Soa_Pointer, } @@ -80,34 +80,34 @@ type_kind :: proc(T: typeid) -> Type_Kind { ti := type_info_of(T) if ti != nil { switch _ in ti.variant { - case Type_Info_Named: return .Named - case Type_Info_Integer: return .Integer - case Type_Info_Rune: return .Rune - case Type_Info_Float: return .Float - case Type_Info_Complex: return .Complex - case Type_Info_Quaternion: return .Quaternion - case Type_Info_String: return .String - case Type_Info_Boolean: return .Boolean - case Type_Info_Any: return .Any - case Type_Info_Type_Id: return .Type_Id - case Type_Info_Pointer: return .Pointer - case Type_Info_Multi_Pointer: return .Multi_Pointer - case Type_Info_Procedure: return .Procedure - case Type_Info_Array: return .Array - case Type_Info_Enumerated_Array: return .Enumerated_Array - case Type_Info_Dynamic_Array: return .Dynamic_Array - case Type_Info_Slice: return .Slice - case Type_Info_Parameters: return .Tuple - case Type_Info_Struct: return .Struct - case Type_Info_Union: return .Union - case Type_Info_Enum: return .Enum - case Type_Info_Map: return .Map - case Type_Info_Bit_Set: return .Bit_Set - case Type_Info_Simd_Vector: return .Simd_Vector - case Type_Info_Relative_Pointer: return .Relative_Pointer - case Type_Info_Relative_Slice: return .Relative_Slice - case Type_Info_Matrix: return .Matrix - case Type_Info_Soa_Pointer: return .Soa_Pointer + case Type_Info_Named: return .Named + case Type_Info_Integer: return .Integer + case Type_Info_Rune: return .Rune + case Type_Info_Float: return .Float + case Type_Info_Complex: return .Complex + case Type_Info_Quaternion: return .Quaternion + case Type_Info_String: return .String + case Type_Info_Boolean: return .Boolean + case Type_Info_Any: return .Any + case Type_Info_Type_Id: return .Type_Id + case Type_Info_Pointer: return .Pointer + case Type_Info_Multi_Pointer: return .Multi_Pointer + case Type_Info_Procedure: return .Procedure + case Type_Info_Array: return .Array + case Type_Info_Enumerated_Array: return .Enumerated_Array + case Type_Info_Dynamic_Array: return .Dynamic_Array + case Type_Info_Slice: return .Slice + case Type_Info_Parameters: return .Tuple + case Type_Info_Struct: return .Struct + case Type_Info_Union: return .Union + case Type_Info_Enum: return .Enum + case Type_Info_Map: return .Map + case Type_Info_Bit_Set: return .Bit_Set + case Type_Info_Simd_Vector: return .Simd_Vector + case Type_Info_Relative_Pointer: return .Relative_Pointer + case Type_Info_Relative_Multi_Pointer: return .Relative_Multi_Pointer + case Type_Info_Matrix: return .Matrix + case Type_Info_Soa_Pointer: return .Soa_Pointer } } @@ -1457,8 +1457,6 @@ equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_ return equal(va, vb, including_indirect_array_recursion, recursion_level+1) case Type_Info_Map: return false - case Type_Info_Relative_Slice: - return false case Type_Info_Boolean, Type_Info_Integer, @@ -1474,6 +1472,7 @@ equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_ Type_Info_Enum, Type_Info_Simd_Vector, Type_Info_Relative_Pointer, + Type_Info_Relative_Multi_Pointer, Type_Info_Soa_Pointer, Type_Info_Matrix: return runtime.memory_compare(a.data, b.data, t.size) == 0 diff --git a/core/reflect/types.odin b/core/reflect/types.odin index cad9b1f66..21f75580c 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -165,9 +165,9 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { y := b.variant.(Type_Info_Relative_Pointer) or_return return x.base_integer == y.base_integer && x.pointer == y.pointer - case Type_Info_Relative_Slice: - y := b.variant.(Type_Info_Relative_Slice) or_return - return x.base_integer == y.base_integer && x.slice == y.slice + case Type_Info_Relative_Multi_Pointer: + y := b.variant.(Type_Info_Relative_Multi_Pointer) or_return + return x.base_integer == y.base_integer && x.pointer == y.pointer case Type_Info_Matrix: y := b.variant.(Type_Info_Matrix) or_return @@ -383,9 +383,9 @@ is_relative_pointer :: proc(info: ^Type_Info) -> bool { return ok } @(require_results) -is_relative_slice :: proc(info: ^Type_Info) -> bool { +is_relative_multi_pointer :: proc(info: ^Type_Info) -> bool { if info == nil { return false } - _, ok := type_info_base(info).variant.(Type_Info_Relative_Slice) + _, ok := type_info_base(info).variant.(Type_Info_Relative_Multi_Pointer) return ok } @@ -395,7 +395,6 @@ is_relative_slice :: proc(info: ^Type_Info) -> bool { - write_typeid_builder :: proc(buf: ^strings.Builder, id: typeid, n_written: ^int = nil) -> (n: int, err: io.Error) { return write_type_writer(strings.to_writer(buf), type_info_of(id)) } @@ -652,11 +651,11 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) - io.write_string(w, ") ", &n) or_return write_type(w, info.pointer, &n) or_return - case Type_Info_Relative_Slice: + case Type_Info_Relative_Multi_Pointer: io.write_string(w, "#relative(", &n) or_return write_type(w, info.base_integer, &n) or_return io.write_string(w, ") ", &n) or_return - write_type(w, info.slice, &n) or_return + write_type(w, info.pointer, &n) or_return case Type_Info_Matrix: io.write_string(w, "matrix[", &n) or_return diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 83504c9ee..f76c77581 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -162,11 +162,11 @@ Type_Info_Simd_Vector :: struct { count: int, } Type_Info_Relative_Pointer :: struct { - pointer: ^Type_Info, + pointer: ^Type_Info, // ^T base_integer: ^Type_Info, } -Type_Info_Relative_Slice :: struct { - slice: ^Type_Info, +Type_Info_Relative_Multi_Pointer :: struct { + pointer: ^Type_Info, // [^]T base_integer: ^Type_Info, } Type_Info_Matrix :: struct { @@ -219,7 +219,7 @@ Type_Info :: struct { Type_Info_Bit_Set, Type_Info_Simd_Vector, Type_Info_Relative_Pointer, - Type_Info_Relative_Slice, + Type_Info_Relative_Multi_Pointer, Type_Info_Matrix, Type_Info_Soa_Pointer, }, @@ -252,7 +252,7 @@ Typeid_Kind :: enum u8 { Bit_Set, Simd_Vector, Relative_Pointer, - Relative_Slice, + Relative_Multi_Pointer, Matrix, } #assert(len(Typeid_Kind) < 32) diff --git a/core/runtime/print.odin b/core/runtime/print.odin index 035d47f15..6b1555f52 100644 --- a/core/runtime/print.odin +++ b/core/runtime/print.odin @@ -471,11 +471,11 @@ print_type :: proc "contextless" (ti: ^Type_Info) { print_string(") ") print_type(info.pointer) - case Type_Info_Relative_Slice: + case Type_Info_Relative_Multi_Pointer: print_string("#relative(") print_type(info.base_integer) print_string(") ") - print_type(info.slice) + print_type(info.pointer) case Type_Info_Matrix: print_string("matrix[") diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 7f9f4ab13..2e65c5750 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1748,7 +1748,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As mode = Addressing_Constant; value = exact_value_i64(at->EnumeratedArray.count); type = t_untyped_integer; - } else if ((is_type_slice(op_type) || is_type_relative_slice(op_type)) && id == BuiltinProc_len) { + } else if (is_type_slice(op_type) && id == BuiltinProc_len) { mode = Addressing_Value; } else if (is_type_dynamic_array(op_type)) { mode = Addressing_Value; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 5b6e8be3d..14a4eebc8 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -856,8 +856,8 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand } } - if (is_type_relative_slice(dst)) { - i64 score = check_distance_between_types(c, operand, dst->RelativeSlice.slice_type); + if (is_type_relative_multi_pointer(dst)) { + i64 score = check_distance_between_types(c, operand, dst->RelativeMultiPointer.pointer_type); if (score >= 0) { return score+2; } @@ -1005,8 +1005,8 @@ gb_internal AstPackage *get_package_of_type(Type *type) { case Type_RelativePointer: type = type->RelativePointer.pointer_type; continue; - case Type_RelativeSlice: - type = type->RelativeSlice.slice_type; + case Type_RelativeMultiPointer: + type = type->RelativeMultiPointer.pointer_type; continue; } return nullptr; @@ -7366,11 +7366,11 @@ gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 } return true; - case Type_RelativeSlice: + case Type_RelativeMultiPointer: { - Type *slice_type = base_type(t->RelativeSlice.slice_type); - GB_ASSERT(slice_type->kind == Type_Slice); - o->type = slice_type->Slice.elem; + Type *pointer_type = base_type(t->RelativeMultiPointer.pointer_type); + GB_ASSERT(pointer_type->kind == Type_MultiPointer); + o->type = pointer_type->MultiPointer.elem; if (o->mode != Addressing_Constant) { o->mode = Addressing_Variable; } @@ -9502,14 +9502,14 @@ gb_internal ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, if (is_const) { if (is_type_array(t)) { - // OKay + // Okay } else if (is_type_slice(t)) { // Okay } else if (is_type_enumerated_array(t)) { // Okay } else if (is_type_string(t)) { // Okay - } else if (is_type_relative_slice(t)) { + } else if (is_type_relative_multi_pointer(t)) { // Okay } else if (is_type_matrix(t)) { // Okay @@ -9647,17 +9647,9 @@ gb_internal ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, } break; - case Type_RelativeSlice: + case Type_RelativeMultiPointer: valid = true; - o->type = t->RelativeSlice.slice_type; - if (o->mode != Addressing_Variable) { - gbString str = expr_to_string(node); - error(node, "Cannot relative slice '%s', as value is not addressable", str); - gb_string_free(str); - o->mode = Addressing_Invalid; - o->expr = node; - return kind; - } + o->type = type_deref(o->type); break; case Type_EnumeratedArray: @@ -9736,8 +9728,19 @@ gb_internal ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, x[i:n] -> []T */ o->type = alloc_type_slice(t->MultiPointer.elem); + } else if (t->kind == Type_RelativeMultiPointer && se->high != nullptr) { + /* + x[:] -> [^]T + x[i:] -> [^]T + x[:n] -> []T + x[i:n] -> []T + */ + Type *pointer_type = base_type(t->RelativeMultiPointer.pointer_type); + GB_ASSERT(pointer_type->kind == Type_MultiPointer); + o->type = alloc_type_slice(pointer_type->MultiPointer.elem); } + o->mode = Addressing_Value; if (is_type_string(t) && max_count >= 0) { diff --git a/src/check_type.cpp b/src/check_type.cpp index 4704f8b9b..cae3ba22e 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2778,16 +2778,16 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T Type *relative_type = nullptr; Type *base_type = check_type(ctx, rt->type); - if (!is_type_pointer(base_type) && !is_type_slice(base_type)) { - error(rt->type, "#relative types can only be a pointer or slice"); + if (!is_type_pointer(base_type) && !is_type_multi_pointer(base_type)) { + error(rt->type, "#relative types can only be a pointer or multi-pointer"); relative_type = base_type; } else if (base_integer == nullptr) { relative_type = base_type; } else { if (is_type_pointer(base_type)) { relative_type = alloc_type_relative_pointer(base_type, base_integer); - } else if (is_type_slice(base_type)) { - relative_type = alloc_type_relative_slice(base_type, base_integer); + } else if (is_type_multi_pointer(base_type)) { + relative_type = alloc_type_relative_multi_pointer(base_type, base_integer); } } GB_ASSERT(relative_type != nullptr); diff --git a/src/checker.cpp b/src/checker.cpp index e1860b1fe..7fa7a9c36 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1969,9 +1969,9 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { add_type_info_type_internal(c, bt->RelativePointer.base_integer); break; - case Type_RelativeSlice: - add_type_info_type_internal(c, bt->RelativeSlice.slice_type); - add_type_info_type_internal(c, bt->RelativeSlice.base_integer); + case Type_RelativeMultiPointer: + add_type_info_type_internal(c, bt->RelativeMultiPointer.pointer_type); + add_type_info_type_internal(c, bt->RelativeMultiPointer.base_integer); break; case Type_Matrix: @@ -2210,9 +2210,9 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { add_min_dep_type_info(c, bt->RelativePointer.base_integer); break; - case Type_RelativeSlice: - add_min_dep_type_info(c, bt->RelativeSlice.slice_type); - add_min_dep_type_info(c, bt->RelativeSlice.base_integer); + case Type_RelativeMultiPointer: + add_min_dep_type_info(c, bt->RelativeMultiPointer.pointer_type); + add_min_dep_type_info(c, bt->RelativeMultiPointer.base_integer); break; case Type_Matrix: @@ -2800,7 +2800,7 @@ gb_internal void init_core_type_info(Checker *c) { t_type_info_bit_set = find_core_type(c, str_lit("Type_Info_Bit_Set")); t_type_info_simd_vector = find_core_type(c, str_lit("Type_Info_Simd_Vector")); 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_relative_multi_pointer = find_core_type(c, str_lit("Type_Info_Relative_Multi_Pointer")); 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")); @@ -2829,7 +2829,7 @@ gb_internal void init_core_type_info(Checker *c) { t_type_info_bit_set_ptr = alloc_type_pointer(t_type_info_bit_set); t_type_info_simd_vector_ptr = alloc_type_pointer(t_type_info_simd_vector); 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_relative_multi_pointer_ptr = alloc_type_pointer(t_type_info_relative_multi_pointer); 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); } diff --git a/src/docs_format.cpp b/src/docs_format.cpp index 34114f08e..d0bca214b 100644 --- a/src/docs_format.cpp +++ b/src/docs_format.cpp @@ -59,31 +59,31 @@ struct OdinDocPosition { }; enum OdinDocTypeKind : u32 { - OdinDocType_Invalid = 0, - OdinDocType_Basic = 1, - OdinDocType_Named = 2, - OdinDocType_Generic = 3, - OdinDocType_Pointer = 4, - OdinDocType_Array = 5, - OdinDocType_EnumeratedArray = 6, - OdinDocType_Slice = 7, - OdinDocType_DynamicArray = 8, - OdinDocType_Map = 9, - OdinDocType_Struct = 10, - OdinDocType_Union = 11, - OdinDocType_Enum = 12, - OdinDocType_Tuple = 13, - OdinDocType_Proc = 14, - OdinDocType_BitSet = 15, - OdinDocType_SimdVector = 16, - OdinDocType_SOAStructFixed = 17, - OdinDocType_SOAStructSlice = 18, - OdinDocType_SOAStructDynamic = 19, - OdinDocType_RelativePointer = 20, - OdinDocType_RelativeSlice = 21, - OdinDocType_MultiPointer = 22, - OdinDocType_Matrix = 23, - OdinDocType_SoaPointer = 24, + OdinDocType_Invalid = 0, + OdinDocType_Basic = 1, + OdinDocType_Named = 2, + OdinDocType_Generic = 3, + OdinDocType_Pointer = 4, + OdinDocType_Array = 5, + OdinDocType_EnumeratedArray = 6, + OdinDocType_Slice = 7, + OdinDocType_DynamicArray = 8, + OdinDocType_Map = 9, + OdinDocType_Struct = 10, + OdinDocType_Union = 11, + OdinDocType_Enum = 12, + OdinDocType_Tuple = 13, + OdinDocType_Proc = 14, + OdinDocType_BitSet = 15, + OdinDocType_SimdVector = 16, + OdinDocType_SOAStructFixed = 17, + OdinDocType_SOAStructSlice = 18, + OdinDocType_SOAStructDynamic = 19, + OdinDocType_RelativePointer = 20, + OdinDocType_RelativeMultiPointer = 21, + OdinDocType_MultiPointer = 22, + OdinDocType_Matrix = 23, + OdinDocType_SoaPointer = 24, }; enum OdinDocTypeFlag_Basic : u32 { diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index 2dd2f338b..6b42d2e7a 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -771,12 +771,12 @@ gb_internal OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { doc_type.types = odin_write_slice(w, types, gb_count_of(types)); } break; - case Type_RelativeSlice: - doc_type.kind = OdinDocType_RelativeSlice; + case Type_RelativeMultiPointer: + doc_type.kind = OdinDocType_RelativeMultiPointer; { OdinDocTypeIndex types[2] = {}; - types[0] = odin_doc_type(w, type->RelativeSlice.slice_type); - types[1] = odin_doc_type(w, type->RelativeSlice.base_integer); + types[0] = odin_doc_type(w, type->RelativeMultiPointer.pointer_type); + types[1] = odin_doc_type(w, type->RelativeMultiPointer.base_integer); doc_type.types = odin_write_slice(w, types, gb_count_of(types)); } break; diff --git a/src/error.cpp b/src/error.cpp index eb010eb36..6a039006b 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -411,7 +411,7 @@ gb_internal void error_line_va(char const *fmt, va_list va) { gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) { mutex_lock(&global_error_collector.mutex); - global_error_collector.count++; + global_error_collector.count.fetch_add(1); // NOTE(bill): Duplicate error, skip it if (pos.line == 0) { error_out_coloured("Error: ", TerminalStyle_Normal, TerminalColour_Red); @@ -425,7 +425,7 @@ gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_li error_out_va(fmt, va); } mutex_unlock(&global_error_collector.mutex); - if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) { + if (global_error_collector.count.load() > MAX_ERROR_COLLECTOR_COUNT()) { gb_exit(1); } } diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index e05bf8025..3178ac9db 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -69,7 +69,6 @@ enum lbAddrKind { lbAddr_SoaVariable, lbAddr_RelativePointer, - lbAddr_RelativeSlice, lbAddr_Swizzle, lbAddr_SwizzleLarge, diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index b9c6c606e..e053c5b40 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -442,19 +442,12 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { gbString name = type_to_string(type, temporary_allocator()); return LLVMDIBuilderCreateTypedef(m->debug_builder, base_integer, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type))); } + case Type_RelativeMultiPointer: { + LLVMMetadataRef base_integer = lb_debug_type(m, type->RelativeMultiPointer.base_integer); + gbString name = type_to_string(type, temporary_allocator()); + return LLVMDIBuilderCreateTypedef(m->debug_builder, base_integer, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type))); + } - case Type_RelativeSlice: - { - unsigned element_count = 0; - LLVMMetadataRef elements[2] = {}; - Type *base_integer = type->RelativeSlice.base_integer; - unsigned base_bits = cast(unsigned)(8*type_size_of(base_integer)); - elements[0] = lb_debug_struct_field(m, str_lit("data_offset"), base_integer, 0); - elements[1] = lb_debug_struct_field(m, str_lit("len"), base_integer, base_bits); - gbString name = type_to_string(type, temporary_allocator()); - return LLVMDIBuilderCreateStructType(m->debug_builder, nullptr, name, gb_string_length(name), nullptr, 0, 2*base_bits, base_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0); - } - case Type_Matrix: { LLVMMetadataRef subscripts[1] = {}; subscripts[0] = LLVMDIBuilderGetOrCreateSubrange(m->debug_builder, diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index 5e6831fc2..33768cc12 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -2863,7 +2863,6 @@ gb_internal lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) { ast_node(ue, UnaryExpr, expr); auto tv = type_and_value_of_expr(expr); - Ast *ue_expr = unparen_expr(ue->expr); if (ue_expr->kind == Ast_IndexExpr && tv.mode == Addressing_OptionalOkPtr && is_type_tuple(tv.type)) { Type *tuple = tv.type; @@ -3803,25 +3802,32 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) { lbValue v = {}; LLVMValueRef indices[1] = {index.value}; - v.value = LLVMBuildGEP2(p->builder, lb_type(p->module, t->MultiPointer.elem), multi_ptr.value, indices, 1, "foo"); + v.value = LLVMBuildGEP2(p->builder, lb_type(p->module, t->MultiPointer.elem), multi_ptr.value, indices, 1, ""); v.type = alloc_type_pointer(t->MultiPointer.elem); return lb_addr(v); } - case Type_RelativeSlice: { - lbAddr slice_addr = {}; + case Type_RelativeMultiPointer: { + lbAddr rel_ptr_addr = {}; if (deref) { - slice_addr = lb_addr(lb_build_expr(p, ie->expr)); + lbValue rel_ptr_ptr = lb_build_expr(p, ie->expr); + rel_ptr_addr = lb_addr(rel_ptr_ptr); } else { - slice_addr = lb_build_addr(p, ie->expr); + rel_ptr_addr = lb_build_addr(p, ie->expr); } - lbValue slice = lb_addr_load(p, slice_addr); + lbValue rel_ptr = lb_relative_pointer_to_pointer(p, rel_ptr_addr); - lbValue elem = lb_slice_elem(p, slice); - lbValue index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int); - lbValue len = lb_slice_len(p, slice); - lb_emit_bounds_check(p, ast_token(ie->index), index, len); - lbValue v = lb_emit_ptr_offset(p, elem, index); + lbValue index = lb_build_expr(p, ie->index); + index = lb_emit_conv(p, index, t_int); + lbValue v = {}; + + Type *pointer_type = base_type(t->RelativeMultiPointer.pointer_type); + GB_ASSERT(pointer_type->kind == Type_MultiPointer); + Type *elem = pointer_type->MultiPointer.elem; + + LLVMValueRef indices[1] = {index.value}; + v.value = LLVMBuildGEP2(p->builder, lb_type(p->module, elem), rel_ptr.value, indices, 1, ""); + v.type = alloc_type_pointer(elem); return lb_addr(v); } @@ -3925,8 +3931,11 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) { return slice; } - case Type_RelativeSlice: - GB_PANIC("TODO(bill): Type_RelativeSlice should be handled above already on the lb_addr_load"); + case Type_RelativePointer: + GB_PANIC("TODO(bill): Type_RelativePointer should be handled above already on the lb_addr_load"); + break; + case Type_RelativeMultiPointer: + GB_PANIC("TODO(bill): Type_RelativeMultiPointer should be handled above already on the lb_addr_load"); break; case Type_DynamicArray: { @@ -3996,7 +4005,7 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) { } case Type_Basic: { - GB_ASSERT(type == t_string); + GB_ASSERT_MSG(type == t_string, "got %s", type_to_string(type)); lbValue len = lb_string_len(p, base); if (high.value == nullptr) high = len; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index cd8041661..5dfc7aff9 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -349,9 +349,10 @@ gb_internal lbAddr lb_addr(lbValue addr) { if (addr.type != nullptr && is_type_relative_pointer(type_deref(addr.type))) { GB_ASSERT(is_type_pointer(addr.type)); v.kind = lbAddr_RelativePointer; - } else if (addr.type != nullptr && is_type_relative_slice(type_deref(addr.type))) { - GB_ASSERT(is_type_pointer(addr.type)); - v.kind = lbAddr_RelativeSlice; + } else if (addr.type != nullptr && is_type_relative_multi_pointer(type_deref(addr.type))) { + GB_ASSERT(is_type_pointer(addr.type) || + is_type_multi_pointer(addr.type)); + v.kind = lbAddr_RelativePointer; } return v; } @@ -424,6 +425,43 @@ gb_internal Type *lb_addr_type(lbAddr const &addr) { return type_deref(addr.addr.type); } + +gb_internal lbValue lb_relative_pointer_to_pointer(lbProcedure *p, lbAddr const &addr) { + GB_ASSERT(addr.kind == lbAddr_RelativePointer); + + Type *t = base_type(lb_addr_type(addr)); + GB_ASSERT(is_type_relative_pointer(t) || is_type_relative_multi_pointer(t)); + + Type *pointer_type = nullptr; + Type *base_integer = nullptr; + if (t->kind == Type_RelativePointer) { + pointer_type = t->RelativePointer.pointer_type; + base_integer = t->RelativePointer.base_integer; + } else if (t->kind == Type_RelativeMultiPointer) { + pointer_type = t->RelativeMultiPointer.pointer_type; + base_integer = t->RelativeMultiPointer.base_integer; + } + + lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr); + lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(base_integer)); + offset = lb_emit_load(p, offset); + + if (!is_type_unsigned(base_integer)) { + offset = lb_emit_conv(p, offset, t_i64); + } + offset = lb_emit_conv(p, offset, t_uintptr); + lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr); + absolute_ptr = lb_emit_conv(p, absolute_ptr, pointer_type); + + lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, base_integer)); + + // NOTE(bill): nil check + lbValue nil_ptr = lb_const_nil(p->module, pointer_type); + lbValue final_ptr = lb_emit_select(p, cond, nil_ptr, absolute_ptr); + return final_ptr; +} + + gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) { if (addr.addr.value == nullptr) { GB_PANIC("Illegal addr -> nullptr"); @@ -434,28 +472,8 @@ gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) { case lbAddr_Map: return lb_internal_dynamic_map_get_ptr(p, addr.addr, addr.map.key); - case lbAddr_RelativePointer: { - Type *rel_ptr = base_type(lb_addr_type(addr)); - GB_ASSERT(rel_ptr->kind == Type_RelativePointer); - - lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr); - lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer)); - offset = lb_emit_load(p, offset); - - if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) { - offset = lb_emit_conv(p, offset, t_i64); - } - offset = lb_emit_conv(p, offset, t_uintptr); - lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr); - absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type); - - lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer)); - - // NOTE(bill): nil check - lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type); - lbValue final_ptr = lb_emit_select(p, cond, nil_ptr, absolute_ptr); - return final_ptr; - } + case lbAddr_RelativePointer: + return lb_relative_pointer_to_pointer(p, addr); case lbAddr_SoaVariable: // TODO(bill): FIX THIS HACK @@ -477,6 +495,9 @@ gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) { gb_internal lbValue lb_build_addr_ptr(lbProcedure *p, Ast *expr) { lbAddr addr = lb_build_addr(p, expr); + if (addr.kind == lbAddr_RelativePointer) { + return addr.addr; + } return lb_addr_get_ptr(p, addr); } @@ -685,9 +706,20 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { if (addr.kind == lbAddr_RelativePointer) { Type *rel_ptr = base_type(lb_addr_type(addr)); - GB_ASSERT(rel_ptr->kind == Type_RelativePointer); + GB_ASSERT(rel_ptr->kind == Type_RelativePointer || + rel_ptr->kind == Type_RelativeMultiPointer); + Type *pointer_type = nullptr; + Type *base_integer = nullptr; - value = lb_emit_conv(p, value, rel_ptr->RelativePointer.pointer_type); + if (rel_ptr->kind == Type_RelativePointer) { + pointer_type = rel_ptr->RelativePointer.pointer_type; + base_integer = rel_ptr->RelativePointer.base_integer; + } else if (rel_ptr->kind == Type_RelativeMultiPointer) { + pointer_type = rel_ptr->RelativeMultiPointer.pointer_type; + base_integer = rel_ptr->RelativeMultiPointer.base_integer; + } + + value = lb_emit_conv(p, value, pointer_type); GB_ASSERT(is_type_pointer(addr.addr.type)); lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr); @@ -696,54 +728,20 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, ""); offset.type = t_uintptr; - if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) { + if (!is_type_unsigned(base_integer)) { offset = lb_emit_conv(p, offset, t_i64); } - offset = lb_emit_conv(p, offset, rel_ptr->RelativePointer.base_integer); + offset = lb_emit_conv(p, offset, base_integer); - lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer)); + lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(base_integer)); offset = lb_emit_select(p, lb_emit_comp(p, Token_CmpEq, val_ptr, lb_const_nil(p->module, t_uintptr)), - lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer), + lb_const_nil(p->module, base_integer), offset ); LLVMBuildStore(p->builder, offset.value, offset_ptr.value); return; - } else if (addr.kind == lbAddr_RelativeSlice) { - Type *rel_ptr = base_type(lb_addr_type(addr)); - GB_ASSERT(rel_ptr->kind == Type_RelativeSlice); - - value = lb_emit_conv(p, value, rel_ptr->RelativeSlice.slice_type); - - GB_ASSERT(is_type_pointer(addr.addr.type)); - lbValue ptr = lb_emit_conv(p, lb_emit_struct_ep(p, addr.addr, 0), t_uintptr); - lbValue val_ptr = lb_emit_conv(p, lb_slice_elem(p, value), t_uintptr); - lbValue offset = {}; - offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, ""); - offset.type = t_uintptr; - - if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) { - offset = lb_emit_conv(p, offset, t_i64); - } - offset = lb_emit_conv(p, offset, rel_ptr->RelativePointer.base_integer); - - - lbValue offset_ptr = lb_emit_conv(p, addr.addr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer)); - offset = lb_emit_select(p, - lb_emit_comp(p, Token_CmpEq, val_ptr, lb_const_nil(p->module, t_uintptr)), - lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer), - offset - ); - LLVMBuildStore(p->builder, offset.value, offset_ptr.value); - - lbValue len = lb_slice_len(p, value); - len = lb_emit_conv(p, len, rel_ptr->RelativePointer.base_integer); - - lbValue len_ptr = lb_emit_struct_ep(p, addr.addr, 1); - LLVMBuildStore(p->builder, len.value, len_ptr.value); - - return; } else if (addr.kind == lbAddr_Map) { lb_internal_dynamic_map_set(p, addr.addr, addr.map.type, addr.map.key, value, p->curr_stmt); return; @@ -1020,67 +1018,43 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) { if (addr.kind == lbAddr_RelativePointer) { Type *rel_ptr = base_type(lb_addr_type(addr)); - GB_ASSERT(rel_ptr->kind == Type_RelativePointer); + Type *base_integer = nullptr; + Type *pointer_type = nullptr; + GB_ASSERT(rel_ptr->kind == Type_RelativePointer || + rel_ptr->kind == Type_RelativeMultiPointer); + + if (rel_ptr->kind == Type_RelativePointer) { + base_integer = rel_ptr->RelativePointer.base_integer; + pointer_type = rel_ptr->RelativePointer.pointer_type; + } else if (rel_ptr->kind == Type_RelativeMultiPointer) { + base_integer = rel_ptr->RelativeMultiPointer.base_integer; + pointer_type = rel_ptr->RelativeMultiPointer.pointer_type; + } lbValue ptr = lb_emit_conv(p, addr.addr, t_uintptr); - lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(rel_ptr->RelativePointer.base_integer)); + lbValue offset = lb_emit_conv(p, ptr, alloc_type_pointer(base_integer)); offset = lb_emit_load(p, offset); - if (!is_type_unsigned(rel_ptr->RelativePointer.base_integer)) { + if (!is_type_unsigned(base_integer)) { offset = lb_emit_conv(p, offset, t_i64); } offset = lb_emit_conv(p, offset, t_uintptr); lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr); - absolute_ptr = lb_emit_conv(p, absolute_ptr, rel_ptr->RelativePointer.pointer_type); + absolute_ptr = lb_emit_conv(p, absolute_ptr, pointer_type); - lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativePointer.base_integer)); + lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, base_integer)); // NOTE(bill): nil check - lbValue nil_ptr = lb_const_nil(p->module, rel_ptr->RelativePointer.pointer_type); + lbValue nil_ptr = lb_const_nil(p->module, pointer_type); lbValue final_ptr = {}; final_ptr.type = absolute_ptr.type; final_ptr.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, ""); - return lb_emit_load(p, final_ptr); - - } else if (addr.kind == lbAddr_RelativeSlice) { - Type *rel_ptr = base_type(lb_addr_type(addr)); - GB_ASSERT(rel_ptr->kind == Type_RelativeSlice); - - lbValue offset_ptr = lb_emit_struct_ep(p, addr.addr, 0); - lbValue ptr = lb_emit_conv(p, offset_ptr, t_uintptr); - lbValue offset = lb_emit_load(p, offset_ptr); - - - if (!is_type_unsigned(rel_ptr->RelativeSlice.base_integer)) { - offset = lb_emit_conv(p, offset, t_i64); + if (rel_ptr->kind == Type_RelativeMultiPointer) { + return final_ptr; } - offset = lb_emit_conv(p, offset, t_uintptr); - lbValue absolute_ptr = lb_emit_arith(p, Token_Add, ptr, offset, t_uintptr); - - Type *slice_type = base_type(rel_ptr->RelativeSlice.slice_type); - GB_ASSERT(rel_ptr->RelativeSlice.slice_type->kind == Type_Slice); - Type *slice_elem = slice_type->Slice.elem; - Type *slice_elem_ptr = alloc_type_pointer(slice_elem); - - absolute_ptr = lb_emit_conv(p, absolute_ptr, slice_elem_ptr); - - lbValue cond = lb_emit_comp(p, Token_CmpEq, offset, lb_const_nil(p->module, rel_ptr->RelativeSlice.base_integer)); - - // NOTE(bill): nil check - lbValue nil_ptr = lb_const_nil(p->module, slice_elem_ptr); - lbValue data = {}; - data.type = absolute_ptr.type; - data.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, ""); - - lbValue len = lb_emit_load(p, lb_emit_struct_ep(p, addr.addr, 1)); - len = lb_emit_conv(p, len, t_int); - - lbAddr slice = lb_add_local_generated(p, slice_type, false); - lb_fill_slice(p, slice, data, len); - return lb_addr_load(p, slice); - + return lb_emit_load(p, final_ptr); } else if (addr.kind == lbAddr_Map) { Type *map_type = base_type(type_deref(addr.addr.type)); @@ -2139,17 +2113,10 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Type_RelativePointer: return lb_type_internal(m, type->RelativePointer.base_integer); + case Type_RelativeMultiPointer: + return lb_type_internal(m, type->RelativeMultiPointer.base_integer); - case Type_RelativeSlice: - { - LLVMTypeRef base_integer = lb_type_internal(m, type->RelativeSlice.base_integer); - unsigned field_count = 2; - LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count); - fields[0] = base_integer; - fields[1] = base_integer; - return LLVMStructTypeInContext(ctx, fields, field_count, false); - } case Type_Matrix: { diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 7e3a9133b..66edda825 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -1710,7 +1710,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu return lb_string_len(p, v); } else if (is_type_array(t)) { GB_PANIC("Array lengths are constant"); - } else if (is_type_slice(t) || is_type_relative_slice(t)) { + } else if (is_type_slice(t)) { return lb_slice_len(p, v); } else if (is_type_dynamic_array(t)) { return lb_dynamic_array_len(p, v); @@ -1735,7 +1735,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu GB_PANIC("Unreachable"); } else if (is_type_array(t)) { GB_PANIC("Array lengths are constant"); - } else if (is_type_slice(t) || is_type_relative_slice(t)) { + } else if (is_type_slice(t)) { return lb_slice_len(p, v); } else if (is_type_dynamic_array(t)) { return lb_dynamic_array_cap(p, v); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index c85840517..62a67f96a 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -57,7 +57,7 @@ gb_internal lbValue lb_typeid(lbModule *m, Type *type) { case Type_BitSet: kind = Typeid_Bit_Set; break; 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_RelativeMultiPointer: kind = Typeid_Relative_Multi_Pointer; break; case Type_SoaPointer: kind = Typeid_SoaPointer; break; } @@ -857,12 +857,13 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup lb_emit_store(p, tag, res); } break; - case Type_RelativeSlice: + + case Type_RelativeMultiPointer: { - tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_relative_slice_ptr); + tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_relative_multi_pointer_ptr); LLVMValueRef vals[2] = { - lb_type_info(m, t->RelativeSlice.slice_type).value, - lb_type_info(m, t->RelativeSlice.base_integer).value, + lb_type_info(m, t->RelativeMultiPointer.pointer_type).value, + lb_type_info(m, t->RelativeMultiPointer.base_integer).value, }; lbValue res = {}; @@ -871,6 +872,7 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup lb_emit_store(p, tag, res); } break; + case Type_Matrix: { tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_matrix_ptr); diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 2ecad1703..8dd6b14b6 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1124,11 +1124,6 @@ gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) { } } else if (is_type_array(t)) { return lb_emit_array_epi(p, s, index); - } else if (is_type_relative_slice(t)) { - switch (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; @@ -1547,7 +1542,7 @@ gb_internal lbValue lb_slice_elem(lbProcedure *p, lbValue slice) { return lb_emit_struct_ev(p, slice, 0); } gb_internal lbValue lb_slice_len(lbProcedure *p, lbValue slice) { - GB_ASSERT(is_type_slice(slice.type) || is_type_relative_slice(slice.type)); + GB_ASSERT(is_type_slice(slice.type)); return lb_emit_struct_ev(p, slice, 1); } gb_internal lbValue lb_dynamic_array_elem(lbProcedure *p, lbValue da) { diff --git a/src/parser.cpp b/src/parser.cpp index aa8969103..56d1e2d6c 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2235,7 +2235,11 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { return parse_check_directive_for_statement(operand, name, StateFlag_no_type_assert); } else if (name.string == "relative") { Ast *tag = ast_basic_directive(f, token, name); - tag = parse_call_expr(f, tag); + if (f->curr_token.kind != Token_OpenParen) { + syntax_error(tag, "expected #relative() "); + } else { + tag = parse_call_expr(f, tag); + } Ast *type = parse_type(f); return ast_relative_type(f, tag, type); } else if (name.string == "force_inline" || diff --git a/src/tilde_builtin.cpp b/src/tilde_builtin.cpp index 9dbc3f7c5..f036ce583 100644 --- a/src/tilde_builtin.cpp +++ b/src/tilde_builtin.cpp @@ -44,8 +44,6 @@ gb_internal cgValue cg_builtin_len(cgProcedure *p, cgValue value) { case Type_Struct: GB_ASSERT(is_type_soa_struct(t)); break; - case Type_RelativeSlice: - break; } GB_PANIC("TODO(bill): cg_builtin_len %s", type_to_string(t)); @@ -106,8 +104,6 @@ gb_internal cgValue cg_builtin_cap(cgProcedure *p, cgValue value) { case Type_Struct: GB_ASSERT(is_type_soa_struct(t)); break; - case Type_RelativeSlice: - break; } GB_PANIC("TODO(bill): cg_builtin_cap %s", type_to_string(t)); diff --git a/src/tilde_const.cpp b/src/tilde_const.cpp index 5b34480f4..f9187e3e1 100644 --- a/src/tilde_const.cpp +++ b/src/tilde_const.cpp @@ -255,9 +255,9 @@ gb_internal i64 cg_global_const_calculate_region_count_from_basic_type(Type *typ return 1; case Type_RelativePointer: - return 1; - case Type_RelativeSlice: - return 1; // technically 1 + case Type_RelativeMultiPointer: + return 2; // allows for offsets + case Type_Matrix: return 1; diff --git a/src/tilde_debug.cpp b/src/tilde_debug.cpp index 708476377..926cf9cd0 100644 --- a/src/tilde_debug.cpp +++ b/src/tilde_debug.cpp @@ -457,20 +457,8 @@ gb_internal TB_DebugType *cg_debug_type_internal(cgModule *m, Type *type) { return tb_debug_create_array(m->mod, cg_debug_type(m, type->SimdVector.elem), type->SimdVector.count); case Type_RelativePointer: return cg_debug_type(m, type->RelativePointer.base_integer); - case Type_RelativeSlice: - { - String name = {}; - TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text); - - TB_DebugType *base_integer = cg_debug_type(m, type->RelativeSlice.base_integer); - TB_CharUnits bi_size = cast(TB_CharUnits)type_size_of(type->RelativeSlice.base_integer); - TB_DebugType **fields = tb_debug_record_begin(record, 2); - fields[0] = tb_debug_create_field(m->mod, base_integer, -1, "data", 0*bi_size); - fields[1] = tb_debug_create_field(m->mod, base_integer, -1, "len", 1*bi_size); - - tb_debug_record_end(record, size, align); - return record; - } + case Type_RelativeMultiPointer: + return cg_debug_type(m, type->RelativeMultiPointer.base_integer); case Type_Matrix: { i64 count = matrix_type_total_internal_elems(type); diff --git a/src/tilde_expr.cpp b/src/tilde_expr.cpp index b654eb5e9..6ff912dd9 100644 --- a/src/tilde_expr.cpp +++ b/src/tilde_expr.cpp @@ -1469,8 +1469,8 @@ gb_internal cgAddr cg_build_addr_slice_expr(cgProcedure *p, Ast *expr) { return slice; } - case Type_RelativeSlice: - GB_PANIC("TODO(bill): Type_RelativeSlice should be handled above already on the cg_addr_load"); + case Type_RelativeMultiPointer: + GB_PANIC("TODO(bill): Type_RelativeMultiPointer should be handled above already on the cg_addr_load"); break; case Type_DynamicArray: { @@ -3598,22 +3598,18 @@ gb_internal cgAddr cg_build_addr_index_expr(cgProcedure *p, Ast *expr) { return cg_addr(v); } - case Type_RelativeSlice: { - GB_PANIC("TODO(bill): relative slice"); - // lbAddr slice_addr = {}; - // if (deref) { - // slice_addr = lb_addr(lb_build_expr(p, ie->expr)); - // } else { - // slice_addr = lb_build_addr(p, ie->expr); - // } - // lbValue slice = lb_addr_load(p, slice_addr); - - // lbValue elem = lb_slice_elem(p, slice); - // lbValue index = lb_emit_conv(p, lb_build_expr(p, ie->index), t_int); - // lbValue len = lb_slice_len(p, slice); - // lb_emit_bounds_check(p, ast_token(ie->index), index, len); - // lbValue v = lb_emit_ptr_offset(p, elem, index); - // return lb_addr(v); + case Type_RelativeMultiPointer: { + cgValue multi_ptr = {}; + multi_ptr = cg_build_expr(p, ie->expr); + if (deref) { + multi_ptr = cg_emit_load(p, multi_ptr); + } + cgValue index = cg_build_expr(p, ie->index); + index = cg_emit_conv(p, index, t_int); + + cgValue v = cg_emit_ptr_offset(p, multi_ptr, index); + v.type = alloc_type_pointer(type_deref(v.type, true)); + return cg_addr(v); } case Type_DynamicArray: { diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp index 382b4c02d..2a2aa31aa 100644 --- a/src/tilde_stmt.cpp +++ b/src/tilde_stmt.cpp @@ -530,21 +530,6 @@ gb_internal cgValue cg_emit_struct_ep(cgProcedure *p, cgValue s, i64 index) { } case Type_Array: return cg_emit_array_epi(p, s, index); - case Type_RelativeSlice: - { - Type *bi = t->RelativeSlice.base_integer; - i64 sz = type_size_of(bi); - switch (index) { - case 0: - case 1: - result_type = bi; - offset = sz * index; - break; - default: - goto error_case; - } - } - break; case Type_SoaPointer: switch (index) { case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break; diff --git a/src/tilde_type_info.cpp b/src/tilde_type_info.cpp index 0dd014bd1..16fe5fd3e 100644 --- a/src/tilde_type_info.cpp +++ b/src/tilde_type_info.cpp @@ -75,24 +75,24 @@ gb_internal u64 cg_typeid_as_u64(cgModule *m, Type *type) { if (flags & BasicFlag_String) kind = Typeid_String; if (flags & BasicFlag_Rune) kind = Typeid_Rune; } break; - case Type_Pointer: kind = Typeid_Pointer; break; - case Type_MultiPointer: kind = Typeid_Multi_Pointer; break; - case Type_Array: kind = Typeid_Array; break; - case Type_Matrix: kind = Typeid_Matrix; break; - case Type_EnumeratedArray: kind = Typeid_Enumerated_Array; break; - case Type_Slice: kind = Typeid_Slice; break; - case Type_DynamicArray: kind = Typeid_Dynamic_Array; break; - case Type_Map: kind = Typeid_Map; break; - case Type_Struct: kind = Typeid_Struct; break; - case Type_Enum: kind = Typeid_Enum; break; - case Type_Union: kind = Typeid_Union; break; - case Type_Tuple: kind = Typeid_Tuple; break; - case Type_Proc: kind = Typeid_Procedure; 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; - case Type_RelativeSlice: kind = Typeid_Relative_Slice; break; - case Type_SoaPointer: kind = Typeid_SoaPointer; break; + case Type_Pointer: kind = Typeid_Pointer; break; + case Type_MultiPointer: kind = Typeid_Multi_Pointer; break; + case Type_Array: kind = Typeid_Array; break; + case Type_Matrix: kind = Typeid_Matrix; break; + case Type_EnumeratedArray: kind = Typeid_Enumerated_Array; break; + case Type_Slice: kind = Typeid_Slice; break; + case Type_DynamicArray: kind = Typeid_Dynamic_Array; break; + case Type_Map: kind = Typeid_Map; break; + case Type_Struct: kind = Typeid_Struct; break; + case Type_Enum: kind = Typeid_Enum; break; + case Type_Union: kind = Typeid_Union; break; + case Type_Tuple: kind = Typeid_Tuple; break; + case Type_Proc: kind = Typeid_Procedure; 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; + case Type_RelativeMultiPointer: kind = Typeid_Relative_Multi_Pointer; break; + case Type_SoaPointer: kind = Typeid_SoaPointer; break; } if (is_type_cstring(type)) { @@ -935,15 +935,15 @@ gb_internal void cg_setup_type_info_data(cgModule *m) { cg_global_const_type_info_ptr(m, t->RelativePointer.base_integer, global, offset+base_integer_offset); } break; - case Type_RelativeSlice: + case Type_RelativeMultiPointer: { - tag_type = t_type_info_relative_slice; + tag_type = t_type_info_relative_multi_pointer; - i64 slice_offset = type_offset_of(tag_type, 0); + i64 pointer_offset = type_offset_of(tag_type, 0); i64 base_integer_offset = type_offset_of(tag_type, 1); - cg_global_const_type_info_ptr(m, t->RelativeSlice.slice_type, global, offset+slice_offset); - cg_global_const_type_info_ptr(m, t->RelativeSlice.base_integer, global, offset+base_integer_offset); + cg_global_const_type_info_ptr(m, t->RelativePointer.pointer_type, global, offset+pointer_offset); + cg_global_const_type_info_ptr(m, t->RelativePointer.base_integer, global, offset+base_integer_offset); } break; case Type_Matrix: diff --git a/src/types.cpp b/src/types.cpp index a4856f767..22deca1dc 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -267,8 +267,8 @@ struct TypeProc { Type *pointer_type; \ Type *base_integer; \ }) \ - TYPE_KIND(RelativeSlice, struct { \ - Type *slice_type; \ + TYPE_KIND(RelativeMultiPointer, struct { \ + Type *pointer_type; \ Type *base_integer; \ }) \ TYPE_KIND(Matrix, struct { \ @@ -349,7 +349,7 @@ enum Typeid_Kind : u8 { Typeid_Bit_Set, Typeid_Simd_Vector, Typeid_Relative_Pointer, - Typeid_Relative_Slice, + Typeid_Relative_Multi_Pointer, Typeid_Matrix, Typeid_SoaPointer, }; @@ -635,7 +635,7 @@ gb_global Type *t_type_info_map = nullptr; gb_global Type *t_type_info_bit_set = nullptr; 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_relative_multi_pointer = nullptr; gb_global Type *t_type_info_matrix = nullptr; gb_global Type *t_type_info_soa_pointer = nullptr; @@ -664,7 +664,7 @@ gb_global Type *t_type_info_map_ptr = nullptr; gb_global Type *t_type_info_bit_set_ptr = nullptr; 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_relative_multi_pointer_ptr = nullptr; gb_global Type *t_type_info_matrix_ptr = nullptr; gb_global Type *t_type_info_soa_pointer_ptr = nullptr; @@ -737,6 +737,7 @@ gb_internal Type * bit_set_to_int(Type *t); gb_internal bool are_types_identical(Type *x, Type *y); gb_internal bool is_type_pointer(Type *t); +gb_internal bool is_type_multi_pointer(Type *t); gb_internal bool is_type_soa_pointer(Type *t); gb_internal bool is_type_proc(Type *t); gb_internal bool is_type_slice(Type *t); @@ -1035,12 +1036,12 @@ gb_internal Type *alloc_type_relative_pointer(Type *pointer_type, Type *base_int return t; } -gb_internal Type *alloc_type_relative_slice(Type *slice_type, Type *base_integer) { - GB_ASSERT(is_type_slice(slice_type)); +gb_internal Type *alloc_type_relative_multi_pointer(Type *pointer_type, Type *base_integer) { + GB_ASSERT(is_type_multi_pointer(pointer_type)); GB_ASSERT(is_type_integer(base_integer)); - Type *t = alloc_type(Type_RelativeSlice); - t->RelativeSlice.slice_type = slice_type; - t->RelativeSlice.base_integer = base_integer; + Type *t = alloc_type(Type_RelativeMultiPointer); + t->RelativeMultiPointer.pointer_type = pointer_type; + t->RelativeMultiPointer.base_integer = base_integer; return t; } @@ -1551,9 +1552,9 @@ gb_internal bool is_type_relative_pointer(Type *t) { t = base_type(t); return t->kind == Type_RelativePointer; } -gb_internal bool is_type_relative_slice(Type *t) { +gb_internal bool is_type_relative_multi_pointer(Type *t) { t = base_type(t); - return t->kind == Type_RelativeSlice; + return t->kind == Type_RelativeMultiPointer; } gb_internal bool is_type_u8_slice(Type *t) { @@ -1970,7 +1971,7 @@ gb_internal bool is_type_indexable(Type *t) { return true; case Type_EnumeratedArray: return true; - case Type_RelativeSlice: + case Type_RelativeMultiPointer: return true; case Type_Matrix: return true; @@ -1989,7 +1990,7 @@ gb_internal bool is_type_sliceable(Type *t) { return true; case Type_EnumeratedArray: return false; - case Type_RelativeSlice: + case Type_RelativeMultiPointer: return true; case Type_Matrix: return false; @@ -2195,12 +2196,12 @@ gb_internal bool is_type_polymorphic(Type *t, bool or_specialized=false) { } break; - case Type_RelativeSlice: - if (is_type_polymorphic(t->RelativeSlice.slice_type, or_specialized)) { + case Type_RelativeMultiPointer: + if (is_type_polymorphic(t->RelativeMultiPointer.pointer_type, or_specialized)) { return true; } - if (t->RelativeSlice.base_integer != nullptr && - is_type_polymorphic(t->RelativeSlice.base_integer, or_specialized)) { + if (t->RelativeMultiPointer.base_integer != nullptr && + is_type_polymorphic(t->RelativeMultiPointer.base_integer, or_specialized)) { return true; } break; @@ -2258,7 +2259,7 @@ gb_internal bool type_has_nil(Type *t) { return false; case Type_RelativePointer: - case Type_RelativeSlice: + case Type_RelativeMultiPointer: return true; } return false; @@ -2425,7 +2426,7 @@ gb_internal bool is_type_load_safe(Type *type) { return true; case Type_RelativePointer: - case Type_RelativeSlice: + case Type_RelativeMultiPointer: return true; case Type_Pointer: @@ -3629,8 +3630,8 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) { case Type_RelativePointer: 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_RelativeMultiPointer: + return type_align_of_internal(t->RelativeMultiPointer.base_integer, path); case Type_SoaPointer: return build_context.int_size; @@ -3912,8 +3913,8 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) { case Type_RelativePointer: return type_size_of_internal(t->RelativePointer.base_integer, path); - case Type_RelativeSlice: - return 2*type_size_of_internal(t->RelativeSlice.base_integer, path); + case Type_RelativeMultiPointer: + return type_size_of_internal(t->RelativeMultiPointer.base_integer, path); } // Catch all @@ -4466,11 +4467,11 @@ gb_internal gbString write_type_to_string(gbString str, Type *type, bool shortha str = gb_string_append_fmt(str, ") "); str = write_type_to_string(str, type->RelativePointer.pointer_type); break; - case Type_RelativeSlice: + case Type_RelativeMultiPointer: str = gb_string_append_fmt(str, "#relative("); - str = write_type_to_string(str, type->RelativeSlice.base_integer); + str = write_type_to_string(str, type->RelativePointer.base_integer); str = gb_string_append_fmt(str, ") "); - str = write_type_to_string(str, type->RelativeSlice.slice_type); + str = write_type_to_string(str, type->RelativePointer.pointer_type); break; case Type_Matrix: -- cgit v1.2.3