123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- gb_internal TB_DebugType *cg_debug_type_internal(cgModule *m, Type *type);
- gb_internal TB_DebugType *cg_debug_type(cgModule *m, Type *type) {
- type = reduce_tuple_to_single_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_for_proc(cgModule *m, Type *type) {
- GB_ASSERT(is_type_proc(type));
- TB_DebugType **func_found = nullptr;
- TB_DebugType *func_ptr = cg_debug_type(m, type);
- GB_ASSERT(func_ptr != nullptr);
- mutex_lock(&m->debug_type_mutex);
- func_found = map_get(&m->proc_debug_type_map, type);
- mutex_unlock(&m->debug_type_mutex);
- GB_ASSERT(func_found != nullptr);
- return *func_found;
- }
- 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_Tuple:
- {
- GB_ASSERT(record_name.len == 0);
- type_set_offsets(bt);
- TB_DebugType *record = tb_debug_create_struct(m->mod, 0, "");
- TB_DebugType **fields = tb_debug_record_begin(record, bt->Tuple.variables.count);
- for_array(i, bt->Tuple.variables) {
- Entity *e = bt->Tuple.variables[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->Tuple.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);
- }
- Type *original_type = type;
- 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, bits);
- case Basic_u128: return tb_debug_get_integer(m->mod, is_signed, 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, false, 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, bits);
- case Basic_u128le: return tb_debug_get_integer(m->mod, is_signed, 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, bits);
- case Basic_u128be: return tb_debug_get_integer(m->mod, is_signed, 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:
- case Type_Tuple:
- 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_Proc:
- {
- TypeProc *pt = &type->Proc;
- isize param_count = 0;
- isize return_count = 0;
- bool is_odin_cc = is_calling_convention_odin(pt->calling_convention);
- if (pt->params) for (Entity *e : pt->params->Tuple.variables) {
- if (e->kind == Entity_Variable) {
- param_count += 1;
- }
- }
- if (pt->result_count > 0) {
- if (is_odin_cc) {
- // Split returns
- param_count += pt->result_count-1;
- return_count = 1;
- } else {
- return_count = 1;
- }
- }
- if (pt->calling_convention == ProcCC_Odin) {
- // `context` ptr
- param_count += 1;
- }
- TB_DebugType *func = tb_debug_create_func(m->mod, TB_CDECL, param_count, return_count, pt->c_vararg);
- map_set(&m->proc_debug_type_map, original_type, func);
- map_set(&m->proc_debug_type_map, type, func);
- TB_DebugType *func_ptr = tb_debug_create_ptr(m->mod, func);
- map_set(&m->debug_type_map, original_type, func_ptr);
- map_set(&m->debug_type_map, type, func_ptr);
- TB_DebugType **params = tb_debug_func_params(func);
- TB_DebugType **returns = tb_debug_func_returns(func);
- isize param_index = 0;
- isize return_index = 0;
- if (pt->params) for (Entity *e : pt->params->Tuple.variables) {
- if (e->kind == Entity_Variable) {
- Type *type = e->type;
- if (is_type_proc(type)) {
- type = t_rawptr;
- }
- String name = e->token.string;
- if (name.len == 0) {
- name = str_lit("_");
- }
- params[param_index++] = tb_debug_create_field(m->mod, cg_debug_type(m, type), name.len, cast(char const *)name.text, 0);
- }
- }
- if (pt->result_count) {
- GB_ASSERT(pt->results);
- if (is_odin_cc) {
- // Split Returns
- for (isize i = 0; i < pt->results->Tuple.variables.count-1; i++) {
- Entity *e = pt->results->Tuple.variables[i];
- GB_ASSERT(e->kind == Entity_Variable);
- Type *type = e->type;
- if (is_type_proc(e->type)) {
- type = t_rawptr;
- }
- type = alloc_type_pointer(type);
- String name = e->token.string;
- if (name.len == 0) {
- name = str_lit("_");
- }
- params[param_index++] = tb_debug_create_field(m->mod, cg_debug_type(m, type), name.len, cast(char const *)name.text, 0);
- }
- Type *last_type = pt->results->Tuple.variables[pt->results->Tuple.variables.count-1]->type;
- if (is_type_proc(last_type)) {
- last_type = t_rawptr;
- }
- returns[return_index++] = cg_debug_type(m, last_type);
- } else {
- returns[return_index++] = cg_debug_type(m, pt->results);
- }
- }
- if (pt->calling_convention == ProcCC_Odin) {
- Type *type = t_context_ptr;
- String name = str_lit("__.context_ptr");
- params[param_index++] = tb_debug_create_field(m->mod, cg_debug_type(m, type), name.len, cast(char const *)name.text, 0);
- }
- GB_ASSERT_MSG(param_index == param_count, "%td vs %td for %s", param_index, param_count, type_to_string(type));
- GB_ASSERT_MSG(return_index == return_count, "%td vs %td for %s", return_index, return_count, type_to_string(type));
- return func_ptr;
- }
- 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);
- }
|