aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2023-07-17 22:18:15 +0100
committergingerBill <bill@gingerbill.org>2023-07-17 22:18:15 +0100
commitb2c75dc3a22f72bcf7b4a47348bd46e4ddb05200 (patch)
tree5ad106eb1b3988e3db7dd040fb5661716893df03
parentb5b3f1fb421ee2c127d96719bfcf77c5ce7fa9e4 (diff)
Mostly fill in `cg_debug_type`
-rw-r--r--src/tilde_backend.cpp3
-rw-r--r--src/tilde_backend.hpp3
-rw-r--r--src/tilde_proc.cpp2
-rw-r--r--src/tilde_stmt.cpp338
4 files changed, 345 insertions, 1 deletions
diff --git a/src/tilde_backend.cpp b/src/tilde_backend.cpp
index db759b767..798f51bb3 100644
--- a/src/tilde_backend.cpp
+++ b/src/tilde_backend.cpp
@@ -396,6 +396,8 @@ gb_internal cgModule *cg_module_create(Checker *c) {
map_init(&m->file_id_map);
+ map_init(&m->debug_type_map);
+
for_array(id, global_files) {
if (AstFile *f = global_files[id]) {
@@ -411,6 +413,7 @@ gb_internal void cg_module_destroy(cgModule *m) {
map_destroy(&m->values);
array_free(&m->procedures_to_generate);
map_destroy(&m->file_id_map);
+ map_destroy(&m->debug_type_map);
tb_module_destroy(m->mod);
}
diff --git a/src/tilde_backend.hpp b/src/tilde_backend.hpp
index b2192cce4..032229193 100644
--- a/src/tilde_backend.hpp
+++ b/src/tilde_backend.hpp
@@ -176,6 +176,9 @@ struct cgModule {
PtrMap<TB_Function *, Entity *> procedure_values;
Array<cgProcedure *> procedures_to_generate;
+ RecursiveMutex debug_type_mutex;
+ PtrMap<Type *, TB_DebugType *> debug_type_map;
+
PtrMap<uintptr, TB_FileID> file_id_map; // Key: AstFile.id (i32 cast to uintptr)
std::atomic<u32> nested_type_name_guid;
diff --git a/src/tilde_proc.cpp b/src/tilde_proc.cpp
index af9bee189..49af695ee 100644
--- a/src/tilde_proc.cpp
+++ b/src/tilde_proc.cpp
@@ -409,7 +409,7 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
}
// TB_Node *ptr = tb_inst_param_addr(p->func, param_index);
- TB_Node *param = tb_inst_param(p->func, param_index);
+ TB_Node *param = tb_inst_param(p->func, param_index++);
TB_Node *ptr = tb_inst_local(p->func, cast(TB_CharUnits)type_size_of(e->type), cast(TB_CharUnits)type_align_of(e->type));
TB_DataType dt = cg_data_type(e->type);
tb_inst_store(p->func, dt, ptr, param, cast(TB_CharUnits)type_align_of(e->type), false);
diff --git a/src/tilde_stmt.cpp b/src/tilde_stmt.cpp
index 6c0e8cf76..4e49199f9 100644
--- a/src/tilde_stmt.cpp
+++ b/src/tilde_stmt.cpp
@@ -629,7 +629,345 @@ gb_internal void cg_pop_target_list(cgProcedure *p) {
p->target_list = p->target_list->prev;
}
+gb_internal TB_DebugType *cg_debug_type_internal(cgModule *m, Type *type);
gb_internal TB_DebugType *cg_debug_type(cgModule *m, Type *type) {
+ mutex_lock(&m->debug_type_mutex);
+ defer (mutex_unlock(&m->debug_type_mutex));
+ TB_DebugType **found = map_get(&m->debug_type_map, type);
+ if (found) {
+ return *found;
+ }
+
+ TB_DebugType *res = cg_debug_type_internal(m, type);
+ map_set(&m->debug_type_map, type, res);
+ return res;
+}
+
+gb_internal TB_DebugType *cg_debug_type_internal_record(cgModule *m, Type *type, String const &record_name) {
+ Type *bt = base_type(type);
+ switch (bt->kind) {
+ case Type_Struct:
+ {
+ type_set_offsets(bt);
+
+ TB_DebugType *record = nullptr;
+ if (bt->Struct.is_raw_union) {
+ record = tb_debug_create_union(m->mod, record_name.len, cast(char const *)record_name.text);
+ } else {
+ record = tb_debug_create_struct(m->mod, record_name.len, cast(char const *)record_name.text);
+ }
+ if (record_name.len != 0) {
+ map_set(&m->debug_type_map, type, record);
+ }
+
+ TB_DebugType **fields = tb_debug_record_begin(record, bt->Struct.fields.count);
+ for_array(i, bt->Struct.fields) {
+ Entity *e = bt->Struct.fields[i];
+ Type *type = e->type;
+ if (is_type_proc(type)) {
+ type = t_rawptr;
+ }
+ TB_DebugType *field_type = cg_debug_type(m, type);
+ String name = e->token.string;
+ TB_CharUnits offset = cast(TB_CharUnits)bt->Struct.offsets[i];
+ if (name.len == 0) {
+ name = str_lit("_");
+ }
+
+ fields[i] = tb_debug_create_field(m->mod, field_type, name.len, cast(char const *)name.text, offset);
+ }
+ tb_debug_record_end(
+ record,
+ cast(TB_CharUnits)type_size_of(type),
+ cast(TB_CharUnits)type_align_of(type)
+ );
+ return record;
+ }
+ break;
+ case Type_Union:
+ {
+ TB_DebugType *record = tb_debug_create_struct(m->mod, record_name.len, cast(char const *)record_name.text);
+ if (record_name.len != 0) {
+ map_set(&m->debug_type_map, type, record);
+ }
+
+ i64 variant_count = bt->Union.variants.count;
+ if (is_type_union_maybe_pointer(bt)) {
+ // NO TAG
+ GB_ASSERT(variant_count == 1);
+ TB_DebugType **fields = tb_debug_record_begin(record, variant_count);
+ TB_DebugType *variant_type = cg_debug_type(m, bt->Union.variants[0]);
+ fields[0] = tb_debug_create_field(m->mod, variant_type, -1, "v0", 0);
+ tb_debug_record_end(
+ record,
+ cast(TB_CharUnits)type_size_of(type),
+ cast(TB_CharUnits)type_align_of(type)
+ );
+ } else {
+ TB_DebugType **fields = tb_debug_record_begin(record, variant_count+1);
+ for_array(i, bt->Union.variants) {
+ Type *v = bt->Union.variants[i];
+ TB_DebugType *variant_type = cg_debug_type(m, v);
+ char name[32] = {};
+ u32 v_index = cast(u32)i;
+ if (bt->Union.kind != UnionType_no_nil) {
+ v_index += 1;
+ }
+ gb_snprintf(name, 31, "v%u", v_index);
+ fields[i] = tb_debug_create_field(m->mod, variant_type, -1, name, 0);
+ }
+
+ TB_DebugType *tag_type = cg_debug_type(m, union_tag_type(bt));
+ fields[variant_count] = tb_debug_create_field(m->mod, tag_type, -1, "tag", cast(TB_CharUnits)bt->Union.variant_block_size);
+
+ }
+ tb_debug_record_end(
+ record,
+ cast(TB_CharUnits)type_size_of(type),
+ cast(TB_CharUnits)type_align_of(type)
+ );
+ return record;
+ }
+ break;
+ }
+ return nullptr;
+}
+
+
+gb_internal TB_DebugType *cg_debug_type_internal(cgModule *m, Type *type) {
+ if (type == nullptr) {
+ return tb_debug_get_void(m->mod);
+ }
+ if (type->kind == Type_Named) {
+ String name = type->Named.name;
+ TB_DebugType *res = cg_debug_type_internal_record(m, type, name);
+ if (res) {
+ return res;
+ }
+ type = base_type(type->Named.base);
+ }
+
+ TB_CharUnits int_size = cast(TB_CharUnits)build_context.int_size;
+ TB_CharUnits ptr_size = cast(TB_CharUnits)build_context.ptr_size;
+ TB_CharUnits size = cast(TB_CharUnits)type_size_of(type);
+ TB_CharUnits align = cast(TB_CharUnits)type_align_of(type);
+ int bits = cast(int)(8*size);
+ bool is_signed = is_type_integer(core_type(type)) && !is_type_unsigned(core_type(type));
+
+ switch (type->kind) {
+ case Type_Basic:
+ switch (type->Basic.kind) {
+ case Basic_bool: return tb_debug_get_bool(m->mod);
+ case Basic_b8: return tb_debug_get_bool(m->mod);
+ case Basic_b16: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_b32: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_b64: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i8: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u8: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i16: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u16: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i32: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u32: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i64: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u64: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i128: return tb_debug_get_integer(m->mod, is_signed, 64/*bits*/);
+ case Basic_u128: return tb_debug_get_integer(m->mod, is_signed, 64/*bits*/);
+ case Basic_rune: return tb_debug_get_integer(m->mod, is_signed, bits);
+
+ case Basic_f16: return tb_debug_get_integer(m->mod, false, bits);
+ case Basic_f32: return tb_debug_get_float(m->mod, TB_FLT_32);
+ case Basic_f64: return tb_debug_get_float(m->mod,TB_FLT_64);
+
+ case Basic_complex32:
+ case Basic_complex64:
+ case Basic_complex128:
+ {
+ String name = basic_types[type->Basic.kind].Basic.name;
+ TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
+ Type *et = base_complex_elem_type(type);
+ TB_CharUnits elem_size = cast(TB_CharUnits)type_size_of(et);
+ TB_DebugType *elem = cg_debug_type(m, et);
+
+ TB_DebugType **fields = tb_debug_record_begin(record, 2);
+ fields[0] = tb_debug_create_field(m->mod, elem, -1, "real", 0*elem_size);
+ fields[1] = tb_debug_create_field(m->mod, elem, -1, "imag", 1*elem_size);
+
+ tb_debug_record_end(record, size, align);
+ return record;
+ }
+ case Basic_quaternion64:
+ case Basic_quaternion128:
+ case Basic_quaternion256:
+ {
+ String name = basic_types[type->Basic.kind].Basic.name;
+ TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
+ Type *et = base_complex_elem_type(type);
+ TB_CharUnits elem_size = cast(TB_CharUnits)type_size_of(et);
+ TB_DebugType *elem = cg_debug_type(m, et);
+
+ // @QuaternionLayout
+ TB_DebugType **fields = tb_debug_record_begin(record, 4);
+ fields[0] = tb_debug_create_field(m->mod, elem, -1, "imag", 0*elem_size);
+ fields[1] = tb_debug_create_field(m->mod, elem, -1, "jmag", 1*elem_size);
+ fields[2] = tb_debug_create_field(m->mod, elem, -1, "kmag", 2*elem_size);
+ fields[3] = tb_debug_create_field(m->mod, elem, -1, "real", 3*elem_size);
+
+ tb_debug_record_end(record, size, align);
+ return record;
+ }
+
+ case Basic_int: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_uint: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_uintptr: return tb_debug_get_integer(m->mod, is_signed, bits);
+
+ case Basic_rawptr: return tb_debug_create_ptr(m->mod, tb_debug_get_void(m->mod));
+ case Basic_string:
+ {
+ String name = basic_types[type->Basic.kind].Basic.name;
+ TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
+ // @QuaternionLayout
+ TB_DebugType **fields = tb_debug_record_begin(record, 2);
+ fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, t_u8_ptr), -1, "data", 0*int_size);
+ fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "len", 1*int_size);
+
+ tb_debug_record_end(record, size, align);
+ return record;
+ }
+ case Basic_cstring:
+ return tb_debug_create_ptr(m->mod, tb_debug_get_integer(m->mod, false, 8));
+
+ case Basic_any:
+ {
+ String name = basic_types[type->Basic.kind].Basic.name;
+ TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
+ // @QuaternionLayout
+ TB_DebugType **fields = tb_debug_record_begin(record, 2);
+ fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, t_rawptr), -1, "data", 0*ptr_size);
+ fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_typeid), -1, "id", 1*ptr_size);
+
+ tb_debug_record_end(record, size, align);
+ return record;
+ }
+ case Basic_typeid: return tb_debug_get_integer(m->mod, is_signed, bits);
+
+ case Basic_i16le: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u16le: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i32le: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u32le: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i64le: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u64le: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i128le: return tb_debug_get_integer(m->mod, is_signed, 64/*bits*/);
+ case Basic_u128le: return tb_debug_get_integer(m->mod, is_signed, 64/*bits*/);
+ case Basic_i16be: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u16be: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i32be: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u32be: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i64be: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_u64be: return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Basic_i128be: return tb_debug_get_integer(m->mod, is_signed, 64/*bits*/);
+ case Basic_u128be: return tb_debug_get_integer(m->mod, is_signed, 64/*bits*/);
+
+ case Basic_f16le: return tb_debug_get_integer(m->mod, false, bits);
+ case Basic_f32le: return tb_debug_get_float(m->mod, TB_FLT_32);
+ case Basic_f64le: return tb_debug_get_float(m->mod,TB_FLT_64);
+ case Basic_f16be: return tb_debug_get_integer(m->mod, false, bits);
+ case Basic_f32be: return tb_debug_get_float(m->mod, TB_FLT_32);
+ case Basic_f64be: return tb_debug_get_float(m->mod,TB_FLT_64);
+ }
+ break;
+ case Type_Generic:
+ GB_PANIC("SHOULD NEVER HIT");
+ break;
+ case Type_Pointer:
+ return tb_debug_create_ptr(m->mod, cg_debug_type(m, type->Pointer.elem));
+ case Type_MultiPointer:
+ return tb_debug_create_ptr(m->mod, cg_debug_type(m, type->MultiPointer.elem));
+ case Type_Array:
+ return tb_debug_create_array(m->mod, cg_debug_type(m, type->Array.elem), type->Array.count);
+ case Type_EnumeratedArray:
+ return tb_debug_create_array(m->mod, cg_debug_type(m, type->EnumeratedArray.elem), type->EnumeratedArray.count);
+ case Type_Slice:
+ {
+ String name = {};
+ TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
+ TB_DebugType **fields = tb_debug_record_begin(record, 2);
+ fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, alloc_type_pointer(type->Slice.elem)), -1, "data", 0*int_size);
+ fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "len", 1*int_size);
+
+ tb_debug_record_end(record, size, align);
+ return record;
+ }
+ case Type_DynamicArray:
+ {
+ String name = {};
+ TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
+ TB_DebugType **fields = tb_debug_record_begin(record, 4);
+ fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, alloc_type_pointer(type->Slice.elem)), -1, "data", 0*int_size);
+ fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "len", 1*int_size);
+ fields[2] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "cap", 2*int_size);
+ fields[3] = tb_debug_create_field(m->mod, cg_debug_type(m, t_allocator), -1, "allocator", 3*int_size);
+
+ tb_debug_record_end(record, size, align);
+ return record;
+ }
+ case Type_Map:
+ return cg_debug_type(m, t_raw_map);
+ case Type_Struct:
+ return cg_debug_type_internal_record(m, type, {});
+ case Type_Union:
+ return cg_debug_type_internal_record(m, type, {});
+ case Type_Enum:
+ return tb_debug_get_integer(m->mod, is_signed, bits);
+ case Type_Tuple:
+ GB_PANIC("SHOULD NEVER HIT");
+ break;
+ case Type_Proc:
+ {
+ TypeProc *pt = &type->Proc;
+ isize param_count = 0;
+ isize return_count = 0;
+ TB_DebugType *func = tb_debug_create_func(m->mod, TB_CDECL, param_count, return_count, pt->c_vararg);
+ return func;
+ }
+ break;
+ case Type_BitSet:
+ return cg_debug_type(m, bit_set_to_int(type));
+ case Type_SimdVector:
+ return tb_debug_create_array(m->mod, cg_debug_type(m, type->SimdVector.elem), type->SimdVector.count);
+ case Type_RelativePointer:
+ return cg_debug_type(m, type->RelativePointer.base_integer);
+ case Type_RelativeSlice:
+ {
+ String name = {};
+ TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
+
+ TB_DebugType *base_integer = cg_debug_type(m, type->RelativeSlice.base_integer);
+ TB_CharUnits bi_size = cast(TB_CharUnits)type_size_of(type->RelativeSlice.base_integer);
+ TB_DebugType **fields = tb_debug_record_begin(record, 2);
+ fields[0] = tb_debug_create_field(m->mod, base_integer, -1, "data", 0*bi_size);
+ fields[1] = tb_debug_create_field(m->mod, base_integer, -1, "len", 1*bi_size);
+
+ tb_debug_record_end(record, size, align);
+ return record;
+ }
+ case Type_Matrix:
+ {
+ i64 count = matrix_type_total_internal_elems(type);
+ return tb_debug_create_array(m->mod, cg_debug_type(m, type->Matrix.elem), count);
+ }
+ case Type_SoaPointer:
+ {
+ String name = {};
+ TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
+ TB_DebugType **fields = tb_debug_record_begin(record, 2);
+ fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, alloc_type_pointer(type->SoaPointer.elem)), -1, "ptr", 0*int_size);
+ fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "offset", 1*int_size);
+
+ tb_debug_record_end(record, size, align);
+ return record;
+ }
+ }
+
// TODO(bill): cg_debug_type
return tb_debug_get_void(m->mod);
}