From c291fffce1972fcfc631dd4c6f623e3f5055f74b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 12 Feb 2024 12:29:37 +0000 Subject: Add metadata type to `map`s debug information to aid debuggers knowing what is in it it --- src/llvm_backend_debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index e053c5b40..894c60729 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -710,7 +710,7 @@ gb_internal void lb_debug_complete_types(lbModule *m) { case Type_Map: GB_ASSERT(t_raw_map != nullptr); - bt = base_type(t_raw_map); + bt = base_type(t->Map.debug_metadata_type); /*fallthrough*/ case Type_Struct: if (file == nullptr) { -- cgit v1.2.3 From 5cd57a3a7f96e4966a7a17f99363893911fbad0d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 13 Feb 2024 15:50:07 +0000 Subject: Use `Raw_Map` as the debug information for a `map` --- src/check_type.cpp | 2 ++ src/llvm_backend_debug.cpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index 01bb36255..03c7474fb 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2307,6 +2307,7 @@ gb_internal void init_map_internal_types(Type *type) { metadata_type->Struct.fields[3] = alloc_entity_field(metadata_scope, make_token_ident("key_cell"), key_cell, false, 3, EntityState_Resolved); metadata_type->Struct.fields[4] = alloc_entity_field(metadata_scope, make_token_ident("value_cell"), value_cell, false, 4, EntityState_Resolved); metadata_type->Struct.scope = metadata_scope; + metadata_type->Struct.node = nullptr; gb_unused(type_size_of(metadata_type)); @@ -2323,6 +2324,7 @@ gb_internal void init_map_internal_types(Type *type) { debug_type->Struct.fields[2] = alloc_entity_field(scope, make_token_ident("allocator"), t_allocator, false, 2, EntityState_Resolved); debug_type->Struct.fields[3] = alloc_entity_field(scope, make_token_ident("__metadata"), metadata_type, false, 3, EntityState_Resolved); debug_type->Struct.scope = scope; + debug_type->Struct.node = nullptr; gb_unused(type_size_of(debug_type)); diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 894c60729..6bcbac13f 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -710,7 +710,9 @@ gb_internal void lb_debug_complete_types(lbModule *m) { case Type_Map: GB_ASSERT(t_raw_map != nullptr); - bt = base_type(t->Map.debug_metadata_type); + // bt = base_type(t->Map.debug_metadata_type); + bt = base_type(t_raw_map); + GB_ASSERT(bt->kind == Type_Struct); /*fallthrough*/ case Type_Struct: if (file == nullptr) { -- cgit v1.2.3 From 912c326d8b05dba282a9a58e2405b09f774dbe34 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 13 Feb 2024 17:06:04 +0000 Subject: Fix typo that causes map info debug issues --- src/llvm_backend_debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 6bcbac13f..f45cf0cbc 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -710,8 +710,8 @@ gb_internal void lb_debug_complete_types(lbModule *m) { case Type_Map: GB_ASSERT(t_raw_map != nullptr); - // bt = base_type(t->Map.debug_metadata_type); - bt = base_type(t_raw_map); + bt = base_type(bt->Map.debug_metadata_type); + // bt = base_type(t_raw_map); GB_ASSERT(bt->kind == Type_Struct); /*fallthrough*/ case Type_Struct: -- cgit v1.2.3 From a4b8c1ea1779ce93349b203aaf56c5aeca316b61 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 22 Feb 2024 15:55:20 +0000 Subject: Begin work adding `bit_field` --- base/runtime/core.odin | 9 +++ base/runtime/print.odin | 14 ++++ core/encoding/json/marshal.odin | 3 + core/fmt/fmt.odin | 65 +++++++++++++++++ core/reflect/reflect.odin | 10 +++ core/reflect/types.odin | 31 ++++++++ src/check_type.cpp | 152 ++++++++++++++++++++++++++++++++++++++++ src/checker.cpp | 18 +++++ src/llvm_backend.cpp | 8 ++- src/llvm_backend_debug.cpp | 36 ++++++++++ src/llvm_backend_general.cpp | 4 +- src/llvm_backend_type.cpp | 67 ++++++++++++++++++ src/parser.cpp | 78 +++++++++++++++++++++ src/parser.hpp | 15 ++++ src/parser_pos.cpp | 3 + src/types.cpp | 24 +++++++ 16 files changed, 535 insertions(+), 2 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/base/runtime/core.odin b/base/runtime/core.odin index 85e64242d..dcc1e7476 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -181,6 +181,13 @@ Type_Info_Matrix :: struct { Type_Info_Soa_Pointer :: struct { elem: ^Type_Info, } +Type_Info_Bit_Field :: struct { + backing_type: ^Type_Info, + names: []string, + types: []^Type_Info, + bit_sizes: []uintptr, + bit_offsets: []uintptr, +} Type_Info_Flag :: enum u8 { Comparable = 0, @@ -223,6 +230,7 @@ Type_Info :: struct { Type_Info_Relative_Multi_Pointer, Type_Info_Matrix, Type_Info_Soa_Pointer, + Type_Info_Bit_Field, }, } @@ -256,6 +264,7 @@ Typeid_Kind :: enum u8 { Relative_Multi_Pointer, Matrix, Soa_Pointer, + Bit_Field, } #assert(len(Typeid_Kind) < 32) diff --git a/base/runtime/print.odin b/base/runtime/print.odin index 41ff9e1bb..c93c2ab49 100644 --- a/base/runtime/print.odin +++ b/base/runtime/print.odin @@ -459,6 +459,20 @@ print_type :: proc "contextless" (ti: ^Type_Info) { } print_byte(']') + case Type_Info_Bit_Field: + print_string("bit_field ") + print_type(info.backing_type) + print_string(" {") + for name, i in info.names { + if i > 0 { print_string(", ") } + print_string(name) + print_string(": ") + print_type(info.types[i]) + print_string(" | ") + print_u64(u64(info.bit_sizes[i])) + } + print_byte('}') + case Type_Info_Simd_Vector: print_string("#simd[") diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index e9285364b..e237892c3 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -228,6 +228,9 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Matrix: return .Unsupported_Type + case runtime.Type_Info_Bit_Field: + return .Unsupported_Type + case runtime.Type_Info_Array: opt_write_start(w, opt, '[') or_return for i in 0.. (res: u64) { + for i in 0.. 0 { + io.write_string(fi.writer, ", ") + } + if hash { + fmt_write_indent(fi) + } + + io.write_string(fi.writer, name, &fi.n) + io.write_string(fi.writer, " = ", &fi.n) + + + bit_offset := info.bit_offsets[i] + bit_size := info.bit_sizes[i] + + value := read_bits(([^]byte)(v.data), bit_offset, bit_size) + + fmt_value(fi, any{&value, info.types[i].id}, verb) + if do_trailing_comma { io.write_string(fi.writer, ",\n", &fi.n) } + + } +} + + + // Formats a value based on its type and formatting verb // // Inputs: @@ -2611,6 +2673,9 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Matrix: fmt_matrix(fi, v, verb, info) + + case runtime.Type_Info_Bit_Field: + fmt_bit_field(fi, v, verb, info) } } // Formats a complex number based on the given formatting verb diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index 0af23b18e..de5dec2e3 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -35,6 +35,7 @@ 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_Bit_Field :: runtime.Type_Info_Bit_Field Type_Info_Enum_Value :: runtime.Type_Info_Enum_Value @@ -70,6 +71,7 @@ Type_Kind :: enum { Relative_Multi_Pointer, Matrix, Soa_Pointer, + Bit_Field, } @@ -106,6 +108,7 @@ type_kind :: proc(T: typeid) -> Type_Kind { case Type_Info_Relative_Multi_Pointer: return .Relative_Multi_Pointer case Type_Info_Matrix: return .Matrix case Type_Info_Soa_Pointer: return .Soa_Pointer + case Type_Info_Bit_Field: return .Bit_Field } } @@ -1604,6 +1607,13 @@ equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_ } } return true + + case Type_Info_Bit_Field: + x, y := a, b + x.id = v.backing_type.id + y.id = v.backing_type.id + return equal(x, y, including_indirect_array_recursion, recursion_level+0) + } runtime.print_typeid(a.id) diff --git a/core/reflect/types.odin b/core/reflect/types.odin index cbe108d82..2b96dd4fb 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -174,6 +174,23 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { if x.row_count != y.row_count { return false } if x.column_count != y.column_count { return false } return are_types_identical(x.elem, y.elem) + + case Type_Info_Bit_Field: + y := b.variant.(Type_Info_Bit_Field) or_return + if !are_types_identical(x.backing_type, y.backing_type) { return false } + if len(x.names) != len(y.names) { return false } + for _, i in x.names { + if x.names[i] != y.names[i] { + return false + } + if !are_types_identical(x.types[i], y.types[i]) { + return false + } + if x.bit_sizes[i] != y.bit_sizes[i] { + return false + } + } + return true } return false @@ -639,6 +656,20 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) - } io.write_byte(w, ']', &n) or_return + case Type_Info_Bit_Field: + io.write_string(w, "bit_field ", &n) or_return + write_type(w, info.backing_type, &n) or_return + io.write_string(w, " {", &n) or_return + for name, i in info.names { + if i > 0 { io.write_string(w, ", ", &n) or_return } + io.write_string(w, name, &n) or_return + io.write_string(w, ": ", &n) or_return + write_type(w, info.types[i], &n) or_return + io.write_string(w, " | ", &n) or_return + io.write_u64(w, u64(info.bit_sizes[i]), 10, &n) or_return + } + io.write_string(w, "}", &n) or_return + case Type_Info_Simd_Vector: io.write_string(w, "#simd[", &n) or_return io.write_i64(w, i64(info.count), 10, &n) or_return diff --git a/src/check_type.cpp b/src/check_type.cpp index 8a140d95e..8afac2fc5 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -925,6 +925,144 @@ gb_internal void check_enum_type(CheckerContext *ctx, Type *enum_type, Type *nam enum_type->Enum.max_value_index = max_value_index; } +gb_internal bool is_valid_bit_field_backing_type(Type *type) { + if (type == nullptr) { + return nullptr; + } + type = base_type(type); + if (is_type_untyped(type)) { + return false; + } + if (is_type_integer(type)) { + return true; + } + if (type->kind == Type_Array) { + return is_type_integer(type->Array.elem); + } + return false; +} + +gb_internal void check_bit_field_type(CheckerContext *ctx, Type *bit_field_type, Type *named_type, Ast *node) { + ast_node(bf, BitFieldType, node); + GB_ASSERT(is_type_bit_field(bit_field_type)); + + Type *backing_type = check_type(ctx, bf->backing_type); + if (backing_type == nullptr || !is_valid_bit_field_backing_type(backing_type)) { + error(node, "Backing type for a bit_field must be an integer or an array of an integer"); + return; + } + + bit_field_type->BitField.backing_type = backing_type; + bit_field_type->BitField.scope = ctx->scope; + + auto fields = array_make(permanent_allocator(), 0, bf->fields.count); + auto bit_sizes = array_make (permanent_allocator(), 0, bf->fields.count); + + u64 maximum_bit_size = 8 * type_size_of(backing_type); + u64 total_bit_size = 0; + + for_array(i, bf->fields) { + i32 field_src_index = cast(i32)i; + Ast *field = bf->fields[i]; + if (field->kind != Ast_BitFieldField) { + error(field, "Invalid AST for a bit_field"); + continue; + } + ast_node(f, BitFieldField, field); + if (f->name == nullptr || f->name->kind != Ast_Ident) { + error(field, "A bit_field's field name must be an identifier"); + continue; + } + CommentGroup *docs = f->docs; + CommentGroup *comment = f->comment; + + String name = f->name->Ident.token.string; + + if (f->type == nullptr) { + error(field, "A bit_field's field must have a type"); + continue; + } + + Type *type = check_type(ctx, f->type); + if (type_size_of(type) > 8) { + error(f->type, "The type of a bit_field's field must be <= 8 bytes, got %lld", cast(long long)type_size_of(type)); + } + + if (is_type_untyped(type)) { + gbString s = type_to_string(type); + error(f->type, "The type of a bit_field's field must be a typed integer, enum, or boolean, got %s", s); + gb_string_free(s); + } else if (!(is_type_integer(type) || is_type_enum(type) || is_type_boolean(type))) { + gbString s = type_to_string(type); + error(f->type, "The type of a bit_field's field must be an integer, enum, or boolean, got %s", s); + gb_string_free(s); + } + + if (f->bit_size == nullptr) { + error(field, "A bit_field's field must have a specified bit size"); + continue; + } + + + Operand o = {}; + check_expr(ctx, &o, f->bit_size); + if (o.mode != Addressing_Constant) { + error(f->bit_size, "A bit_field's specified bit size must be a constant"); + o.mode = Addressing_Invalid; + } + if (o.value.kind == ExactValue_Float) { + o.value = exact_value_to_integer(o.value); + } + + ExactValue bit_size = o.value; + + if (bit_size.kind != ExactValue_Integer) { + gbString s = expr_to_string(f->bit_size); + error(f->bit_size, "Expected an integer constant value for the specified bit size, got %s", s); + gb_string_free(s); + } + + if (scope_lookup_current(ctx->scope, name) != nullptr) { + error(f->name, "'%.*s' is already declared in this bit_field", LIT(name)); + } else { + i64 bit_size_i64 = exact_value_to_i64(bit_size); + u8 bit_size_u8 = 0; + if (bit_size_i64 <= 0) { + error(f->bit_size, "A bit_field's specified bit size cannot be <= 0, got %lld", cast(long long)bit_size_i64); + bit_size_i64 = 1; + } + if (bit_size_i64 > 64) { + error(f->bit_size, "A bit_field's specified bit size cannot exceed 64 bits, got %lld", cast(long long)bit_size_i64); + bit_size_i64 = 64; + } + bit_size_u8 = cast(u8)bit_size_i64; + + Entity *e = alloc_entity_field(ctx->scope, f->name->Ident.token, type, false, field_src_index); + e->Variable.docs = docs; + e->Variable.comment = comment; + + add_entity(ctx, ctx->scope, nullptr, e); + array_add(&fields, e); + array_add(&bit_sizes, bit_size_u8); + add_entity_use(ctx, field, e); + } + } + + GB_ASSERT(fields.count <= bf->fields.count); + + if (total_bit_size > maximum_bit_size) { + gbString s = type_to_string(backing_type); + error(node, "The numbers required %llu exceeds the backing type's (%s) bit size %llu", + cast(unsigned long long)total_bit_size, + s, + cast(unsigned long long)maximum_bit_size); + gb_string_free(s); + } + + bit_field_type->BitField.fields = slice_from_array(fields); + bit_field_type->BitField.bit_sizes = slice_from_array(bit_sizes); +} + gb_internal bool is_type_valid_bit_set_range(Type *t) { if (is_type_integer(t)) { return true; @@ -3051,6 +3189,20 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T return true; case_end; + case_ast_node(bf, BitFieldType, e); + bool ips = ctx->in_polymorphic_specialization; + defer (ctx->in_polymorphic_specialization = ips); + ctx->in_polymorphic_specialization = false; + + *type = alloc_type_bit_field(); + set_base_type(named_type, *type); + check_open_scope(ctx, e); + check_bit_field_type(ctx, *type, named_type, e); + check_close_scope(ctx); + (*type)->BitField.node = e; + return true; + case_end; + case_ast_node(pt, ProcType, e); bool ips = ctx->in_polymorphic_specialization; diff --git a/src/checker.cpp b/src/checker.cpp index 569a3c76f..5827fc695 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -313,6 +313,7 @@ gb_internal void add_scope(CheckerContext *c, Ast *node, Scope *scope) { case Ast_StructType: node->StructType.scope = scope; break; case Ast_UnionType: node->UnionType.scope = scope; break; case Ast_EnumType: node->EnumType.scope = scope; break; + case Ast_BitFieldType: node->BitFieldType.scope = scope; break; default: GB_PANIC("Invalid node for add_scope: %.*s", LIT(ast_strings[node->kind])); } } @@ -334,6 +335,7 @@ gb_internal Scope *scope_of_node(Ast *node) { case Ast_StructType: return node->StructType.scope; case Ast_UnionType: return node->UnionType.scope; case Ast_EnumType: return node->EnumType.scope; + case Ast_BitFieldType: return node->BitFieldType.scope; } GB_PANIC("Invalid node for add_scope: %.*s", LIT(ast_strings[node->kind])); return nullptr; @@ -355,6 +357,7 @@ gb_internal void check_open_scope(CheckerContext *c, Ast *node) { case Ast_EnumType: case Ast_UnionType: case Ast_BitSetType: + case Ast_BitFieldType: scope->flags |= ScopeFlag_Type; break; } @@ -2060,6 +2063,12 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { add_type_info_type_internal(c, bt->SoaPointer.elem); break; + case Type_BitField: + add_type_info_type_internal(c, bt->BitField.backing_type); + for (Entity *f : bt->BitField.fields) { + add_type_info_type_internal(c, f->type); + } + break; case Type_Generic: break; @@ -2309,6 +2318,13 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { add_min_dep_type_info(c, bt->SoaPointer.elem); break; + case Type_BitField: + add_min_dep_type_info(c, bt->BitField.backing_type); + for (Entity *f : bt->BitField.fields) { + add_min_dep_type_info(c, f->type); + } + break; + default: GB_PANIC("Unhandled type: %*.s", LIT(type_strings[bt->kind])); break; @@ -2907,6 +2923,7 @@ gb_internal void init_core_type_info(Checker *c) { 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")); + t_type_info_bit_field = find_core_type(c, str_lit("Type_Info_Bit_Field")); t_type_info_named_ptr = alloc_type_pointer(t_type_info_named); t_type_info_integer_ptr = alloc_type_pointer(t_type_info_integer); @@ -2936,6 +2953,7 @@ gb_internal void init_core_type_info(Checker *c) { 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); + t_type_info_bit_field_ptr = alloc_type_pointer(t_type_info_bit_field); } gb_internal void init_mem_allocator(Checker *c) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index fa76ac22f..45d903b43 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2719,6 +2719,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { { // Type info member buffer // NOTE(bill): Removes need for heap allocation by making it global memory isize count = 0; + isize offsets_extra = 0; for (Type *t : m->info->type_info_types) { isize index = lb_type_info_index(m->info, t, false); @@ -2736,6 +2737,11 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { case Type_Tuple: count += t->Tuple.variables.count; break; + case Type_BitField: + count += t->BitField.fields.count; + // Twice is needed for the bit_offsets + offsets_extra += t->BitField.fields.count; + break; } } @@ -2752,7 +2758,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { lb_global_type_info_member_types = global_type_info_make(m, LB_TYPE_INFO_TYPES_NAME, t_type_info_ptr, count); lb_global_type_info_member_names = global_type_info_make(m, LB_TYPE_INFO_NAMES_NAME, t_string, count); - lb_global_type_info_member_offsets = global_type_info_make(m, LB_TYPE_INFO_OFFSETS_NAME, t_uintptr, count); + lb_global_type_info_member_offsets = global_type_info_make(m, LB_TYPE_INFO_OFFSETS_NAME, t_uintptr, count+offsets_extra); lb_global_type_info_member_usings = global_type_info_make(m, LB_TYPE_INFO_USINGS_NAME, t_bool, count); lb_global_type_info_member_tags = global_type_info_make(m, LB_TYPE_INFO_TAGS_NAME, t_string, count); } diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index f45cf0cbc..7d3692a53 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -461,6 +461,42 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { lb_debug_type(m, type->Matrix.elem), subscripts, gb_count_of(subscripts)); } + + case Type_BitField: { + LLVMMetadataRef parent_scope = nullptr; + LLVMMetadataRef scope = nullptr; + LLVMMetadataRef file = nullptr; + unsigned line = 0; + u64 size_in_bits = 8*cast(u64)type_size_of(type); + u32 align_in_bits = 8*cast(u32)type_align_of(type); + LLVMDIFlags flags = LLVMDIFlagZero; + + unsigned element_count = cast(unsigned)type->BitField.fields.count; + LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count); + + u64 offset_in_bits = 0; + for (unsigned i = 0; i < element_count; i++) { + Entity *f = type->BitField.fields[i]; + u8 bit_size = type->BitField.bit_sizes[i]; + GB_ASSERT(f->kind == Entity_Variable); + String name = f->token.string; + unsigned field_line = 0; + LLVMDIFlags field_flags = LLVMDIFlagZero; + elements[i] = LLVMDIBuilderCreateBitFieldMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, field_line, + bit_size, offset_in_bits, offset_in_bits, + field_flags, lb_debug_type(m, f->type) + ); + + offset_in_bits += bit_size; + } + + + return LLVMDIBuilderCreateStructType(m->debug_builder, parent_scope, "", 0, file, line, + size_in_bits, align_in_bits, flags, + nullptr, elements, element_count, 0, nullptr, + "", 0 + ); + } } GB_PANIC("Invalid type %s", type_to_string(type)); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index f0f5327c6..2102420f8 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2216,7 +2216,9 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { } return LLVMStructTypeInContext(ctx, fields, field_count, false); } - + + case Type_BitField: + return lb_type_internal(m, type->BitField.backing_type); } GB_PANIC("Invalid type %s", type_to_string(type)); diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index e291e40a5..3567a550b 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -1788,6 +1788,73 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup lb_emit_store(p, tag, res); } break; + + case Type_BitField: + { + tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_bit_field_ptr); + LLVMValueRef vals[5] = {}; + + vals[0] = lb_type_info(m, t->BitField.backing_type).value; + isize count = t->BitField.fields.count; + if (count > 0) { + i64 names_offset = 0; + i64 types_offset = 0; + i64 bit_sizes_offset = 0; + i64 bit_offsets_offset = 0; + lbValue memory_names = lb_type_info_member_names_offset (m, count, &names_offset); + lbValue memory_types = lb_type_info_member_types_offset (m, count, &types_offset); + lbValue memory_bit_sizes = lb_type_info_member_offsets_offset(m, count, &bit_sizes_offset); + lbValue memory_bit_offsets = lb_type_info_member_offsets_offset(m, count, &bit_offsets_offset); + + u64 bit_offset = 0; + for (isize source_index = 0; source_index < count; source_index++) { + Entity *f = t->BitField.fields[source_index]; + u64 bit_size = cast(u64)t->BitField.bit_sizes[source_index]; + + lbValue index = lb_const_int(m, t_int, source_index); + if (f->token.string.len > 0) { + lbValue name = lb_emit_ptr_offset(p, memory_names, index); + lb_emit_store(p, name, lb_const_string(m, f->token.string)); + } + lbValue type_ptr = lb_emit_ptr_offset(p, memory_types, index); + lbValue bit_size_ptr = lb_emit_ptr_offset(p, memory_bit_sizes, index); + lbValue bit_offset_ptr = lb_emit_ptr_offset(p, memory_bit_offsets, index); + + lb_emit_store(p, type_ptr, lb_type_info(m, f->type)); + lb_emit_store(p, bit_size_ptr, lb_const_int(m, t_uintptr, bit_size)); + lb_emit_store(p, bit_offset_ptr, lb_const_int(m, t_uintptr, bit_offset)); + + // lb_global_type_info_member_types_values [types_offset +source_index] = get_type_info_ptr(m, f->type); + // lb_global_type_info_member_offsets_values[bit_sizes_offset +source_index] = lb_const_int(m, t_uintptr, bit_size).value; + // lb_global_type_info_member_offsets_values[bit_offsets_offset+source_index] = lb_const_int(m, t_uintptr, bit_offset).value; + // if (f->token.string.len > 0) { + // lb_global_type_info_member_names_values[names_offset+source_index] = lb_const_string(m, f->token.string).value; + // } + + bit_offset += bit_size; + } + + lbValue cv = lb_const_int(m, t_int, count); + vals[1] = llvm_const_slice(m, memory_names, cv); + vals[2] = llvm_const_slice(m, memory_types, cv); + vals[3] = llvm_const_slice(m, memory_bit_sizes, cv); + vals[4] = llvm_const_slice(m, memory_bit_offsets, cv); + } + + for (isize i = 0; i < gb_count_of(vals); i++) { + if (vals[i] == nullptr) { + vals[i] = LLVMConstNull(lb_type(m, get_struct_field_type(tag.type, i))); + } + } + + lbValue res = {}; + res.type = type_deref(tag.type); + res.value = llvm_const_named_struct(m, res.type, vals, gb_count_of(vals)); + lb_emit_store(p, tag, res); + + break; + } + } diff --git a/src/parser.cpp b/src/parser.cpp index 78ac29dfd..70da9414d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -350,6 +350,11 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) { n->Field.names = clone_ast_array(n->Field.names, f); n->Field.type = clone_ast(n->Field.type, f); break; + case Ast_BitFieldField: + n->BitFieldField.name = clone_ast(n->BitFieldField.name, f); + n->BitFieldField.type = clone_ast(n->BitFieldField.type, f); + n->BitFieldField.bit_size = clone_ast(n->BitFieldField.bit_size, f); + break; case Ast_FieldList: n->FieldList.list = clone_ast_array(n->FieldList.list, f); break; @@ -406,6 +411,10 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) { n->BitSetType.elem = clone_ast(n->BitSetType.elem, f); n->BitSetType.underlying = clone_ast(n->BitSetType.underlying, f); break; + case Ast_BitFieldType: + n->BitFieldType.backing_type = clone_ast(n->BitFieldType.backing_type, f); + n->BitFieldType.fields = clone_ast_array(n->BitFieldType.fields, f); + break; case Ast_MapType: n->MapType.count = clone_ast(n->MapType.count, f); n->MapType.key = clone_ast(n->MapType.key, f); @@ -1045,6 +1054,17 @@ gb_internal Ast *ast_field(AstFile *f, Array const &names, Ast *type, Ast return result; } +gb_internal Ast *ast_bit_field_field(AstFile *f, Ast *name, Ast *type, Ast *bit_size, + CommentGroup *docs, CommentGroup *comment) { + Ast *result = alloc_ast_node(f, Ast_BitFieldField); + result->BitFieldField.name = name; + result->BitFieldField.type = type; + result->BitFieldField.bit_size = bit_size; + result->BitFieldField.docs = docs; + result->BitFieldField.comment = comment; + return result; +} + gb_internal Ast *ast_field_list(AstFile *f, Token token, Array const &list) { Ast *result = alloc_ast_node(f, Ast_FieldList); result->FieldList.token = token; @@ -1178,6 +1198,17 @@ gb_internal Ast *ast_bit_set_type(AstFile *f, Token token, Ast *elem, Ast *under return result; } +gb_internal Ast *ast_bit_field_type(AstFile *f, Token token, Ast *backing_type, Token open, Array const &fields, Token close) { + Ast *result = alloc_ast_node(f, Ast_BitFieldType); + result->BitFieldType.token = token; + result->BitFieldType.backing_type = backing_type; + result->BitFieldType.open = open; + result->BitFieldType.fields = slice_from_array(fields); + result->BitFieldType.close = close; + return result; +} + + gb_internal Ast *ast_map_type(AstFile *f, Token token, Ast *key, Ast *value) { Ast *result = alloc_ast_node(f, Ast_MapType); result->MapType.token = token; @@ -2549,6 +2580,53 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { return ast_matrix_type(f, token, row_count, column_count, type); } break; + case Token_bit_field: { + Token token = expect_token(f, Token_bit_field); + isize prev_level; + + prev_level = f->expr_level; + f->expr_level = -1; + + Ast *backing_type = parse_type_or_ident(f); + if (backing_type == nullptr) { + Token token = advance_token(f); + syntax_error(token, "Expected a backing type for a 'bit_field'"); + backing_type = ast_bad_expr(f, token, f->curr_token); + } + + skip_possible_newline_for_literal(f); + Token open = expect_token_after(f, Token_OpenBrace, "bit_field"); + + + auto fields = array_make(ast_allocator(f), 0, 0); + + while (f->curr_token.kind != Token_CloseBrace && + f->curr_token.kind != Token_EOF) { + CommentGroup *docs = nullptr; + CommentGroup *comment = nullptr; + + Ast *name = parse_ident(f); + expect_token(f, Token_Colon); + Ast *type = parse_type(f); + expect_token(f, Token_Or); + Ast *bit_size = parse_expr(f, true); + + Ast *bf_field = ast_bit_field_field(f, name, type, bit_size, docs, comment); + array_add(&fields, bf_field); + + if (!allow_field_separator(f)) { + break; + } + } + + Token close = expect_closing_brace_of_field_list(f); + + f->expr_level = prev_level; + + return ast_bit_field_type(f, token, backing_type, open, fields, close); + } + + case Token_struct: { Token token = expect_token(f, Token_struct); Ast *polymorphic_params = nullptr; diff --git a/src/parser.hpp b/src/parser.hpp index 1edb1f9dd..ff77c88c7 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -650,6 +650,13 @@ AST_KIND(_DeclEnd, "", bool) \ CommentGroup * docs; \ CommentGroup * comment; \ }) \ + AST_KIND(BitFieldField, "bit field field", struct { \ + Ast * name; \ + Ast * type; \ + Ast * bit_size; \ + CommentGroup *docs; \ + CommentGroup *comment; \ + }) \ AST_KIND(FieldList, "field list", struct { \ Token token; \ Slice list; \ @@ -742,6 +749,14 @@ AST_KIND(_TypeBegin, "", bool) \ Ast * elem; \ Ast * underlying; \ }) \ + AST_KIND(BitFieldType, "bit field type", struct { \ + Scope *scope; \ + Token token; \ + Ast * backing_type; \ + Token open; \ + Slice fields; /* BitFieldField */ \ + Token close; \ + }) \ AST_KIND(MapType, "map type", struct { \ Token token; \ Ast *count; \ diff --git a/src/parser_pos.cpp b/src/parser_pos.cpp index f49c40f16..b2e12999b 100644 --- a/src/parser_pos.cpp +++ b/src/parser_pos.cpp @@ -111,6 +111,7 @@ gb_internal Token ast_token(Ast *node) { case Ast_UnionType: return node->UnionType.token; case Ast_EnumType: return node->EnumType.token; case Ast_BitSetType: return node->BitSetType.token; + case Ast_BitFieldType: return node->BitFieldType.token; case Ast_MapType: return node->MapType.token; case Ast_MatrixType: return node->MatrixType.token; } @@ -364,6 +365,8 @@ Token ast_end_token(Ast *node) { return ast_end_token(node->BitSetType.underlying); } return ast_end_token(node->BitSetType.elem); + case Ast_BitFieldType: + return node->BitFieldType.close; case Ast_MapType: return ast_end_token(node->MapType.value); case Ast_MatrixType: return ast_end_token(node->MatrixType.elem); } diff --git a/src/types.cpp b/src/types.cpp index 78d281715..1c28e6583 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -282,6 +282,13 @@ struct TypeProc { Type *generic_column_count; \ i64 stride_in_bytes; \ }) \ + TYPE_KIND(BitField, struct { \ + Scope * scope; \ + Type * backing_type; \ + Slice fields; \ + Slice bit_sizes; \ + Ast * node; \ + }) \ TYPE_KIND(SoaPointer, struct { Type *elem; }) @@ -355,6 +362,7 @@ enum Typeid_Kind : u8 { Typeid_Relative_Multi_Pointer, Typeid_Matrix, Typeid_SoaPointer, + Typeid_Bit_Field, }; // IMPORTANT NOTE(bill): This must match the same as the in core.odin @@ -641,6 +649,7 @@ gb_global Type *t_type_info_relative_pointer = 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; +gb_global Type *t_type_info_bit_field = nullptr; gb_global Type *t_type_info_named_ptr = nullptr; gb_global Type *t_type_info_integer_ptr = nullptr; @@ -670,6 +679,7 @@ gb_global Type *t_type_info_relative_pointer_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; +gb_global Type *t_type_info_bit_field_ptr = nullptr; gb_global Type *t_allocator = nullptr; gb_global Type *t_allocator_ptr = nullptr; @@ -1040,6 +1050,11 @@ gb_internal Type *alloc_type_enum() { return t; } +gb_internal Type *alloc_type_bit_field() { + Type *t = alloc_type(Type_BitField); + return t; +} + gb_internal Type *alloc_type_relative_pointer(Type *pointer_type, Type *base_integer) { GB_ASSERT(is_type_pointer(pointer_type)); GB_ASSERT(is_type_integer(base_integer)); @@ -1707,6 +1722,10 @@ gb_internal bool is_type_bit_set(Type *t) { t = base_type(t); return (t->kind == Type_BitSet); } +gb_internal bool is_type_bit_field(Type *t) { + t = base_type(t); + return (t->kind == Type_BitField); +} gb_internal bool is_type_map(Type *t) { t = base_type(t); return t->kind == Type_Map; @@ -3568,6 +3587,8 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) { case Type_Slice: return build_context.int_size; + case Type_BitField: + return type_align_of_internal(t->BitField.backing_type, path); case Type_Tuple: { i64 max = 1; @@ -3943,6 +3964,9 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) { return stride_in_bytes * t->Matrix.column_count; } + case Type_BitField: + return type_size_of_internal(t->BitField.backing_type, path); + case Type_RelativePointer: return type_size_of_internal(t->RelativePointer.base_integer, path); case Type_RelativeMultiPointer: -- cgit v1.2.3 From ff24cfe314b0dc121a5ab6d600ae06c31a29b3d3 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 1 Mar 2024 14:00:14 +0000 Subject: Fix debug issue with `map`s --- src/llvm_backend_debug.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 7d3692a53..c06026568 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -746,8 +746,8 @@ gb_internal void lb_debug_complete_types(lbModule *m) { case Type_Map: GB_ASSERT(t_raw_map != nullptr); - bt = base_type(bt->Map.debug_metadata_type); - // bt = base_type(t_raw_map); + // bt = base_type(bt->Map.debug_metadata_type); + bt = base_type(t_raw_map); GB_ASSERT(bt->kind == Type_Struct); /*fallthrough*/ case Type_Struct: -- cgit v1.2.3 From 915f63b3f92bc17e4a5875623f46e167dcd17322 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Fri, 29 Mar 2024 22:42:12 +0100 Subject: fix a segfault when incomplete types array resizes while processing --- src/llvm_backend_debug.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index c06026568..9ecacb4f4 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -652,7 +652,9 @@ gb_internal void lb_debug_complete_types(lbModule *m) { for_array(debug_incomplete_type_index, m->debug_incomplete_types) { TEMPORARY_ALLOCATOR_GUARD(); - auto const &idt = m->debug_incomplete_types[debug_incomplete_type_index]; + // NOTE(laytan): don't make this a pointer, the array could resize while in this iteration + // and cause a use-after-free at the end. + auto const idt = m->debug_incomplete_types[debug_incomplete_type_index]; GB_ASSERT(idt.type != nullptr); GB_ASSERT(idt.metadata != nullptr); -- cgit v1.2.3 From 4edcaa6124eac5e73359ff98239be6f447a42f47 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 30 Mar 2024 10:29:20 +0000 Subject: Try storing a pointer to a fake metadata type in the debug info for a `map` --- src/check_type.cpp | 10 ++++------ src/llvm_backend_debug.cpp | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/check_type.cpp b/src/check_type.cpp index 40a7ec947..2846aae86 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2526,18 +2526,16 @@ gb_internal void init_map_internal_types(Type *type) { gb_unused(type_size_of(metadata_type)); - // NOTE(bill): [0]^struct{key: Key, value: Value, hash: uintptr} - // This is a zero array to a pointer to keep the alignment to that of a pointer, and not effective the size of the final struct - metadata_type = alloc_type_array(alloc_type_pointer(metadata_type), 0);; + // NOTE(bill): ^struct{key: Key, value: Value, hash: uintptr} + metadata_type = alloc_type_pointer(metadata_type); Scope *scope = create_scope(nullptr, nullptr); Type *debug_type = alloc_type_struct(); - debug_type->Struct.fields = slice_make(permanent_allocator(), 4); - debug_type->Struct.fields[0] = alloc_entity_field(scope, make_token_ident("data"), t_uintptr, false, 0, EntityState_Resolved); + debug_type->Struct.fields = slice_make(permanent_allocator(), 3); + debug_type->Struct.fields[0] = alloc_entity_field(scope, make_token_ident("data"), metadata_type, false, 0, EntityState_Resolved); debug_type->Struct.fields[1] = alloc_entity_field(scope, make_token_ident("len"), t_int, false, 1, EntityState_Resolved); debug_type->Struct.fields[2] = alloc_entity_field(scope, make_token_ident("allocator"), t_allocator, false, 2, EntityState_Resolved); - debug_type->Struct.fields[3] = alloc_entity_field(scope, make_token_ident("__metadata"), metadata_type, false, 3, EntityState_Resolved); debug_type->Struct.scope = scope; debug_type->Struct.node = nullptr; wait_signal_set(&debug_type->Struct.fields_wait_signal); diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 9ecacb4f4..048f5f933 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -748,8 +748,8 @@ gb_internal void lb_debug_complete_types(lbModule *m) { case Type_Map: GB_ASSERT(t_raw_map != nullptr); - // bt = base_type(bt->Map.debug_metadata_type); - bt = base_type(t_raw_map); + bt = base_type(bt->Map.debug_metadata_type); + // bt = base_type(t_raw_map); GB_ASSERT(bt->kind == Type_Struct); /*fallthrough*/ case Type_Struct: -- cgit v1.2.3 From 9647cb74ad7f72b25a1cd513a153871dc00b036d Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 1 Apr 2024 00:29:57 +0200 Subject: debug info fixes/refactor This fixes (on my end) #3340, #3117, #2945, #2922, and #2762 A general refactor of debug info generation in order to fix issues and increase stability. What I believe is the root cause of a bunch of issues is that we use the temporary metadata/forward declarations too much (/ hold onto them for too long). It seems to cause problems with the reference counting inside LLVM. This PR reduces the use of these forward declarations to a minimum, it creates it, fills in the fields, and resolves it, instead of waiting until the end of generating code. Some smaller issues I came across have also been solved. --- src/llvm_backend.cpp | 6 - src/llvm_backend.hpp | 2 - src/llvm_backend_debug.cpp | 975 ++++++++++++++++++++++--------------------- src/llvm_backend_general.cpp | 1 - 4 files changed, 495 insertions(+), 489 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index cc9b3ac5d..645a091b0 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -1975,12 +1975,6 @@ gb_internal void lb_generate_missing_procedures(lbGenerator *gen, bool do_thread } gb_internal void lb_debug_info_complete_types_and_finalize(lbGenerator *gen) { - for (auto const &entry : gen->modules) { - lbModule *m = entry.value; - if (m->debug_builder != nullptr) { - lb_debug_complete_types(m); - } - } for (auto const &entry : gen->modules) { lbModule *m = entry.value; if (m->debug_builder != nullptr) { diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 6000be32d..c4bf2691d 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -199,8 +199,6 @@ struct lbModule { RecursiveMutex debug_values_mutex; PtrMap debug_values; - Array debug_incomplete_types; - StringMap objc_classes; StringMap objc_selectors; diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 048f5f933..2bcf6e24b 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -114,6 +114,464 @@ gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &nam return LLVMDIBuilderCreateStructType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, 1, size_in_bits, align_in_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0); } +gb_internal LLVMMetadataRef lb_debug_struct(lbModule *m, Type *type, Type *bt, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { + GB_ASSERT(bt->kind == Type_Struct); + + unsigned const int_bits = cast(unsigned)(8*build_context.int_size); + + unsigned tag = DW_TAG_structure_type; + if (is_type_raw_union(bt)) { + tag = DW_TAG_union_type; + } + + u64 size_in_bits = 8*type_size_of(bt); + u32 align_in_bits = 8*cast(u32)type_align_of(bt); + + LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType( + m->debug_builder, tag, + cast(char const *)name.text, cast(size_t)name.len, + scope, file, line, 0, size_in_bits, align_in_bits, LLVMDIFlagZero, "", 0 + ); + + lb_set_llvm_metadata(m, type, temp_forward_decl); + + isize element_offset = 0; + switch (type->Struct.soa_kind) { + case StructSoa_Slice: element_offset = 1; break; + case StructSoa_Dynamic: element_offset = 3; break; + } + + type_set_offsets(bt); + + unsigned element_count = cast(unsigned)(bt->Struct.fields.count + element_offset); + LLVMMetadataRef *elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); + + LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Struct.scope); + + isize field_size_bits = 8*type_size_of(bt) - element_offset*int_bits; + + switch (bt->Struct.soa_kind) { + case StructSoa_Slice: + elements[0] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "len", 3, + file, line, + 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), + field_size_bits, + LLVMDIFlagZero, lb_debug_type(m, t_int) + ); + break; + case StructSoa_Dynamic: + elements[0] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "len", 3, + file, line, + 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), + field_size_bits + 0*int_bits, + LLVMDIFlagZero, lb_debug_type(m, t_int) + ); + elements[1] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "cap", 3, + file, line, + 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), + field_size_bits + 1*int_bits, + LLVMDIFlagZero, lb_debug_type(m, t_int) + ); + elements[2] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "allocator", 9, + file, line, + 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), + field_size_bits + 2*int_bits, + LLVMDIFlagZero, lb_debug_type(m, t_allocator) + ); + break; + } + + for_array(j, bt->Struct.fields) { + Entity *f = bt->Struct.fields[j]; + String fname = f->token.string; + + unsigned field_line = 0; + LLVMDIFlags field_flags = LLVMDIFlagZero; + GB_ASSERT(bt->Struct.offsets != nullptr); + u64 offset_in_bits = 8*cast(u64)bt->Struct.offsets[j]; + + elements[j] = LLVMDIBuilderCreateMemberType( + m->debug_builder, + member_scope, + cast(char const *)fname.text, cast(size_t)fname.len, + file, field_line, + 8*cast(u64)type_size_of(f->type), 8*cast(u32)type_align_of(f->type), + offset_in_bits, + field_flags, + lb_debug_type(m, f->type) + ); + } + + LLVMMetadataRef final_decl = nullptr; + if (tag == DW_TAG_union_type) { + final_decl = LLVMDIBuilderCreateUnionType( + m->debug_builder, scope, + cast(char const*)name.text, cast(size_t)name.len, + file, line, + size_in_bits, align_in_bits, + LLVMDIFlagZero, + elements, element_count, + 0, + "", 0 + ); + } else { + final_decl = LLVMDIBuilderCreateStructType( + m->debug_builder, scope, + cast(char const *)name.text, cast(size_t)name.len, + file, line, + size_in_bits, align_in_bits, + LLVMDIFlagZero, + nullptr, + elements, element_count, + 0, + nullptr, + "", 0 + ); + } + + LLVMMetadataReplaceAllUsesWith(temp_forward_decl, final_decl); + lb_set_llvm_metadata(m, type, final_decl); + return final_decl; +} + +gb_internal LLVMMetadataRef lb_debug_slice(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { + Type *bt = base_type(type); + GB_ASSERT(bt->kind == Type_Slice); + + unsigned const ptr_bits = cast(unsigned)(8*build_context.ptr_size); + + u64 size_in_bits = 8*type_size_of(bt); + u32 align_in_bits = 8*cast(u32)type_align_of(bt); + + LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType( + m->debug_builder, DW_TAG_structure_type, + cast(char const *)name.text, cast(size_t)name.len, + scope, file, line, 0, size_in_bits, align_in_bits, LLVMDIFlagZero, "", 0 + ); + + lb_set_llvm_metadata(m, type, temp_forward_decl); + + unsigned element_count = 2; + LLVMMetadataRef elements[2]; + + // LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Slice.scope); + LLVMMetadataRef member_scope = nullptr; + + Type *elem_type = alloc_type_pointer(bt->Slice.elem); + elements[0] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "data", 4, + file, line, + 8*cast(u64)type_size_of(elem_type), 8*cast(u32)type_align_of(elem_type), + 0, + LLVMDIFlagZero, lb_debug_type(m, elem_type) + ); + + elements[1] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "len", 3, + file, line, + 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), + ptr_bits, + LLVMDIFlagZero, lb_debug_type(m, t_int) + ); + + LLVMMetadataRef final_decl = LLVMDIBuilderCreateStructType( + m->debug_builder, scope, + cast(char const *)name.text, cast(size_t)name.len, + file, line, + size_in_bits, align_in_bits, + LLVMDIFlagZero, + nullptr, + elements, element_count, + 0, + nullptr, + "", 0 + ); + + LLVMMetadataReplaceAllUsesWith(temp_forward_decl, final_decl); + lb_set_llvm_metadata(m, type, final_decl); + return final_decl; +} + +gb_internal LLVMMetadataRef lb_debug_dynamic_array(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { + Type *bt = base_type(type); + GB_ASSERT(bt->kind == Type_DynamicArray); + + unsigned const ptr_bits = cast(unsigned)(8*build_context.ptr_size); + unsigned const int_bits = cast(unsigned)(8*build_context.int_size); + + u64 size_in_bits = 8*type_size_of(bt); + u32 align_in_bits = 8*cast(u32)type_align_of(bt); + + LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType( + m->debug_builder, DW_TAG_structure_type, + cast(char const *)name.text, cast(size_t)name.len, + scope, file, line, 0, size_in_bits, align_in_bits, LLVMDIFlagZero, "", 0 + ); + + lb_set_llvm_metadata(m, type, temp_forward_decl); + + unsigned element_count = 4; + LLVMMetadataRef elements[4]; + + // LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->DynamicArray.scope); + LLVMMetadataRef member_scope = nullptr; + + Type *elem_type = alloc_type_pointer(bt->DynamicArray.elem); + elements[0] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "data", 4, + file, line, + 8*cast(u64)type_size_of(elem_type), 8*cast(u32)type_align_of(elem_type), + 0, + LLVMDIFlagZero, lb_debug_type(m, elem_type) + ); + + elements[1] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "len", 3, + file, line, + 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), + ptr_bits, + LLVMDIFlagZero, lb_debug_type(m, t_int) + ); + + elements[2] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "cap", 3, + file, line, + 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), + ptr_bits+int_bits, + LLVMDIFlagZero, lb_debug_type(m, t_int) + ); + + elements[3] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "allocator", 9, + file, line, + 8*cast(u64)type_size_of(t_allocator), 8*cast(u32)type_align_of(t_allocator), + ptr_bits+int_bits+int_bits, + LLVMDIFlagZero, lb_debug_type(m, t_allocator) + ); + + LLVMMetadataRef final_decl = LLVMDIBuilderCreateStructType( + m->debug_builder, scope, + cast(char const *)name.text, cast(size_t)name.len, + file, line, + size_in_bits, align_in_bits, + LLVMDIFlagZero, + nullptr, + elements, element_count, + 0, + nullptr, + "", 0 + ); + + LLVMMetadataReplaceAllUsesWith(temp_forward_decl, final_decl); + lb_set_llvm_metadata(m, type, final_decl); + return final_decl; +} + +gb_internal LLVMMetadataRef lb_debug_union(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { + Type *bt = base_type(type); + GB_ASSERT(bt->kind == Type_Union); + + u64 size_in_bits = 8*type_size_of(bt); + u32 align_in_bits = 8*cast(u32)type_align_of(bt); + + LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType( + m->debug_builder, DW_TAG_union_type, + cast(char const *)name.text, cast(size_t)name.len, + scope, file, line, 0, size_in_bits, align_in_bits, LLVMDIFlagZero, "", 0 + ); + + lb_set_llvm_metadata(m, type, temp_forward_decl); + + isize index_offset = 1; + if (is_type_union_maybe_pointer(bt)) { + index_offset = 0; + } + + LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Union.scope); + unsigned element_count = cast(unsigned)bt->Union.variants.count; + if (index_offset > 0) { + element_count += 1; + } + + LLVMMetadataRef *elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); + + if (index_offset > 0) { + Type *tag_type = union_tag_type(bt); + u64 offset_in_bits = 8*cast(u64)bt->Union.variant_block_size; + + elements[0] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + "tag", 3, + file, line, + 8*cast(u64)type_size_of(tag_type), 8*cast(u32)type_align_of(tag_type), + offset_in_bits, + LLVMDIFlagZero, lb_debug_type(m, tag_type) + ); + } + + for_array(j, bt->Union.variants) { + Type *variant = bt->Union.variants[j]; + + unsigned field_index = cast(unsigned)(index_offset+j); + + char name[16] = {}; + gb_snprintf(name, gb_size_of(name), "v%u", field_index); + isize name_len = gb_strlen(name); + + elements[field_index] = LLVMDIBuilderCreateMemberType( + m->debug_builder, member_scope, + name, name_len, + file, line, + 8*cast(u64)type_size_of(variant), 8*cast(u32)type_align_of(variant), + 0, + LLVMDIFlagZero, lb_debug_type(m, variant) + ); + } + + LLVMMetadataRef final_decl = LLVMDIBuilderCreateUnionType( + m->debug_builder, + scope, + cast(char const *)name.text, cast(size_t)name.len, + file, line, + size_in_bits, align_in_bits, + LLVMDIFlagZero, + elements, + element_count, + 0, + "", 0 + ); + + LLVMMetadataReplaceAllUsesWith(temp_forward_decl, final_decl); + lb_set_llvm_metadata(m, type, final_decl); + return final_decl; +} + +gb_internal LLVMMetadataRef lb_debug_bitset(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { + Type *bt = base_type(type); + GB_ASSERT(bt->kind == Type_BitSet); + + u64 size_in_bits = 8*type_size_of(bt); + u32 align_in_bits = 8*cast(u32)type_align_of(bt); + + LLVMMetadataRef bit_set_field_type = lb_debug_type(m, t_bool); + + unsigned element_count = 0; + LLVMMetadataRef *elements = nullptr; + + Type *elem = base_type(bt->BitSet.elem); + if (elem->kind == Type_Enum) { + element_count = cast(unsigned)elem->Enum.fields.count; + elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); + + for_array(i, elem->Enum.fields) { + Entity *f = elem->Enum.fields[i]; + GB_ASSERT(f->kind == Entity_Constant); + i64 val = exact_value_to_i64(f->Constant.value); + String field_name = f->token.string; + u64 offset_in_bits = cast(u64)(val - bt->BitSet.lower); + elements[i] = LLVMDIBuilderCreateBitFieldMemberType( + m->debug_builder, + scope, + cast(char const *)field_name.text, field_name.len, + file, line, + 1, + offset_in_bits, + 0, + LLVMDIFlagZero, + bit_set_field_type + ); + } + } else { + char name[32] = {}; + + GB_ASSERT(is_type_integer(elem)); + i64 count = bt->BitSet.upper - bt->BitSet.lower + 1; + GB_ASSERT(0 <= count); + + element_count = cast(unsigned)count; + elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); + + for (unsigned i = 0; i < element_count; i++) { + u64 offset_in_bits = i; + i64 val = bt->BitSet.lower + cast(i64)i; + gb_snprintf(name, gb_count_of(name), "%lld", cast(long long)val); + elements[i] = LLVMDIBuilderCreateBitFieldMemberType( + m->debug_builder, + scope, + name, gb_strlen(name), + file, line, + 1, + offset_in_bits, + 0, + LLVMDIFlagZero, + bit_set_field_type + ); + } + } + + LLVMMetadataRef final_decl = LLVMDIBuilderCreateUnionType( + m->debug_builder, + scope, + cast(char const *)name.text, cast(size_t)name.len, + file, line, + size_in_bits, align_in_bits, + LLVMDIFlagZero, + elements, + element_count, + 0, + "", 0 + ); + lb_set_llvm_metadata(m, type, final_decl); + return final_decl; +} + +gb_internal LLVMMetadataRef lb_debug_enum(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { + Type *bt = base_type(type); + GB_ASSERT(bt->kind == Type_Enum); + + u64 size_in_bits = 8*type_size_of(bt); + u32 align_in_bits = 8*cast(u32)type_align_of(bt); + + unsigned element_count = cast(unsigned)bt->Enum.fields.count; + LLVMMetadataRef *elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); + + Type *bt_enum = base_enum_type(bt); + LLVMBool is_unsigned = is_type_unsigned(bt_enum); + for (unsigned i = 0; i < element_count; i++) { + Entity *f = bt->Enum.fields[i]; + GB_ASSERT(f->kind == Entity_Constant); + String enum_name = f->token.string; + i64 value = exact_value_to_i64(f->Constant.value); + elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)enum_name.text, cast(size_t)enum_name.len, value, is_unsigned); + } + + LLVMMetadataRef class_type = lb_debug_type(m, bt_enum); + LLVMMetadataRef final_decl = LLVMDIBuilderCreateEnumerationType( + m->debug_builder, + scope, + cast(char const *)name.text, cast(size_t)name.len, + file, line, + size_in_bits, align_in_bits, + elements, element_count, + class_type + ); + lb_set_llvm_metadata(m, type, final_decl); + return final_decl; +} gb_internal LLVMMetadataRef lb_debug_type_basic_type(lbModule *m, String const &name, u64 size_in_bits, LLVMDWARFTypeEncoding encoding, LLVMDIFlags flags = LLVMDIFlagZero) { LLVMMetadataRef basic_type = LLVMDIBuilderCreateBasicType(m->debug_builder, cast(char const *)name.text, name.len, size_in_bits, encoding, flags); @@ -329,53 +787,19 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { return LLVMDIBuilderCreateTypedef(m->debug_builder, array_type, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type))); } + case Type_Map: { + Type *bt = base_type(type->Map.debug_metadata_type); + GB_ASSERT(bt->kind == Type_Struct); - case Type_Struct: - case Type_Union: - case Type_Slice: - case Type_DynamicArray: - case Type_Map: - case Type_BitSet: - { - unsigned tag = DW_TAG_structure_type; - if (is_type_raw_union(type) || is_type_union(type)) { - tag = DW_TAG_union_type; - } - u64 size_in_bits = cast(u64)(8*type_size_of(type)); - u32 align_in_bits = cast(u32)(8*type_size_of(type)); - LLVMDIFlags flags = LLVMDIFlagZero; - - LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType( - m->debug_builder, tag, "", 0, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0 - ); - lbIncompleteDebugType idt = {}; - idt.type = type; - idt.metadata = temp_forward_decl; - - array_add(&m->debug_incomplete_types, idt); - lb_set_llvm_metadata(m, type, temp_forward_decl); - return temp_forward_decl; - } + return lb_debug_struct(m, type, bt, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); + } - case Type_Enum: - { - LLVMMetadataRef scope = nullptr; - LLVMMetadataRef file = nullptr; - unsigned line = 0; - unsigned element_count = cast(unsigned)type->Enum.fields.count; - LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count); - Type *bt = base_enum_type(type); - LLVMBool is_unsigned = is_type_unsigned(bt); - for (unsigned i = 0; i < element_count; i++) { - Entity *f = type->Enum.fields[i]; - GB_ASSERT(f->kind == Entity_Constant); - String name = f->token.string; - i64 value = exact_value_to_i64(f->Constant.value); - elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned); - } - LLVMMetadataRef class_type = lb_debug_type(m, bt); - return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, "", 0, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type); - } + case Type_Struct: return lb_debug_struct( m, type, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); + case Type_Slice: return lb_debug_slice( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); + case Type_DynamicArray: return lb_debug_dynamic_array(m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); + case Type_Union: return lb_debug_union( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); + case Type_BitSet: return lb_debug_bitset( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); + case Type_Enum: return lb_debug_enum( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); case Type_Tuple: if (type->Tuple.variables.count == 1) { @@ -539,7 +963,6 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) { unsigned line = 0; LLVMMetadataRef scope = nullptr; - if (type->Named.type_name != nullptr) { Entity *e = type->Named.type_name; scope = lb_get_base_scope_metadata(m, e->scope); @@ -548,456 +971,48 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) { } line = cast(unsigned)e->token.pos.line; } - // TODO(bill): location data for Type_Named - u64 size_in_bits = 8*type_size_of(type); - u32 align_in_bits = 8*cast(u32)type_align_of(type); String name = type->Named.name; - char const *name_text = cast(char const *)name.text; - size_t name_len = cast(size_t)name.len; - unsigned tag = DW_TAG_structure_type; - if (is_type_raw_union(type) || is_type_union(type)) { - tag = DW_TAG_union_type; + if (type->Named.type_name && type->Named.type_name->pkg && type->Named.type_name->pkg->name.len != 0) { + name = concatenate3_strings(permanent_allocator(), type->Named.type_name->pkg->name, str_lit("."), type->Named.name); } - LLVMDIFlags flags = LLVMDIFlagZero; Type *bt = base_type(type->Named.base); - lbIncompleteDebugType idt = {}; - idt.type = type; - switch (bt->kind) { - case Type_Enum: - { - unsigned line = 0; - unsigned element_count = cast(unsigned)bt->Enum.fields.count; - LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count); - Type *ct = base_enum_type(type); - LLVMBool is_unsigned = is_type_unsigned(ct); - for (unsigned i = 0; i < element_count; i++) { - Entity *f = bt->Enum.fields[i]; - GB_ASSERT(f->kind == Entity_Constant); - String name = f->token.string; - i64 value = exact_value_to_i64(f->Constant.value); - elements[i] = LLVMDIBuilderCreateEnumerator(m->debug_builder, cast(char const *)name.text, cast(size_t)name.len, value, is_unsigned); - } - LLVMMetadataRef class_type = lb_debug_type(m, ct); - return LLVMDIBuilderCreateEnumerationType(m->debug_builder, scope, name_text, name_len, file, line, 8*type_size_of(type), 8*cast(unsigned)type_align_of(type), elements, element_count, class_type); - } - + default: { + u32 align_in_bits = 8*cast(u32)type_align_of(type); + LLVMMetadataRef debug_bt = lb_debug_type(m, bt); + LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef( + m->debug_builder, + debug_bt, + cast(char const *)name.text, cast(size_t)name.len, + file, line, scope, align_in_bits + ); + lb_set_llvm_metadata(m, type, final_decl); + return final_decl; + } - default: - { - LLVMMetadataRef debug_bt = lb_debug_type(m, bt); - LLVMMetadataRef final_decl = LLVMDIBuilderCreateTypedef(m->debug_builder, debug_bt, name_text, name_len, file, line, scope, align_in_bits); - lb_set_llvm_metadata(m, type, final_decl); - return final_decl; - } + case Type_Map: { + bt = base_type(type->Map.debug_metadata_type); + GB_ASSERT(bt->kind == Type_Struct); + return lb_debug_struct(m, type, bt, name, scope, file, line); + } - case Type_Slice: - case Type_DynamicArray: - case Type_Map: - case Type_Struct: - case Type_Union: - case Type_BitSet: - { - LLVMMetadataRef temp_forward_decl = LLVMDIBuilderCreateReplaceableCompositeType( - m->debug_builder, tag, name_text, name_len, nullptr, nullptr, 0, 0, size_in_bits, align_in_bits, flags, "", 0 - ); - idt.metadata = temp_forward_decl; - - array_add(&m->debug_incomplete_types, idt); - lb_set_llvm_metadata(m, type, temp_forward_decl); - - LLVMMetadataRef dummy = nullptr; - switch (bt->kind) { - case Type_Slice: - dummy = lb_debug_type(m, bt->Slice.elem); - dummy = lb_debug_type(m, alloc_type_pointer(bt->Slice.elem)); - dummy = lb_debug_type(m, t_int); - break; - case Type_DynamicArray: - dummy = lb_debug_type(m, bt->DynamicArray.elem); - dummy = lb_debug_type(m, alloc_type_pointer(bt->DynamicArray.elem)); - dummy = lb_debug_type(m, t_int); - dummy = lb_debug_type(m, t_allocator); - break; - case Type_Map: - dummy = lb_debug_type(m, bt->Map.key); - dummy = lb_debug_type(m, bt->Map.value); - dummy = lb_debug_type(m, t_int); - dummy = lb_debug_type(m, t_allocator); - dummy = lb_debug_type(m, t_uintptr); - break; - case Type_BitSet: - if (bt->BitSet.elem) dummy = lb_debug_type(m, bt->BitSet.elem); - if (bt->BitSet.underlying) dummy = lb_debug_type(m, bt->BitSet.underlying); - break; - } - - return temp_forward_decl; - } + case Type_Struct: return lb_debug_struct(m, type, base_type(type), name, scope, file, line); + case Type_Slice: return lb_debug_slice(m, type, name, scope, file, line); + case Type_DynamicArray: return lb_debug_dynamic_array(m, type, name, scope, file, line); + case Type_Union: return lb_debug_union(m, type, name, scope, file, line); + case Type_BitSet: return lb_debug_bitset(m, type, name, scope, file, line); + case Type_Enum: return lb_debug_enum(m, type, name, scope, file, line); } } - LLVMMetadataRef dt = lb_debug_type_internal(m, type); lb_set_llvm_metadata(m, type, dt); return dt; } -gb_internal void lb_debug_complete_types(lbModule *m) { - unsigned const int_bits = cast(unsigned)(8*build_context.int_size); - - for_array(debug_incomplete_type_index, m->debug_incomplete_types) { - TEMPORARY_ALLOCATOR_GUARD(); - - // NOTE(laytan): don't make this a pointer, the array could resize while in this iteration - // and cause a use-after-free at the end. - auto const idt = m->debug_incomplete_types[debug_incomplete_type_index]; - GB_ASSERT(idt.type != nullptr); - GB_ASSERT(idt.metadata != nullptr); - - Type *t = idt.type; - Type *bt = base_type(t); - - LLVMMetadataRef parent_scope = nullptr; - LLVMMetadataRef file = nullptr; - unsigned line_number = 0; - u64 size_in_bits = 8*type_size_of(t); - u32 align_in_bits = cast(u32)(8*type_align_of(t)); - LLVMDIFlags flags = LLVMDIFlagZero; - - LLVMMetadataRef derived_from = nullptr; - - LLVMMetadataRef *elements = nullptr; - unsigned element_count = 0; - - - unsigned runtime_lang = 0; // Objective-C runtime version - char const *unique_id = ""; - LLVMMetadataRef vtable_holder = nullptr; - size_t unique_id_len = 0; - - - LLVMMetadataRef record_scope = nullptr; - - switch (bt->kind) { - case Type_Slice: - case Type_DynamicArray: - case Type_Map: - case Type_Struct: - case Type_Union: - case Type_BitSet: { - bool is_union = is_type_raw_union(bt) || is_type_union(bt); - - String name = str_lit(""); - if (t->kind == Type_Named) { - name = t->Named.name; - if (t->Named.type_name && t->Named.type_name->pkg && t->Named.type_name->pkg->name.len != 0) { - name = concatenate3_strings(temporary_allocator(), t->Named.type_name->pkg->name, str_lit("."), t->Named.name); - } - - LLVMMetadataRef file = nullptr; - unsigned line = 0; - LLVMMetadataRef file_scope = nullptr; - - if (t->Named.type_name != nullptr) { - Entity *e = t->Named.type_name; - file_scope = lb_get_llvm_metadata(m, e->scope); - if (file_scope != nullptr) { - file = LLVMDIScopeGetFile(file_scope); - } - line = cast(unsigned)e->token.pos.line; - } - // TODO(bill): location data for Type_Named - - } else { - name = make_string_c(type_to_string(t, temporary_allocator())); - } - - - - switch (bt->kind) { - case Type_Slice: - element_count = 2; - elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); - #if defined(GB_SYSTEM_WINDOWS) - elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->Slice.elem), 0*int_bits); - #else - // FIX HACK TODO(bill): For some reason this causes a crash in *nix systems due to the reference counting - // of the debug type information - elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*int_bits); - #endif - elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*int_bits); - break; - case Type_DynamicArray: - element_count = 4; - elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); - #if defined(GB_SYSTEM_WINDOWS) - elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->DynamicArray.elem), 0*int_bits); - #else - // FIX HACK TODO(bill): For some reason this causes a crash in *nix systems due to the reference counting - // of the debug type information - elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*int_bits); - #endif - elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*int_bits); - elements[2] = lb_debug_struct_field(m, str_lit("cap"), t_int, 2*int_bits); - elements[3] = lb_debug_struct_field(m, str_lit("allocator"), t_allocator, 3*int_bits); - break; - - case Type_Map: - GB_ASSERT(t_raw_map != nullptr); - bt = base_type(bt->Map.debug_metadata_type); - // bt = base_type(t_raw_map); - GB_ASSERT(bt->kind == Type_Struct); - /*fallthrough*/ - case Type_Struct: - if (file == nullptr) { - if (bt->Struct.node) { - file = lb_get_llvm_metadata(m, bt->Struct.node->file()); - line_number = cast(unsigned)ast_token(bt->Struct.node).pos.line; - } - } - - type_set_offsets(bt); - { - isize element_offset = 0; - record_scope = lb_get_llvm_metadata(m, bt->Struct.scope); - switch (bt->Struct.soa_kind) { - case StructSoa_Slice: element_offset = 1; break; - case StructSoa_Dynamic: element_offset = 3; break; - } - element_count = cast(unsigned)(bt->Struct.fields.count + element_offset); - elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); - - isize field_size_bits = 8*type_size_of(bt) - element_offset*int_bits; - - switch (bt->Struct.soa_kind) { - case StructSoa_Slice: - elements[0] = LLVMDIBuilderCreateMemberType( - m->debug_builder, record_scope, - ".len", 4, - file, 0, - 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), - field_size_bits, - LLVMDIFlagZero, lb_debug_type(m, t_int) - ); - break; - case StructSoa_Dynamic: - elements[0] = LLVMDIBuilderCreateMemberType( - m->debug_builder, record_scope, - ".len", 4, - file, 0, - 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), - field_size_bits + 0*int_bits, - LLVMDIFlagZero, lb_debug_type(m, t_int) - ); - elements[1] = LLVMDIBuilderCreateMemberType( - m->debug_builder, record_scope, - ".cap", 4, - file, 0, - 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), - field_size_bits + 1*int_bits, - LLVMDIFlagZero, lb_debug_type(m, t_int) - ); - elements[2] = LLVMDIBuilderCreateMemberType( - m->debug_builder, record_scope, - ".allocator", 10, - file, 0, - 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), - field_size_bits + 2*int_bits, - LLVMDIFlagZero, lb_debug_type(m, t_allocator) - ); - break; - } - - for_array(j, bt->Struct.fields) { - Entity *f = bt->Struct.fields[j]; - String fname = f->token.string; - - unsigned field_line = 0; - LLVMDIFlags field_flags = LLVMDIFlagZero; - GB_ASSERT(bt->Struct.offsets != nullptr); - u64 offset_in_bits = 8*cast(u64)bt->Struct.offsets[j]; - - elements[element_offset+j] = LLVMDIBuilderCreateMemberType( - m->debug_builder, record_scope, - cast(char const *)fname.text, cast(size_t)fname.len, - file, field_line, - 8*cast(u64)type_size_of(f->type), 8*cast(u32)type_align_of(f->type), - offset_in_bits, - field_flags, lb_debug_type(m, f->type) - ); - } - } - break; - case Type_Union: - { - if (file == nullptr) { - GB_ASSERT(bt->Union.node != nullptr); - file = lb_get_llvm_metadata(m, bt->Union.node->file()); - line_number = cast(unsigned)ast_token(bt->Union.node).pos.line; - } - - isize index_offset = 1; - if (is_type_union_maybe_pointer(bt)) { - index_offset = 0; - } - record_scope = lb_get_llvm_metadata(m, bt->Union.scope); - element_count = cast(unsigned)bt->Union.variants.count; - if (index_offset > 0) { - element_count += 1; - } - - elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); - if (index_offset > 0) { - Type *tag_type = union_tag_type(bt); - unsigned field_line = 0; - u64 offset_in_bits = 8*cast(u64)bt->Union.variant_block_size; - LLVMDIFlags field_flags = LLVMDIFlagZero; - - elements[0] = LLVMDIBuilderCreateMemberType( - m->debug_builder, record_scope, - "tag", 3, - file, field_line, - 8*cast(u64)type_size_of(tag_type), 8*cast(u32)type_align_of(tag_type), - offset_in_bits, - field_flags, lb_debug_type(m, tag_type) - ); - } - - for_array(j, bt->Union.variants) { - Type *variant = bt->Union.variants[j]; - - unsigned field_index = cast(unsigned)(index_offset+j); - - char name[16] = {}; - gb_snprintf(name, gb_size_of(name), "v%u", field_index); - isize name_len = gb_strlen(name); - - unsigned field_line = 0; - LLVMDIFlags field_flags = LLVMDIFlagZero; - u64 offset_in_bits = 0; - - elements[field_index] = LLVMDIBuilderCreateMemberType( - m->debug_builder, record_scope, - name, name_len, - file, field_line, - 8*cast(u64)type_size_of(variant), 8*cast(u32)type_align_of(variant), - offset_in_bits, - field_flags, lb_debug_type(m, variant) - ); - } - } - break; - - case Type_BitSet: - { - if (file == nullptr) { - GB_ASSERT(bt->BitSet.node != nullptr); - file = lb_get_llvm_metadata(m, bt->BitSet.node->file()); - line_number = cast(unsigned)ast_token(bt->BitSet.node).pos.line; - } - - LLVMMetadataRef bit_set_field_type = lb_debug_type(m, t_bool); - LLVMMetadataRef scope = file; - - Type *elem = base_type(bt->BitSet.elem); - if (elem->kind == Type_Enum) { - element_count = cast(unsigned)elem->Enum.fields.count; - elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); - for_array(i, elem->Enum.fields) { - Entity *f = elem->Enum.fields[i]; - GB_ASSERT(f->kind == Entity_Constant); - i64 val = exact_value_to_i64(f->Constant.value); - String name = f->token.string; - u64 offset_in_bits = cast(u64)(val - bt->BitSet.lower); - elements[i] = LLVMDIBuilderCreateBitFieldMemberType( - m->debug_builder, - scope, - cast(char const *)name.text, name.len, - file, line_number, - 1, - offset_in_bits, - 0, - LLVMDIFlagZero, - bit_set_field_type - ); - } - } else { - - char name[32] = {}; - - GB_ASSERT(is_type_integer(elem)); - i64 count = bt->BitSet.upper - bt->BitSet.lower + 1; - GB_ASSERT(0 <= count); - - element_count = cast(unsigned)count; - elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); - for (unsigned i = 0; i < element_count; i++) { - u64 offset_in_bits = i; - i64 val = bt->BitSet.lower + cast(i64)i; - gb_snprintf(name, gb_count_of(name), "%lld", cast(long long)val); - elements[i] = LLVMDIBuilderCreateBitFieldMemberType( - m->debug_builder, - scope, - name, gb_strlen(name), - file, line_number, - 1, - offset_in_bits, - 0, - LLVMDIFlagZero, - bit_set_field_type - ); - } - } - } - } - - - LLVMMetadataRef final_metadata = nullptr; - if (is_union) { - final_metadata = LLVMDIBuilderCreateUnionType( - m->debug_builder, - parent_scope, - cast(char const *)name.text, cast(size_t)name.len, - file, line_number, - size_in_bits, align_in_bits, - flags, - elements, element_count, - runtime_lang, - unique_id, unique_id_len - ); - } else { - final_metadata = LLVMDIBuilderCreateStructType( - m->debug_builder, - parent_scope, - cast(char const *)name.text, cast(size_t)name.len, - file, line_number, - size_in_bits, align_in_bits, - flags, - derived_from, - elements, element_count, - runtime_lang, - vtable_holder, - unique_id, unique_id_len - ); - } - - LLVMMetadataReplaceAllUsesWith(idt.metadata, final_metadata); - lb_set_llvm_metadata(m, idt.type, final_metadata); - } break; - default: - GB_PANIC("invalid incomplete debug type"); - break; - } - } - array_clear(&m->debug_incomplete_types); -} - - - gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token) { if (p->debug_info == nullptr) { return; @@ -1267,4 +1282,4 @@ gb_internal void add_debug_info_for_global_constant_from_entity(lbGenerator *gen add_debug_info_for_global_constant_internal_i64(m, e, dtype, v); } } -} \ No newline at end of file +} diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index a77e2ad15..889cb8822 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -81,7 +81,6 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) { array_init(&m->global_procedures_and_types_to_create, a, 0, 1024); array_init(&m->missing_procedures_to_check, a, 0, 16); map_init(&m->debug_values); - array_init(&m->debug_incomplete_types, a, 0, 1024); string_map_init(&m->objc_classes); string_map_init(&m->objc_selectors); -- cgit v1.2.3 From 7c2352ea083132bbe28e41bd958eb6608c4c1986 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 1 Apr 2024 16:48:47 +0200 Subject: remove soa handling in debug info, fields are already added in checker --- src/llvm_backend_debug.cpp | 51 +--------------------------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 2bcf6e24b..1b8e02a36 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -117,8 +117,6 @@ gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &nam gb_internal LLVMMetadataRef lb_debug_struct(lbModule *m, Type *type, Type *bt, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { GB_ASSERT(bt->kind == Type_Struct); - unsigned const int_bits = cast(unsigned)(8*build_context.int_size); - unsigned tag = DW_TAG_structure_type; if (is_type_raw_union(bt)) { tag = DW_TAG_union_type; @@ -135,60 +133,13 @@ gb_internal LLVMMetadataRef lb_debug_struct(lbModule *m, Type *type, Type *bt, S lb_set_llvm_metadata(m, type, temp_forward_decl); - isize element_offset = 0; - switch (type->Struct.soa_kind) { - case StructSoa_Slice: element_offset = 1; break; - case StructSoa_Dynamic: element_offset = 3; break; - } - type_set_offsets(bt); - unsigned element_count = cast(unsigned)(bt->Struct.fields.count + element_offset); + unsigned element_count = cast(unsigned)(bt->Struct.fields.count); LLVMMetadataRef *elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count); LLVMMetadataRef member_scope = lb_get_llvm_metadata(m, bt->Struct.scope); - isize field_size_bits = 8*type_size_of(bt) - element_offset*int_bits; - - switch (bt->Struct.soa_kind) { - case StructSoa_Slice: - elements[0] = LLVMDIBuilderCreateMemberType( - m->debug_builder, member_scope, - "len", 3, - file, line, - 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), - field_size_bits, - LLVMDIFlagZero, lb_debug_type(m, t_int) - ); - break; - case StructSoa_Dynamic: - elements[0] = LLVMDIBuilderCreateMemberType( - m->debug_builder, member_scope, - "len", 3, - file, line, - 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), - field_size_bits + 0*int_bits, - LLVMDIFlagZero, lb_debug_type(m, t_int) - ); - elements[1] = LLVMDIBuilderCreateMemberType( - m->debug_builder, member_scope, - "cap", 3, - file, line, - 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), - field_size_bits + 1*int_bits, - LLVMDIFlagZero, lb_debug_type(m, t_int) - ); - elements[2] = LLVMDIBuilderCreateMemberType( - m->debug_builder, member_scope, - "allocator", 9, - file, line, - 8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int), - field_size_bits + 2*int_bits, - LLVMDIFlagZero, lb_debug_type(m, t_allocator) - ); - break; - } - for_array(j, bt->Struct.fields) { Entity *f = bt->Struct.fields[j]; String fname = f->token.string; -- cgit v1.2.3 From cfc85fd737a5e51e68cf5d87ba4cd8a9846df61d Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 1 Apr 2024 18:42:10 +0200 Subject: fix wrong type in map debug info --- src/llvm_backend_debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 1b8e02a36..faefb569e 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -945,7 +945,7 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) { } case Type_Map: { - bt = base_type(type->Map.debug_metadata_type); + bt = base_type(bt->Map.debug_metadata_type); GB_ASSERT(bt->kind == Type_Struct); return lb_debug_struct(m, type, bt, name, scope, file, line); } -- cgit v1.2.3 From 4fc96e1ca52c8e70cbd6b0f5582b3c469c8a17d2 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 1 Apr 2024 19:05:49 +0200 Subject: change unneeded permanent allocation to temporary --- src/llvm_backend_debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index faefb569e..511ff0475 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -925,7 +925,7 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) { String name = type->Named.name; if (type->Named.type_name && type->Named.type_name->pkg && type->Named.type_name->pkg->name.len != 0) { - name = concatenate3_strings(permanent_allocator(), type->Named.type_name->pkg->name, str_lit("."), type->Named.name); + name = concatenate3_strings(temporary_allocator(), type->Named.type_name->pkg->name, str_lit("."), type->Named.name); } Type *bt = base_type(type->Named.base); -- cgit v1.2.3 From aad41fc76210814f4bf708927a10d17de0e2621d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 18 Apr 2024 11:27:42 +0100 Subject: Fix #3445 --- src/llvm_backend_debug.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 511ff0475..b430cf894 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -739,6 +739,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { } case Type_Map: { + init_map_internal_debug_types(bt); Type *bt = base_type(type->Map.debug_metadata_type); GB_ASSERT(bt->kind == Type_Struct); @@ -945,6 +946,7 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) { } case Type_Map: { + init_map_internal_debug_types(bt); bt = base_type(bt->Map.debug_metadata_type); GB_ASSERT(bt->kind == Type_Struct); return lb_debug_struct(m, type, bt, name, scope, file, line); -- cgit v1.2.3 From f84a09297795bd5c6d00305e0ad32dd696fe36a7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 18 Apr 2024 11:28:46 +0100 Subject: Fix typo. --- src/llvm_backend_debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index b430cf894..853941496 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -739,7 +739,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { } case Type_Map: { - init_map_internal_debug_types(bt); + init_map_internal_debug_types(type); Type *bt = base_type(type->Map.debug_metadata_type); GB_ASSERT(bt->kind == Type_Struct); -- cgit v1.2.3 From 90369b669b5d48f1912f5a3667fcea57a0c4cef2 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Mon, 22 Apr 2024 19:05:50 +0200 Subject: fix direct proc args debug info --- src/llvm_backend_debug.cpp | 12 ++---------- src/llvm_backend_proc.cpp | 13 ++----------- 2 files changed, 4 insertions(+), 21 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 853941496..2654a1d28 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -1027,7 +1027,7 @@ gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, T LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block); } -gb_internal void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block, lbArgKind arg_kind) { +gb_internal void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token, unsigned arg_number, lbBlock *block) { if (p->debug_info == nullptr) { return; } @@ -1088,15 +1088,7 @@ gb_internal void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, T // NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block // The reason is that if the parameter is at index 0 and a pointer, there is not such things as an // instruction "before" it. - switch (arg_kind) { - case lbArg_Direct: - LLVMDIBuilderInsertDbgValueAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); - break; - case lbArg_Indirect: - LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); - break; - } - + LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block->block); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index bb4aed3f1..f73698d34 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -597,16 +597,7 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { lbValue ptr = lb_address_from_load_or_generate_local(p, param); GB_ASSERT(LLVMIsAAllocaInst(ptr.value)); lb_add_entity(p->module, e, ptr); - - lbBlock *block = p->decl_block; - if (original_value != value) { - block = p->curr_block; - } - LLVMValueRef debug_storage_value = value; - if (original_value != value && LLVMIsALoadInst(value)) { - debug_storage_value = LLVMGetOperand(value, 0); - } - lb_add_debug_param_variable(p, debug_storage_value, e->type, e->token, param_index+1, block, arg_type->kind); + lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->curr_block); } } else if (arg_type->kind == lbArg_Indirect) { if (e->token.string.len != 0 && !is_blank_ident(e->token.string)) { @@ -614,7 +605,7 @@ gb_internal void lb_begin_procedure_body(lbProcedure *p) { ptr.value = LLVMGetParam(p->value, param_offset+param_index); ptr.type = alloc_type_pointer(e->type); lb_add_entity(p->module, e, ptr); - lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block, arg_type->kind); + lb_add_debug_param_variable(p, ptr.value, e->type, e->token, param_index+1, p->decl_block); } } } -- cgit v1.2.3 From 7d293898348173f4a8c373c037b3035f83f9dd13 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Tue, 4 Jun 2024 14:21:51 +0200 Subject: fix debug info IR error on LLVM < 13 --- src/llvm_backend_debug.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 2654a1d28..afbf3e046 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -46,6 +46,15 @@ gb_internal LLVMMetadataRef lb_debug_end_location_from_ast(lbProcedure *p, Ast * return lb_debug_location_from_token_pos(p, ast_end_token(node).pos); } +gb_internal void lb_debug_file_line(lbModule *m, Ast *node, LLVMMetadataRef *file, unsigned *line) { + if (*file == nullptr) { + if (node) { + *file = lb_get_llvm_metadata(m, node->file()); + *line = cast(unsigned)ast_token(node).pos.line; + } + } +} + gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) { i64 size = type_size_of(type); // Check size gb_unused(size); @@ -117,6 +126,8 @@ gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &nam gb_internal LLVMMetadataRef lb_debug_struct(lbModule *m, Type *type, Type *bt, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { GB_ASSERT(bt->kind == Type_Struct); + lb_debug_file_line(m, bt->Struct.node, &file, &line); + unsigned tag = DW_TAG_structure_type; if (is_type_raw_union(bt)) { tag = DW_TAG_union_type; @@ -336,6 +347,8 @@ gb_internal LLVMMetadataRef lb_debug_union(lbModule *m, Type *type, String name, Type *bt = base_type(type); GB_ASSERT(bt->kind == Type_Union); + lb_debug_file_line(m, bt->Union.node, &file, &line); + u64 size_in_bits = 8*type_size_of(bt); u32 align_in_bits = 8*cast(u32)type_align_of(bt); @@ -415,6 +428,8 @@ gb_internal LLVMMetadataRef lb_debug_bitset(lbModule *m, Type *type, String name Type *bt = base_type(type); GB_ASSERT(bt->kind == Type_BitSet); + lb_debug_file_line(m, bt->BitSet.node, &file, &line); + u64 size_in_bits = 8*type_size_of(bt); u32 align_in_bits = 8*cast(u32)type_align_of(bt); @@ -494,6 +509,8 @@ gb_internal LLVMMetadataRef lb_debug_enum(lbModule *m, Type *type, String name, Type *bt = base_type(type); GB_ASSERT(bt->kind == Type_Enum); + lb_debug_file_line(m, bt->Enum.node, &file, &line); + u64 size_in_bits = 8*type_size_of(bt); u32 align_in_bits = 8*cast(u32)type_align_of(bt); -- cgit v1.2.3 From eef2aef021a039e627693c73c7962ed57f4ea073 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 10 Jun 2024 15:07:45 +0100 Subject: Fix #3724 --- src/llvm_backend_debug.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index afbf3e046..f1ace5f06 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -626,50 +626,50 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { case Basic_complex32: { LLVMMetadataRef elements[2] = {}; - elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f16, 0); - elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f16, 4); + elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f16, 0*16); + elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f16, 1*16); return lb_debug_basic_struct(m, str_lit("complex32"), 64, 32, elements, gb_count_of(elements)); } case Basic_complex64: { LLVMMetadataRef elements[2] = {}; - elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f32, 0); - elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f32, 4); + elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f32, 0*32); + elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f32, 2*32); return lb_debug_basic_struct(m, str_lit("complex64"), 64, 32, elements, gb_count_of(elements)); } case Basic_complex128: { LLVMMetadataRef elements[2] = {}; - elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f64, 0); - elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f64, 8); + elements[0] = lb_debug_struct_field(m, str_lit("real"), t_f64, 0*64); + elements[1] = lb_debug_struct_field(m, str_lit("imag"), t_f64, 1*64); return lb_debug_basic_struct(m, str_lit("complex128"), 128, 64, elements, gb_count_of(elements)); } case Basic_quaternion64: { LLVMMetadataRef elements[4] = {}; - elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f16, 0); - elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f16, 4); - elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f16, 8); - elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f16, 12); + elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f16, 0*16); + elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f16, 1*16); + elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f16, 2*16); + elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f16, 3*16); return lb_debug_basic_struct(m, str_lit("quaternion64"), 128, 32, elements, gb_count_of(elements)); } case Basic_quaternion128: { LLVMMetadataRef elements[4] = {}; - elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f32, 0); - elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f32, 4); - elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f32, 8); - elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f32, 12); + elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f32, 0*32); + elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f32, 1*32); + elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f32, 2*32); + elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f32, 3*32); return lb_debug_basic_struct(m, str_lit("quaternion128"), 128, 32, elements, gb_count_of(elements)); } case Basic_quaternion256: { LLVMMetadataRef elements[4] = {}; - elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f64, 0); - elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f64, 8); - elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f64, 16); - elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f64, 24); + elements[0] = lb_debug_struct_field(m, str_lit("imag"), t_f64, 0*64); + elements[1] = lb_debug_struct_field(m, str_lit("jmag"), t_f64, 1*64); + elements[2] = lb_debug_struct_field(m, str_lit("kmag"), t_f64, 2*64); + elements[3] = lb_debug_struct_field(m, str_lit("real"), t_f64, 3*64); return lb_debug_basic_struct(m, str_lit("quaternion256"), 256, 32, elements, gb_count_of(elements)); } -- cgit v1.2.3 From 549311fac98ce447e8ab18d365841dc4f0671abf Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 15 Jul 2024 12:21:42 +0100 Subject: Fix global variables being "missing" with `-use-separate-modules` --- src/llvm_backend.cpp | 37 +++++++---------- src/llvm_backend.hpp | 3 +- src/llvm_backend_debug.cpp | 1 + src/llvm_backend_general.cpp | 99 ++++++++++++++++++++++++-------------------- 4 files changed, 73 insertions(+), 67 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index d975ac600..4f3186dba 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -137,18 +137,23 @@ gb_internal void lb_set_entity_from_other_modules_linkage_correctly(lbModule *ot } char const *cname = alloc_cstring(permanent_allocator(), name); mpsc_enqueue(&other_module->gen->entities_to_correct_linkage, lbEntityCorrection{other_module, e, cname}); +} - // LLVMValueRef other_global = nullptr; - // if (e->kind == Entity_Variable) { - // other_global = LLVMGetNamedGlobal(other_module->mod, cname); - // } else if (e->kind == Entity_Procedure) { - // other_global = LLVMGetNamedFunction(other_module->mod, cname); - // } - // if (other_global) { - // LLVMSetLinkage(other_global, LLVMExternalLinkage); - // } +gb_internal void lb_correct_entity_linkage(lbGenerator *gen) { + for (lbEntityCorrection ec = {}; mpsc_dequeue(&gen->entities_to_correct_linkage, &ec); /**/) { + LLVMValueRef other_global = nullptr; + if (ec.e->kind == Entity_Variable) { + other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname); + } else if (ec.e->kind == Entity_Procedure) { + other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname); + } + if (other_global) { + LLVMSetLinkage(other_global, LLVMExternalLinkage); + } + } } + gb_internal void lb_emit_init_context(lbProcedure *p, lbAddr addr) { TEMPORARY_ALLOCATOR_GUARD(); @@ -1386,6 +1391,7 @@ gb_internal void lb_create_global_procedures_and_types(lbGenerator *gen, Checker if (USE_SEPARATE_MODULES) { m = lb_module_of_entity(gen, e); } + GB_ASSERT(m != nullptr); if (e->kind == Entity_Procedure) { array_add(&m->global_procedures_to_create, e); @@ -3431,18 +3437,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { lb_add_foreign_library_paths(gen); TIME_SECTION("LLVM Correct Entity Linkage"); - for (lbEntityCorrection ec = {}; mpsc_dequeue(&gen->entities_to_correct_linkage, &ec); /**/) { - LLVMValueRef other_global = nullptr; - if (ec.e->kind == Entity_Variable) { - other_global = LLVMGetNamedGlobal(ec.other_module->mod, ec.cname); - } else if (ec.e->kind == Entity_Procedure) { - other_global = LLVMGetNamedFunction(ec.other_module->mod, ec.cname); - } - if (other_global) { - LLVMSetLinkage(other_global, LLVMExternalLinkage); - } - } - + lb_correct_entity_linkage(gen); //////////////////////////////////////////// for (auto const &entry: gen->modules) { diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index c4f2bd884..806864c7c 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -147,6 +147,7 @@ struct lbModule { CheckerInfo *info; AstPackage *pkg; // possibly associated AstFile *file; // possibly associated + char const *module_name; PtrMap types; // mutex: types_mutex PtrMap struct_field_remapping; // Key: LLVMTypeRef or Type *, mutex: types_mutex @@ -379,7 +380,7 @@ struct lbProcedure { gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c); -gb_internal String lb_mangle_name(lbModule *m, Entity *e); +gb_internal String lb_mangle_name(Entity *e); gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String name = {}); gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0); diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index f1ace5f06..c896f889d 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -1187,6 +1187,7 @@ gb_internal void add_debug_info_for_global_constant_from_entity(lbGenerator *gen if (USE_SEPARATE_MODULES) { m = lb_module_of_entity(gen, e); } + GB_ASSERT(m != nullptr); if (is_type_integer(e->type)) { ExactValue const &value = e->Constant.value; diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index ba8b13bd8..dbeea1dac 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -29,8 +29,9 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) { module_name = gb_string_appendc(module_name, "-builtin"); } + m->module_name = module_name ? module_name : "odin_package"; m->ctx = LLVMContextCreate(); - m->mod = LLVMModuleCreateWithNameInContext(module_name ? module_name : "odin_package", m->ctx); + m->mod = LLVMModuleCreateWithNameInContext(m->module_name, m->ctx); // m->debug_builder = nullptr; if (build_context.ODIN_DEBUG) { enum {DEBUG_METADATA_VERSION = 3}; @@ -389,12 +390,14 @@ gb_internal lbModule *lb_module_of_entity(lbGenerator *gen, Entity *e) { if (e->file) { found = map_get(&gen->modules, cast(void *)e->file); if (found) { + GB_ASSERT(*found != nullptr); return *found; } } if (e->pkg) { found = map_get(&gen->modules, cast(void *)e->pkg); if (found) { + GB_ASSERT(*found != nullptr); return *found; } } @@ -1532,7 +1535,7 @@ gb_internal void lb_clone_struct_type(LLVMTypeRef dst, LLVMTypeRef src) { LLVMStructSetBody(dst, fields, field_count, LLVMIsPackedStruct(src)); } -gb_internal String lb_mangle_name(lbModule *m, Entity *e) { +gb_internal String lb_mangle_name(Entity *e) { String name = e->token.string; AstPackage *pkg = e->pkg; @@ -1632,6 +1635,7 @@ gb_internal String lb_set_nested_type_name_ir_mangled_name(Entity *e, lbProcedur } gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String default_name) { + GB_ASSERT(m != nullptr); if (e != nullptr && e->kind == Entity_TypeName && e->TypeName.ir_mangled_name.len != 0) { return e->TypeName.ir_mangled_name; } @@ -1663,7 +1667,7 @@ gb_internal String lb_get_entity_name(lbModule *m, Entity *e, String default_nam } if (!no_name_mangle) { - name = lb_mangle_name(m, e); + name = lb_mangle_name(e); } if (name.len == 0) { name = e->token.string; @@ -3039,58 +3043,63 @@ gb_internal lbValue lb_find_value_from_entity(lbModule *m, Entity *e) { return *found; } - if (USE_SEPARATE_MODULES) { - lbModule *other_module = lb_module_of_entity(m->gen, e); + lbValue g = {}; + String name = {}; - bool is_external = other_module != m; - if (!is_external) { - if (e->code_gen_module != nullptr) { - other_module = e->code_gen_module; - } else { - other_module = nullptr; - } - is_external = other_module != m; - } + if (!USE_SEPARATE_MODULES) { + goto failed; + } + lbModule *other_module = lb_module_of_entity(m->gen, e); - if (is_external) { - String name = lb_get_entity_name(other_module, e); + bool is_external = other_module != m; + if (!is_external) { + if (e->code_gen_module != nullptr) { + other_module = e->code_gen_module; + } else { + other_module = &m->gen->default_module; + } + is_external = other_module != m; + } - lbValue g = {}; - g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); - g.type = alloc_type_pointer(e->type); - lb_add_entity(m, e, g); - lb_add_member(m, name, g); + if (!is_external) { + goto failed; + } + name = lb_get_entity_name(other_module, e); - LLVMSetLinkage(g.value, LLVMExternalLinkage); + g.value = LLVMAddGlobal(m->mod, lb_type(m, e->type), alloc_cstring(permanent_allocator(), name)); + g.type = alloc_type_pointer(e->type); + lb_add_entity(m, e, g); + lb_add_member(m, name, g); - lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name); + LLVMSetLinkage(g.value, LLVMExternalLinkage); - // LLVMSetLinkage(other_g.value, LLVMExternalLinkage); - - if (e->Variable.thread_local_model != "") { - LLVMSetThreadLocal(g.value, true); - - String m = e->Variable.thread_local_model; - LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel; - if (m == "default") { - mode = LLVMGeneralDynamicTLSModel; - } else if (m == "localdynamic") { - mode = LLVMLocalDynamicTLSModel; - } else if (m == "initialexec") { - mode = LLVMInitialExecTLSModel; - } else if (m == "localexec") { - mode = LLVMLocalExecTLSModel; - } else { - GB_PANIC("Unhandled thread local mode %.*s", LIT(m)); - } - LLVMSetThreadLocalMode(g.value, mode); - } + lb_set_entity_from_other_modules_linkage_correctly(other_module, e, name); + if (e->Variable.thread_local_model != "") { + LLVMSetThreadLocal(g.value, true); - return g; + String m = e->Variable.thread_local_model; + LLVMThreadLocalMode mode = LLVMGeneralDynamicTLSModel; + if (m == "default") { + mode = LLVMGeneralDynamicTLSModel; + } else if (m == "localdynamic") { + mode = LLVMLocalDynamicTLSModel; + } else if (m == "initialexec") { + mode = LLVMInitialExecTLSModel; + } else if (m == "localexec") { + mode = LLVMLocalExecTLSModel; + } else { + GB_PANIC("Unhandled thread local mode %.*s", LIT(m)); } + LLVMSetThreadLocalMode(g.value, mode); } - GB_PANIC("\n\tError in: %s, missing value '%.*s'\n", token_pos_to_string(e->token.pos), LIT(e->token.string)); + + + return g; + +failed:; + GB_PANIC("\n\tError in: %s, missing value '%.*s' in module %s\n", + token_pos_to_string(e->token.pos), LIT(e->token.string), m->module_name); return {}; } -- cgit v1.2.3 From 8b248673c10b7301b7bbab3ace73b631d3964aee Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 24 Aug 2024 13:36:43 +0100 Subject: Fix #4105 --- src/llvm_backend_debug.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index c896f889d..5d90dccea 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -55,6 +55,16 @@ gb_internal void lb_debug_file_line(lbModule *m, Ast *node, LLVMMetadataRef *fil } } +gb_internal LLVMMetadataRef lb_debug_procedure_parameters(lbModule *m, Type *type) { + if (is_type_proc(type)) { + return lb_debug_type(m, t_rawptr); + } + if (type->kind == Type_Tuple && type->Tuple.variables.count == 1) { + return lb_debug_procedure_parameters(m, type->Tuple.variables[0]->type); + } + return lb_debug_type(m, type); +} + gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) { i64 size = type_size_of(type); // Check size gb_unused(size); @@ -78,7 +88,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) if (type->Proc.result_count == 0) { parameters[param_index++] = nullptr; } else { - parameters[param_index++] = lb_debug_type(m, type->Proc.results); + parameters[param_index++] = lb_debug_procedure_parameters(m, type->Proc.results); } LLVMMetadataRef file = nullptr; @@ -88,7 +98,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) if (e->kind != Entity_Variable) { continue; } - parameters[param_index] = lb_debug_type(m, e->type); + parameters[param_index] = lb_debug_procedure_parameters(m, e->type); param_index += 1; } @@ -969,7 +979,7 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) { return lb_debug_struct(m, type, bt, name, scope, file, line); } - case Type_Struct: return lb_debug_struct(m, type, base_type(type), name, scope, file, line); + case Type_Struct: return lb_debug_struct(m, type, bt, name, scope, file, line); case Type_Slice: return lb_debug_slice(m, type, name, scope, file, line); case Type_DynamicArray: return lb_debug_dynamic_array(m, type, name, scope, file, line); case Type_Union: return lb_debug_union(m, type, name, scope, file, line); -- cgit v1.2.3 From 5a4746c3a077b8a815475a205aaa49233acc92d4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 7 Sep 2024 17:41:16 +0100 Subject: Improve debug information for procedure types --- src/llvm_backend_debug.cpp | 55 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 5d90dccea..68e1efc1c 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -82,13 +82,36 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) parameter_count += 1; } } - LLVMMetadataRef *parameters = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, parameter_count); - unsigned param_index = 0; - if (type->Proc.result_count == 0) { - parameters[param_index++] = nullptr; - } else { - parameters[param_index++] = lb_debug_procedure_parameters(m, type->Proc.results); + auto parameters = array_make(permanent_allocator(), 0, type->Proc.param_count+type->Proc.result_count+2); + + array_add(¶meters, cast(LLVMMetadataRef)nullptr); + + bool return_is_tuple = false; + if (type->Proc.result_count != 0) { + Type *single_ret = reduce_tuple_to_single_type(type->Proc.results); + if (is_type_proc(single_ret)) { + single_ret = t_rawptr; + } + if (is_type_tuple(single_ret) && is_calling_convention_odin(type->Proc.calling_convention)) { + LLVMTypeRef actual = lb_type_internal_for_procedures_raw(m, type); + actual = LLVMGetReturnType(actual); + if (actual == nullptr) { + // results were passed as a single pointer + parameters[0] = lb_debug_procedure_parameters(m, single_ret); + } else { + LLVMTypeRef possible = lb_type(m, type->Proc.results); + if (possible == actual) { + // results were returned directly + parameters[0] = lb_debug_procedure_parameters(m, single_ret); + } else { + // resulsts were returned separately + return_is_tuple = true; + } + } + } else { + parameters[0] = lb_debug_procedure_parameters(m, single_ret); + } } LLVMMetadataRef file = nullptr; @@ -98,8 +121,22 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) if (e->kind != Entity_Variable) { continue; } - parameters[param_index] = lb_debug_procedure_parameters(m, e->type); - param_index += 1; + array_add(¶meters, lb_debug_procedure_parameters(m, e->type)); + } + + + if (return_is_tuple) { + Type *results = type->Proc.results; + GB_ASSERT(results != nullptr && results->kind == Type_Tuple); + isize count = results->Tuple.variables.count; + parameters[0] = lb_debug_procedure_parameters(m, results->Tuple.variables[count-1]->type); + for (isize i = 0; i < count-1; i++) { + array_add(¶meters, lb_debug_procedure_parameters(m, results->Tuple.variables[i]->type)); + } + } + + if (type->Proc.calling_convention == ProcCC_Odin) { + array_add(¶meters, lb_debug_type(m, t_context_ptr)); } LLVMDIFlags flags = LLVMDIFlagZero; @@ -107,7 +144,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) flags = LLVMDIFlagNoReturn; } - return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags); + return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters.data, cast(unsigned)parameters.count, flags); } gb_internal LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &name, Type *type, u64 offset_in_bits) { -- cgit v1.2.3 From 4f3f256375e3ae7e9ac0420fa41a7e6cead4ad72 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sat, 14 Sep 2024 15:52:37 +0200 Subject: improve bit field debug info --- src/llvm_backend_debug.cpp | 80 +++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 36 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 68e1efc1c..bb6a1ba4f 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -552,6 +552,48 @@ gb_internal LLVMMetadataRef lb_debug_bitset(lbModule *m, Type *type, String name return final_decl; } +gb_internal LLVMMetadataRef lb_debug_bitfield(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { + Type *bt = base_type(type); + GB_ASSERT(bt->kind == Type_BitField); + + lb_debug_file_line(m, bt->BitField.node, &file, &line); + + u64 size_in_bits = 8*type_size_of(bt); + u32 align_in_bits = 8*cast(u32)type_align_of(bt); + + unsigned element_count = cast(unsigned)bt->BitField.fields.count; + LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count); + + u64 offset_in_bits = 0; + for (unsigned i = 0; i < element_count; i++) { + Entity *f = bt->BitField.fields[i]; + u8 bit_size = bt->BitField.bit_sizes[i]; + GB_ASSERT(f->kind == Entity_Variable); + String name = f->token.string; + elements[i] = LLVMDIBuilderCreateBitFieldMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, line, + bit_size, offset_in_bits, offset_in_bits, + LLVMDIFlagZero, lb_debug_type(m, f->type) + ); + + offset_in_bits += bit_size; + } + + LLVMMetadataRef final_decl = LLVMDIBuilderCreateStructType( + m->debug_builder, scope, + cast(char const *)name.text, cast(size_t)name.len, + file, line, + size_in_bits, align_in_bits, + LLVMDIFlagZero, + nullptr, + elements, element_count, + 0, + nullptr, + "", 0 + ); + lb_set_llvm_metadata(m, type, final_decl); + return final_decl; +} + gb_internal LLVMMetadataRef lb_debug_enum(lbModule *m, Type *type, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) { Type *bt = base_type(type); GB_ASSERT(bt->kind == Type_Enum); @@ -816,6 +858,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { case Type_Union: return lb_debug_union( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); case Type_BitSet: return lb_debug_bitset( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); case Type_Enum: return lb_debug_enum( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); + case Type_BitField: return lb_debug_bitfield( m, type, make_string_c(type_to_string(type, temporary_allocator())), nullptr, nullptr, 0); case Type_Tuple: if (type->Tuple.variables.count == 1) { @@ -901,42 +944,6 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { lb_debug_type(m, type->Matrix.elem), subscripts, gb_count_of(subscripts)); } - - case Type_BitField: { - LLVMMetadataRef parent_scope = nullptr; - LLVMMetadataRef scope = nullptr; - LLVMMetadataRef file = nullptr; - unsigned line = 0; - u64 size_in_bits = 8*cast(u64)type_size_of(type); - u32 align_in_bits = 8*cast(u32)type_align_of(type); - LLVMDIFlags flags = LLVMDIFlagZero; - - unsigned element_count = cast(unsigned)type->BitField.fields.count; - LLVMMetadataRef *elements = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, element_count); - - u64 offset_in_bits = 0; - for (unsigned i = 0; i < element_count; i++) { - Entity *f = type->BitField.fields[i]; - u8 bit_size = type->BitField.bit_sizes[i]; - GB_ASSERT(f->kind == Entity_Variable); - String name = f->token.string; - unsigned field_line = 0; - LLVMDIFlags field_flags = LLVMDIFlagZero; - elements[i] = LLVMDIBuilderCreateBitFieldMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, field_line, - bit_size, offset_in_bits, offset_in_bits, - field_flags, lb_debug_type(m, f->type) - ); - - offset_in_bits += bit_size; - } - - - return LLVMDIBuilderCreateStructType(m->debug_builder, parent_scope, "", 0, file, line, - size_in_bits, align_in_bits, flags, - nullptr, elements, element_count, 0, nullptr, - "", 0 - ); - } } GB_PANIC("Invalid type %s", type_to_string(type)); @@ -1022,6 +1029,7 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) { case Type_Union: return lb_debug_union(m, type, name, scope, file, line); case Type_BitSet: return lb_debug_bitset(m, type, name, scope, file, line); case Type_Enum: return lb_debug_enum(m, type, name, scope, file, line); + case Type_BitField: return lb_debug_bitfield(m, type, name, scope, file, line); } } -- cgit v1.2.3 From d03d9e49a6290b29a3259f99c4cdf574988b5765 Mon Sep 17 00:00:00 2001 From: Laytan Laats Date: Sun, 15 Sep 2024 00:03:20 +0200 Subject: fix #4243 --- src/llvm_backend_debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index bb6a1ba4f..5cc79dcc8 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -571,7 +571,7 @@ gb_internal LLVMMetadataRef lb_debug_bitfield(lbModule *m, Type *type, String na GB_ASSERT(f->kind == Entity_Variable); String name = f->token.string; elements[i] = LLVMDIBuilderCreateBitFieldMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, line, - bit_size, offset_in_bits, offset_in_bits, + bit_size, offset_in_bits, 0, LLVMDIFlagZero, lb_debug_type(m, f->type) ); -- cgit v1.2.3 From e38a08013e1afa1bbd7b8f90ee16cfbdfacfb13f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 14 Nov 2024 16:17:24 +0000 Subject: Remove `#relative` types from the compiler --- base/runtime/core.odin | 12 ---- base/runtime/print.odin | 12 ---- core/fmt/fmt.odin | 12 ---- core/reflect/reflect.odin | 81 +++++++++---------------- core/reflect/types.odin | 32 ---------- examples/demo/demo.odin | 17 ------ src/check_expr.cpp | 64 -------------------- src/check_type.cpp | 37 +----------- src/checker.cpp | 24 -------- src/docs_format.cpp | 3 +- src/docs_writer.cpp | 18 ------ src/llvm_backend.hpp | 4 -- src/llvm_backend_debug.cpp | 11 ---- src/llvm_backend_expr.cpp | 37 +----------- src/llvm_backend_general.cpp | 139 ------------------------------------------- src/llvm_backend_type.cpp | 26 -------- src/llvm_backend_utility.cpp | 6 -- src/types.cpp | 98 ------------------------------ 18 files changed, 31 insertions(+), 602 deletions(-) (limited to 'src/llvm_backend_debug.cpp') diff --git a/base/runtime/core.odin b/base/runtime/core.odin index a5a3a4d8c..e47f3ecbc 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -171,14 +171,6 @@ Type_Info_Simd_Vector :: struct { elem_size: int, count: int, } -Type_Info_Relative_Pointer :: struct { - pointer: ^Type_Info, // ^T - base_integer: ^Type_Info, -} -Type_Info_Relative_Multi_Pointer :: struct { - pointer: ^Type_Info, // [^]T - base_integer: ^Type_Info, -} Type_Info_Matrix :: struct { elem: ^Type_Info, elem_size: int, @@ -241,8 +233,6 @@ Type_Info :: struct { Type_Info_Map, Type_Info_Bit_Set, Type_Info_Simd_Vector, - Type_Info_Relative_Pointer, - Type_Info_Relative_Multi_Pointer, Type_Info_Matrix, Type_Info_Soa_Pointer, Type_Info_Bit_Field, @@ -275,8 +265,6 @@ Typeid_Kind :: enum u8 { Map, Bit_Set, Simd_Vector, - Relative_Pointer, - Relative_Multi_Pointer, Matrix, Soa_Pointer, Bit_Field, diff --git a/base/runtime/print.odin b/base/runtime/print.odin index 45f6f01ef..c28fd593d 100644 --- a/base/runtime/print.odin +++ b/base/runtime/print.odin @@ -486,18 +486,6 @@ print_type :: #force_no_inline proc "contextless" (ti: ^Type_Info) { print_u64(u64(info.count)) print_byte(']') print_type(info.elem) - - case Type_Info_Relative_Pointer: - print_string("#relative(") - print_type(info.base_integer) - print_string(") ") - print_type(info.pointer) - - case Type_Info_Relative_Multi_Pointer: - print_string("#relative(") - print_type(info.base_integer) - print_string(") ") - print_type(info.pointer) case Type_Info_Matrix: print_string("matrix[") diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index dd5c2c6a2..49e9f2e6d 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -3002,18 +3002,6 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Bit_Set: fmt_bit_set(fi, v, verb = verb) - case runtime.Type_Info_Relative_Pointer: - ptr := reflect.relative_pointer_to_absolute_raw(v.data, info.base_integer.id) - absolute_ptr := any{ptr, info.pointer.id} - - fmt_value(fi, absolute_ptr, verb) - - 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} - - fmt_value(fi, absolute_ptr, verb) - case runtime.Type_Info_Matrix: fmt_matrix(fi, v, verb, info) diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index d547b67ed..7f79acb77 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -31,8 +31,6 @@ 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_Bit_Field :: runtime.Type_Info_Bit_Field @@ -67,8 +65,6 @@ Type_Kind :: enum { Map, Bit_Set, Simd_Vector, - Relative_Pointer, - Relative_Multi_Pointer, Matrix, Soa_Pointer, Bit_Field, @@ -80,35 +76,33 @@ 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_Multi_Pointer: return .Relative_Multi_Pointer - case Type_Info_Matrix: return .Matrix - case Type_Info_Soa_Pointer: return .Soa_Pointer - case Type_Info_Bit_Field: return .Bit_Field + 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_Matrix: return .Matrix + case Type_Info_Soa_Pointer: return .Soa_Pointer + case Type_Info_Bit_Field: return .Bit_Field } } @@ -1488,21 +1482,6 @@ as_string :: proc(a: any) -> (value: string, valid: bool) { return } -@(require_results) -relative_pointer_to_absolute :: proc(a: any) -> rawptr { - if a == nil { return nil } - a := a - ti := runtime.type_info_core(type_info_of(a.id)) - a.id = ti.id - - #partial switch info in ti.variant { - case Type_Info_Relative_Pointer: - return relative_pointer_to_absolute_raw(a.data, info.base_integer.id) - } - return nil -} - - @(require_results) relative_pointer_to_absolute_raw :: proc(data: rawptr, base_integer_id: typeid) -> rawptr { _handle :: proc(ptr: ^$T) -> rawptr where intrinsics.type_is_integer(T) { @@ -1564,10 +1543,6 @@ as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) { case cstring: value = rawptr(v) case: valid = false } - - case Type_Info_Relative_Pointer: - valid = true - value = relative_pointer_to_absolute_raw(a.data, info.base_integer.id) } return @@ -1677,8 +1652,6 @@ equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_ Type_Info_Bit_Set, 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 4f0674dc8..cb31a27e2 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -158,14 +158,6 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { case Type_Info_Simd_Vector: y := b.variant.(Type_Info_Simd_Vector) or_return return x.count == y.count && x.elem == y.elem - - case Type_Info_Relative_Pointer: - y := b.variant.(Type_Info_Relative_Pointer) or_return - return x.base_integer == y.base_integer && x.pointer == y.pointer - - 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 @@ -392,18 +384,6 @@ is_simd_vector :: proc(info: ^Type_Info) -> bool { _, ok := type_info_base(info).variant.(Type_Info_Simd_Vector) return ok } -@(require_results) -is_relative_pointer :: proc(info: ^Type_Info) -> bool { - if info == nil { return false } - _, ok := type_info_base(info).variant.(Type_Info_Relative_Pointer) - return ok -} -@(require_results) -is_relative_multi_pointer :: proc(info: ^Type_Info) -> bool { - if info == nil { return false } - _, ok := type_info_base(info).variant.(Type_Info_Relative_Multi_Pointer) - return ok -} @(require_results) @@ -736,18 +716,6 @@ write_type_writer :: #force_no_inline proc(w: io.Writer, ti: ^Type_Info, n_writt io.write_i64(w, i64(info.count), 10, &n) or_return io.write_byte(w, ']', &n) or_return write_type(w, info.elem, &n) or_return - - case Type_Info_Relative_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.pointer, &n) or_return - - 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.pointer, &n) or_return case Type_Info_Matrix: if info.layout == .Row_Major { diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index b234ba4f3..36d1359ca 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -2052,22 +2052,6 @@ explicit_context_definition :: proc "c" () { dummy_procedure() } -relative_data_types :: proc() { - fmt.println("\n#relative data types") - - x: int = 123 - ptr: #relative(i16) ^int - ptr = &x - fmt.println(ptr^) - - arr := [3]int{1, 2, 3} - multi_ptr: #relative(i16) [^]int - multi_ptr = &arr[0] - fmt.println(multi_ptr) - fmt.println(multi_ptr[:3]) - fmt.println(multi_ptr[1]) -} - or_else_operator :: proc() { fmt.println("\n#'or_else'") { @@ -2634,7 +2618,6 @@ main :: proc() { constant_literal_expressions() union_maybe() explicit_context_definition() - relative_data_types() or_else_operator() or_return_operator() or_break_and_or_continue_operators() diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 05f491690..cb4647f33 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -897,20 +897,6 @@ gb_internal i64 check_distance_between_types(CheckerContext *c, Operand *operand } } - if (is_type_relative_pointer(dst)) { - i64 score = check_distance_between_types(c, operand, dst->RelativePointer.pointer_type, allow_array_programming); - if (score >= 0) { - return score+2; - } - } - - if (is_type_relative_multi_pointer(dst)) { - i64 score = check_distance_between_types(c, operand, dst->RelativeMultiPointer.pointer_type, allow_array_programming); - if (score >= 0) { - return score+2; - } - } - if (is_type_proc(dst)) { if (are_types_identical(src, dst)) { return 3; @@ -1052,12 +1038,6 @@ gb_internal AstPackage *get_package_of_type(Type *type) { case Type_DynamicArray: type = type->DynamicArray.elem; continue; - case Type_RelativePointer: - type = type->RelativePointer.pointer_type; - continue; - case Type_RelativeMultiPointer: - type = type->RelativeMultiPointer.pointer_type; - continue; } return nullptr; } @@ -8230,17 +8210,6 @@ gb_internal bool check_set_index_data(Operand *o, Type *t, bool indirection, i64 } return true; - case Type_RelativeMultiPointer: - { - 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; - } - } - return true; - case Type_DynamicArray: o->type = t->DynamicArray.elem; if (o->mode != Addressing_Constant) { @@ -10623,8 +10592,6 @@ gb_internal ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node, // Okay } else if (is_type_string(t)) { // Okay - } else if (is_type_relative_multi_pointer(t)) { - // Okay } else if (is_type_matrix(t)) { // Okay } else { @@ -10779,11 +10746,6 @@ gb_internal ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, } break; - case Type_RelativeMultiPointer: - valid = true; - o->type = type_deref(o->type); - break; - case Type_EnumeratedArray: { gbString str = expr_to_string(o->expr); @@ -10860,16 +10822,6 @@ 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); } @@ -11230,22 +11182,6 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast } else if (t->kind == Type_SoaPointer) { o->mode = Addressing_SoaVariable; o->type = type_deref(t); - } else if (t->kind == Type_RelativePointer) { - if (o->mode != Addressing_Variable) { - gbString str = expr_to_string(o->expr); - gbString typ = type_to_string(o->type); - error(o->expr, "Cannot dereference relative pointer '%s' of type '%s' as it does not have a variable addressing mode", str, typ); - gb_string_free(typ); - gb_string_free(str); - } - - // NOTE(bill): This is required because when dereferencing, the original type has been lost - add_type_info_type(c, o->type); - - Type *ptr_type = base_type(t->RelativePointer.pointer_type); - GB_ASSERT(ptr_type->kind == Type_Pointer); - o->mode = Addressing_Variable; - o->type = ptr_type->Pointer.elem; } else { gbString str = expr_to_string(o->expr); gbString typ = type_to_string(o->type); diff --git a/src/check_type.cpp b/src/check_type.cpp index bbeff9ca7..84e7fb249 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -3517,41 +3517,8 @@ gb_internal bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, T case_end; case_ast_node(rt, RelativeType, e); - GB_ASSERT(rt->tag->kind == Ast_CallExpr); - ast_node(ce, CallExpr, rt->tag); - - Type *base_integer = nullptr; - - if (ce->args.count != 1) { - error(rt->type, "#relative expected 1 type argument, got %td", ce->args.count); - } else { - base_integer = check_type(ctx, ce->args[0]); - if (!is_type_integer(base_integer)) { - error(rt->type, "#relative base types must be an integer"); - base_integer = nullptr; - } else if (type_size_of(base_integer) > 64) { - error(rt->type, "#relative base integer types be less than or equal to 64-bits"); - base_integer = nullptr; - } - } - - Type *relative_type = nullptr; - Type *base_type = check_type(ctx, rt->type); - 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_multi_pointer(base_type)) { - relative_type = alloc_type_relative_multi_pointer(base_type, base_integer); - } - } - GB_ASSERT(relative_type != nullptr); - - *type = relative_type; + error(e, "#relative types have been removed from the compiler. Prefer \"core:relative\"."); + *type = t_invalid; set_base_type(named_type, *type); return true; case_end; diff --git a/src/checker.cpp b/src/checker.cpp index 76f996648..b7cf343f8 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2186,16 +2186,6 @@ gb_internal void add_type_info_type_internal(CheckerContext *c, Type *t) { add_type_info_type_internal(c, bt->SimdVector.elem); break; - case Type_RelativePointer: - add_type_info_type_internal(c, bt->RelativePointer.pointer_type); - add_type_info_type_internal(c, bt->RelativePointer.base_integer); - break; - - 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: add_type_info_type_internal(c, bt->Matrix.elem); break; @@ -2441,16 +2431,6 @@ gb_internal void add_min_dep_type_info(Checker *c, Type *t) { add_min_dep_type_info(c, bt->SimdVector.elem); break; - case Type_RelativePointer: - add_min_dep_type_info(c, bt->RelativePointer.pointer_type); - add_min_dep_type_info(c, bt->RelativePointer.base_integer); - break; - - 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: add_min_dep_type_info(c, bt->Matrix.elem); break; @@ -3075,8 +3055,6 @@ gb_internal void init_core_type_info(Checker *c) { t_type_info_map = find_core_type(c, str_lit("Type_Info_Map")); 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_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")); t_type_info_bit_field = find_core_type(c, str_lit("Type_Info_Bit_Field")); @@ -3105,8 +3083,6 @@ gb_internal void init_core_type_info(Checker *c) { t_type_info_map_ptr = alloc_type_pointer(t_type_info_map); 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_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); t_type_info_bit_field_ptr = alloc_type_pointer(t_type_info_bit_field); diff --git a/src/docs_format.cpp b/src/docs_format.cpp index ca6ecb5c2..6378971d0 100644 --- a/src/docs_format.cpp +++ b/src/docs_format.cpp @@ -79,8 +79,7 @@ enum OdinDocTypeKind : u32 { OdinDocType_SOAStructFixed = 17, OdinDocType_SOAStructSlice = 18, OdinDocType_SOAStructDynamic = 19, - OdinDocType_RelativePointer = 20, - OdinDocType_RelativeMultiPointer = 21, + OdinDocType_MultiPointer = 22, OdinDocType_Matrix = 23, OdinDocType_SoaPointer = 24, diff --git a/src/docs_writer.cpp b/src/docs_writer.cpp index 835dfdff1..341b3fa6b 100644 --- a/src/docs_writer.cpp +++ b/src/docs_writer.cpp @@ -776,24 +776,6 @@ gb_internal OdinDocTypeIndex odin_doc_type(OdinDocWriter *w, Type *type) { doc_type.types = odin_doc_type_as_slice(w, type->SimdVector.elem); // TODO(bill): break; - case Type_RelativePointer: - doc_type.kind = OdinDocType_RelativePointer; - { - OdinDocTypeIndex types[2] = {}; - types[0] = odin_doc_type(w, type->RelativePointer.pointer_type); - types[1] = odin_doc_type(w, type->RelativePointer.base_integer); - doc_type.types = odin_write_slice(w, types, gb_count_of(types)); - } - break; - case Type_RelativeMultiPointer: - doc_type.kind = OdinDocType_RelativeMultiPointer; - { - OdinDocTypeIndex types[2] = {}; - 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; case Type_Matrix: doc_type.kind = OdinDocType_Matrix; diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 68f95cb03..464efa325 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -75,7 +75,6 @@ enum lbAddrKind { lbAddr_Context, lbAddr_SoaVariable, - lbAddr_RelativePointer, lbAddr_Swizzle, lbAddr_SwizzleLarge, @@ -103,9 +102,6 @@ struct lbAddr { lbValue index; Ast *node; } index_set; - struct { - bool deref; - } relative; struct { Type *type; u8 count; // 2, 3, or 4 components diff --git a/src/llvm_backend_debug.cpp b/src/llvm_backend_debug.cpp index 5cc79dcc8..464f7065c 100644 --- a/src/llvm_backend_debug.cpp +++ b/src/llvm_backend_debug.cpp @@ -920,17 +920,6 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) { elem, subscripts, gb_count_of(subscripts)); } - case Type_RelativePointer: { - LLVMMetadataRef base_integer = lb_debug_type(m, type->RelativePointer.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_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_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 8ad44035d..80c469ae6 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -4200,30 +4200,6 @@ gb_internal lbAddr lb_build_addr_index_expr(lbProcedure *p, Ast *expr) { return lb_addr(v); } - case Type_RelativeMultiPointer: { - lbAddr rel_ptr_addr = {}; - if (deref) { - lbValue rel_ptr_ptr = lb_build_expr(p, ie->expr); - rel_ptr_addr = lb_addr(rel_ptr_ptr); - } else { - rel_ptr_addr = lb_build_addr(p, ie->expr); - } - lbValue rel_ptr = lb_relative_pointer_to_pointer(p, rel_ptr_addr); - - 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); - } - case Type_DynamicArray: { lbValue dynamic_array = {}; dynamic_array = lb_build_expr(p, ie->expr); @@ -4333,13 +4309,6 @@ gb_internal lbAddr lb_build_addr_slice_expr(lbProcedure *p, Ast *expr) { return slice; } - 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: { Type *elem_type = type->DynamicArray.elem; Type *slice_type = alloc_type_slice(elem_type); @@ -5343,11 +5312,7 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { case_ast_node(de, DerefExpr, expr); Type *t = type_of_expr(de->expr); - if (is_type_relative_pointer(t)) { - lbAddr addr = lb_build_addr(p, de->expr); - addr.relative.deref = true; - return addr; - } else if (is_type_soa_pointer(t)) { + if (is_type_soa_pointer(t)) { lbValue value = lb_build_expr(p, de->expr); lbValue ptr = lb_emit_struct_ev(p, value, 0); lbValue idx = lb_emit_struct_ev(p, value, 1); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 686724f6a..9dc603993 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -409,14 +409,6 @@ gb_internal lbModule *lb_module_of_entity(lbGenerator *gen, Entity *e) { gb_internal lbAddr lb_addr(lbValue addr) { lbAddr v = {lbAddr_Default, 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_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; } @@ -501,42 +493,6 @@ 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_make_soa_pointer(lbProcedure *p, Type *type, lbValue const &addr, lbValue const &index) { lbAddr v = lb_add_local_generated(p, type, false); lbValue ptr = lb_emit_struct_ep(p, v.addr, 0); @@ -557,9 +513,6 @@ 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: - return lb_relative_pointer_to_pointer(p, addr); - case lbAddr_SoaVariable: { Type *soa_ptr_type = alloc_type_soa_pointer(lb_addr_type(addr)); @@ -584,9 +537,6 @@ 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); } @@ -819,10 +769,6 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { value.value = LLVMConstNull(lb_type(p->module, t)); } - if (addr.kind == lbAddr_RelativePointer && addr.relative.deref) { - addr = lb_addr(lb_address_from_load(p, lb_addr_load(p, addr))); - } - if (addr.kind == lbAddr_BitField) { lbValue dst = addr.addr; if (is_type_endian_big(addr.bitfield.type)) { @@ -860,44 +806,6 @@ gb_internal void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value) { lb_emit_runtime_call(p, "__write_bits", args); } return; - } else if (addr.kind == lbAddr_RelativePointer) { - Type *rel_ptr = base_type(lb_addr_type(addr)); - GB_ASSERT(rel_ptr->kind == Type_RelativePointer || - rel_ptr->kind == Type_RelativeMultiPointer); - Type *pointer_type = nullptr; - Type *base_integer = nullptr; - - 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); - lbValue val_ptr = lb_emit_conv(p, value, t_uintptr); - lbValue offset = {}; - offset.value = LLVMBuildSub(p->builder, val_ptr.value, ptr.value, ""); - offset.type = t_uintptr; - - if (!is_type_unsigned(base_integer)) { - offset = lb_emit_conv(p, offset, t_i64); - } - offset = lb_emit_conv(p, offset, 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, base_integer), - offset - ); - LLVMBuildStore(p->builder, offset.value, offset_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; @@ -1246,46 +1154,6 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) { } return r; - } else if (addr.kind == lbAddr_RelativePointer) { - Type *rel_ptr = base_type(lb_addr_type(addr)); - 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(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 = {}; - final_ptr.type = absolute_ptr.type; - final_ptr.value = LLVMBuildSelect(p->builder, cond.value, nil_ptr.value, absolute_ptr.value, ""); - - if (rel_ptr->kind == Type_RelativeMultiPointer) { - return final_ptr; - } - return lb_emit_load(p, final_ptr); - } else if (addr.kind == lbAddr_Map) { Type *map_type = base_type(type_deref(addr.addr.type)); GB_ASSERT(map_type->kind == Type_Map); @@ -2378,13 +2246,6 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) { case Type_SimdVector: return LLVMVectorType(lb_type(m, type->SimdVector.elem), cast(unsigned)type->SimdVector.count); - - 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_Matrix: { diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index f3fcc8de4..6c12b37be 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -61,8 +61,6 @@ gb_internal u64 lb_typeid_kind(lbModule *m, Type *type, u64 id=0) { 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; case Type_BitField: kind = Typeid_Bit_Field; break; } @@ -950,30 +948,6 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ } break; - case Type_RelativePointer: - { - tag_type = t_type_info_relative_pointer; - LLVMValueRef vals[2] = { - get_type_info_ptr(m, t->RelativePointer.pointer_type), - get_type_info_ptr(m, t->RelativePointer.base_integer), - }; - - variant_value = llvm_const_named_struct(m, tag_type, vals, gb_count_of(vals)); - } - break; - - case Type_RelativeMultiPointer: - { - tag_type = t_type_info_relative_multi_pointer; - LLVMValueRef vals[2] = { - get_type_info_ptr(m, t->RelativeMultiPointer.pointer_type), - get_type_info_ptr(m, t->RelativeMultiPointer.base_integer), - }; - - variant_value = llvm_const_named_struct(m, tag_type, vals, gb_count_of(vals)); - } - break; - case Type_Matrix: { tag_type = t_type_info_matrix; diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index e6049da84..a2a0ba4cc 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1131,10 +1131,6 @@ gb_internal lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) { Type *t = base_type(type_deref(s.type)); Type *result_type = nullptr; - if (is_type_relative_pointer(t)) { - s = lb_addr_get_ptr(p, lb_addr(s)); - } - if (is_type_struct(t)) { result_type = get_struct_field_type(t, index); } else if (is_type_union(t)) { @@ -1440,8 +1436,6 @@ gb_internal lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection e = lb_emit_array_epi(p, e, index); } else if (type->kind == Type_Map) { e = lb_emit_struct_ep(p, e, index); - } else if (type->kind == Type_RelativePointer) { - e = lb_emit_struct_ep(p, e, index); } else { GB_PANIC("un-gep-able type %s", type_to_string(type)); } diff --git a/src/types.cpp b/src/types.cpp index b49bce7d4..c51df7261 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -272,14 +272,6 @@ struct TypeProc { Type *elem; \ Type *generic_count; \ }) \ - TYPE_KIND(RelativePointer, struct { \ - Type *pointer_type; \ - Type *base_integer; \ - }) \ - TYPE_KIND(RelativeMultiPointer, struct { \ - Type *pointer_type; \ - Type *base_integer; \ - }) \ TYPE_KIND(Matrix, struct { \ Type *elem; \ i64 row_count; \ @@ -367,8 +359,6 @@ enum Typeid_Kind : u8 { Typeid_Map, Typeid_Bit_Set, Typeid_Simd_Vector, - Typeid_Relative_Pointer, - Typeid_Relative_Multi_Pointer, Typeid_Matrix, Typeid_SoaPointer, Typeid_Bit_Field, @@ -678,8 +668,6 @@ gb_global Type *t_type_info_enum = nullptr; 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_multi_pointer = nullptr; gb_global Type *t_type_info_matrix = nullptr; gb_global Type *t_type_info_soa_pointer = nullptr; gb_global Type *t_type_info_bit_field = nullptr; @@ -708,8 +696,6 @@ gb_global Type *t_type_info_enum_ptr = nullptr; 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_multi_pointer_ptr = nullptr; gb_global Type *t_type_info_matrix_ptr = nullptr; gb_global Type *t_type_info_soa_pointer_ptr = nullptr; gb_global Type *t_type_info_bit_field_ptr = nullptr; @@ -1118,24 +1104,6 @@ gb_internal Type *alloc_type_bit_field() { return t; } -gb_internal Type *alloc_type_relative_pointer(Type *pointer_type, Type *base_integer) { - GB_ASSERT(is_type_pointer(pointer_type)); - GB_ASSERT(is_type_integer(base_integer)); - Type *t = alloc_type(Type_RelativePointer); - t->RelativePointer.pointer_type = pointer_type; - t->RelativePointer.base_integer = base_integer; - return t; -} - -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_RelativeMultiPointer); - t->RelativeMultiPointer.pointer_type = pointer_type; - t->RelativeMultiPointer.base_integer = base_integer; - return t; -} - gb_internal Type *alloc_type_named(String name, Type *base, Entity *type_name) { Type *t = alloc_type(Type_Named); t->Named.name = name; @@ -1227,8 +1195,6 @@ gb_internal Type *type_deref(Type *t, bool allow_multi_pointer) { switch (bt->kind) { case Type_Pointer: return bt->Pointer.elem; - case Type_RelativePointer: - return type_deref(bt->RelativePointer.pointer_type); case Type_SoaPointer: { Type *elem = base_type(bt->SoaPointer.elem); @@ -1667,15 +1633,6 @@ gb_internal bool is_type_generic(Type *t) { return t->kind == Type_Generic; } -gb_internal bool is_type_relative_pointer(Type *t) { - t = base_type(t); - return t->kind == Type_RelativePointer; -} -gb_internal bool is_type_relative_multi_pointer(Type *t) { - t = base_type(t); - return t->kind == Type_RelativeMultiPointer; -} - gb_internal bool is_type_u8_slice(Type *t) { t = base_type(t); if (t->kind == Type_Slice) { @@ -2118,8 +2075,6 @@ gb_internal bool is_type_indexable(Type *t) { return true; case Type_EnumeratedArray: return true; - case Type_RelativeMultiPointer: - return true; case Type_Matrix: return true; } @@ -2137,8 +2092,6 @@ gb_internal bool is_type_sliceable(Type *t) { return true; case Type_EnumeratedArray: return false; - case Type_RelativeMultiPointer: - return true; case Type_Matrix: return false; } @@ -2345,27 +2298,7 @@ gb_internal bool is_type_polymorphic(Type *t, bool or_specialized=false) { return true; } break; - - case Type_RelativeMultiPointer: - if (is_type_polymorphic(t->RelativeMultiPointer.pointer_type, or_specialized)) { - return true; - } - if (t->RelativeMultiPointer.base_integer != nullptr && - is_type_polymorphic(t->RelativeMultiPointer.base_integer, or_specialized)) { - return true; - } - break; - case Type_RelativePointer: - if (is_type_polymorphic(t->RelativePointer.pointer_type, or_specialized)) { - return true; - } - if (t->RelativePointer.base_integer != nullptr && - is_type_polymorphic(t->RelativePointer.base_integer, or_specialized)) { - return true; - } - break; } - return false; } @@ -2407,10 +2340,6 @@ gb_internal bool type_has_nil(Type *t) { } } return false; - - case Type_RelativePointer: - case Type_RelativeMultiPointer: - return true; } return false; } @@ -2579,10 +2508,6 @@ gb_internal bool is_type_load_safe(Type *type) { } return true; - case Type_RelativePointer: - case Type_RelativeMultiPointer: - return true; - case Type_Pointer: case Type_MultiPointer: case Type_Slice: @@ -3945,11 +3870,6 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) { case Type_Matrix: return matrix_align_of(t, path); - case Type_RelativePointer: - return type_align_of_internal(t->RelativePointer.base_integer, path); - case Type_RelativeMultiPointer: - return type_align_of_internal(t->RelativeMultiPointer.base_integer, path); - case Type_SoaPointer: return build_context.int_size; } @@ -4242,11 +4162,6 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) { case Type_BitField: return type_size_of_internal(t->BitField.backing_type, path); - - case Type_RelativePointer: - return type_size_of_internal(t->RelativePointer.base_integer, path); - case Type_RelativeMultiPointer: - return type_size_of_internal(t->RelativeMultiPointer.base_integer, path); } // Catch all @@ -4872,19 +4787,6 @@ gb_internal gbString write_type_to_string(gbString str, Type *type, bool shortha str = gb_string_append_fmt(str, "#simd[%d]", cast(int)type->SimdVector.count); str = write_type_to_string(str, type->SimdVector.elem); break; - - case Type_RelativePointer: - str = gb_string_append_fmt(str, "#relative("); - str = write_type_to_string(str, type->RelativePointer.base_integer); - str = gb_string_append_fmt(str, ") "); - str = write_type_to_string(str, type->RelativePointer.pointer_type); - break; - case Type_RelativeMultiPointer: - str = gb_string_append_fmt(str, "#relative("); - str = write_type_to_string(str, type->RelativePointer.base_integer); - str = gb_string_append_fmt(str, ") "); - str = write_type_to_string(str, type->RelativePointer.pointer_type); - break; case Type_Matrix: if (type->Matrix.is_row_major) { -- cgit v1.2.3