tilde_debug.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. gb_internal TB_DebugType *cg_debug_type_internal(cgModule *m, Type *type);
  2. gb_internal TB_DebugType *cg_debug_type(cgModule *m, Type *type) {
  3. type = reduce_tuple_to_single_type(type);
  4. mutex_lock(&m->debug_type_mutex);
  5. defer (mutex_unlock(&m->debug_type_mutex));
  6. TB_DebugType **found = map_get(&m->debug_type_map, type);
  7. if (found) {
  8. return *found;
  9. }
  10. TB_DebugType *res = cg_debug_type_internal(m, type);
  11. map_set(&m->debug_type_map, type, res);
  12. return res;
  13. }
  14. gb_internal TB_DebugType *cg_debug_type_for_proc(cgModule *m, Type *type) {
  15. GB_ASSERT(is_type_proc(type));
  16. TB_DebugType **func_found = nullptr;
  17. TB_DebugType *func_ptr = cg_debug_type(m, type);
  18. GB_ASSERT(func_ptr != nullptr);
  19. mutex_lock(&m->debug_type_mutex);
  20. func_found = map_get(&m->proc_debug_type_map, type);
  21. mutex_unlock(&m->debug_type_mutex);
  22. GB_ASSERT(func_found != nullptr);
  23. return *func_found;
  24. }
  25. gb_internal TB_DebugType *cg_debug_type_internal_record(cgModule *m, Type *type, String const &record_name) {
  26. Type *bt = base_type(type);
  27. switch (bt->kind) {
  28. case Type_Struct:
  29. {
  30. type_set_offsets(bt);
  31. TB_DebugType *record = nullptr;
  32. if (bt->Struct.is_raw_union) {
  33. record = tb_debug_create_union(m->mod, record_name.len, cast(char const *)record_name.text);
  34. } else {
  35. record = tb_debug_create_struct(m->mod, record_name.len, cast(char const *)record_name.text);
  36. }
  37. if (record_name.len != 0) {
  38. map_set(&m->debug_type_map, type, record);
  39. }
  40. TB_DebugType **fields = tb_debug_record_begin(record, bt->Struct.fields.count);
  41. for_array(i, bt->Struct.fields) {
  42. Entity *e = bt->Struct.fields[i];
  43. Type *type = e->type;
  44. if (is_type_proc(type)) {
  45. type = t_rawptr;
  46. }
  47. TB_DebugType *field_type = cg_debug_type(m, type);
  48. String name = e->token.string;
  49. TB_CharUnits offset = cast(TB_CharUnits)bt->Struct.offsets[i];
  50. if (name.len == 0) {
  51. name = str_lit("_");
  52. }
  53. fields[i] = tb_debug_create_field(m->mod, field_type, name.len, cast(char const *)name.text, offset);
  54. }
  55. tb_debug_record_end(
  56. record,
  57. cast(TB_CharUnits)type_size_of(type),
  58. cast(TB_CharUnits)type_align_of(type)
  59. );
  60. return record;
  61. }
  62. break;
  63. case Type_Tuple:
  64. {
  65. GB_ASSERT(record_name.len == 0);
  66. type_set_offsets(bt);
  67. TB_DebugType *record = tb_debug_create_struct(m->mod, 0, "");
  68. TB_DebugType **fields = tb_debug_record_begin(record, bt->Tuple.variables.count);
  69. for_array(i, bt->Tuple.variables) {
  70. Entity *e = bt->Tuple.variables[i];
  71. Type *type = e->type;
  72. if (is_type_proc(type)) {
  73. type = t_rawptr;
  74. }
  75. TB_DebugType *field_type = cg_debug_type(m, type);
  76. String name = e->token.string;
  77. TB_CharUnits offset = cast(TB_CharUnits)bt->Tuple.offsets[i];
  78. if (name.len == 0) {
  79. name = str_lit("_");
  80. }
  81. fields[i] = tb_debug_create_field(m->mod, field_type, name.len, cast(char const *)name.text, offset);
  82. }
  83. tb_debug_record_end(
  84. record,
  85. cast(TB_CharUnits)type_size_of(type),
  86. cast(TB_CharUnits)type_align_of(type)
  87. );
  88. return record;
  89. }
  90. break;
  91. case Type_Union:
  92. {
  93. TB_DebugType *record = tb_debug_create_struct(m->mod, record_name.len, cast(char const *)record_name.text);
  94. if (record_name.len != 0) {
  95. map_set(&m->debug_type_map, type, record);
  96. }
  97. i64 variant_count = bt->Union.variants.count;
  98. if (is_type_union_maybe_pointer(bt)) {
  99. // NO TAG
  100. GB_ASSERT(variant_count == 1);
  101. TB_DebugType **fields = tb_debug_record_begin(record, variant_count);
  102. TB_DebugType *variant_type = cg_debug_type(m, bt->Union.variants[0]);
  103. fields[0] = tb_debug_create_field(m->mod, variant_type, -1, "v0", 0);
  104. tb_debug_record_end(
  105. record,
  106. cast(TB_CharUnits)type_size_of(type),
  107. cast(TB_CharUnits)type_align_of(type)
  108. );
  109. } else {
  110. TB_DebugType **fields = tb_debug_record_begin(record, variant_count+1);
  111. for_array(i, bt->Union.variants) {
  112. Type *v = bt->Union.variants[i];
  113. TB_DebugType *variant_type = cg_debug_type(m, v);
  114. char name[32] = {};
  115. u32 v_index = cast(u32)i;
  116. if (bt->Union.kind != UnionType_no_nil) {
  117. v_index += 1;
  118. }
  119. gb_snprintf(name, 31, "v%u", v_index);
  120. fields[i] = tb_debug_create_field(m->mod, variant_type, -1, name, 0);
  121. }
  122. TB_DebugType *tag_type = cg_debug_type(m, union_tag_type(bt));
  123. fields[variant_count] = tb_debug_create_field(m->mod, tag_type, -1, "tag", cast(TB_CharUnits)bt->Union.variant_block_size);
  124. }
  125. tb_debug_record_end(
  126. record,
  127. cast(TB_CharUnits)type_size_of(type),
  128. cast(TB_CharUnits)type_align_of(type)
  129. );
  130. return record;
  131. }
  132. break;
  133. }
  134. return nullptr;
  135. }
  136. gb_internal TB_DebugType *cg_debug_type_internal(cgModule *m, Type *type) {
  137. if (type == nullptr) {
  138. return tb_debug_get_void(m->mod);
  139. }
  140. Type *original_type = type;
  141. if (type->kind == Type_Named) {
  142. String name = type->Named.name;
  143. TB_DebugType *res = cg_debug_type_internal_record(m, type, name);
  144. if (res) {
  145. return res;
  146. }
  147. type = base_type(type->Named.base);
  148. }
  149. TB_CharUnits int_size = cast(TB_CharUnits)build_context.int_size;
  150. TB_CharUnits ptr_size = cast(TB_CharUnits)build_context.ptr_size;
  151. TB_CharUnits size = cast(TB_CharUnits)type_size_of(type);
  152. TB_CharUnits align = cast(TB_CharUnits)type_align_of(type);
  153. int bits = cast(int)(8*size);
  154. bool is_signed = is_type_integer(core_type(type)) && !is_type_unsigned(core_type(type));
  155. switch (type->kind) {
  156. case Type_Basic:
  157. switch (type->Basic.kind) {
  158. case Basic_bool: return tb_debug_get_bool(m->mod);
  159. case Basic_b8: return tb_debug_get_bool(m->mod);
  160. case Basic_b16: return tb_debug_get_integer(m->mod, is_signed, bits);
  161. case Basic_b32: return tb_debug_get_integer(m->mod, is_signed, bits);
  162. case Basic_b64: return tb_debug_get_integer(m->mod, is_signed, bits);
  163. case Basic_i8: return tb_debug_get_integer(m->mod, is_signed, bits);
  164. case Basic_u8: return tb_debug_get_integer(m->mod, is_signed, bits);
  165. case Basic_i16: return tb_debug_get_integer(m->mod, is_signed, bits);
  166. case Basic_u16: return tb_debug_get_integer(m->mod, is_signed, bits);
  167. case Basic_i32: return tb_debug_get_integer(m->mod, is_signed, bits);
  168. case Basic_u32: return tb_debug_get_integer(m->mod, is_signed, bits);
  169. case Basic_i64: return tb_debug_get_integer(m->mod, is_signed, bits);
  170. case Basic_u64: return tb_debug_get_integer(m->mod, is_signed, bits);
  171. case Basic_i128: return tb_debug_get_integer(m->mod, is_signed, bits);
  172. case Basic_u128: return tb_debug_get_integer(m->mod, is_signed, bits);
  173. case Basic_rune: return tb_debug_get_integer(m->mod, is_signed, bits);
  174. case Basic_f16: return tb_debug_get_integer(m->mod, false, bits);
  175. case Basic_f32: return tb_debug_get_float(m->mod, TB_FLT_32);
  176. case Basic_f64: return tb_debug_get_float(m->mod, TB_FLT_64);
  177. case Basic_complex32:
  178. case Basic_complex64:
  179. case Basic_complex128:
  180. {
  181. String name = basic_types[type->Basic.kind].Basic.name;
  182. TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
  183. Type *et = base_complex_elem_type(type);
  184. TB_CharUnits elem_size = cast(TB_CharUnits)type_size_of(et);
  185. TB_DebugType *elem = cg_debug_type(m, et);
  186. TB_DebugType **fields = tb_debug_record_begin(record, 2);
  187. fields[0] = tb_debug_create_field(m->mod, elem, -1, "real", 0*elem_size);
  188. fields[1] = tb_debug_create_field(m->mod, elem, -1, "imag", 1*elem_size);
  189. tb_debug_record_end(record, size, align);
  190. return record;
  191. }
  192. case Basic_quaternion64:
  193. case Basic_quaternion128:
  194. case Basic_quaternion256:
  195. {
  196. String name = basic_types[type->Basic.kind].Basic.name;
  197. TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
  198. Type *et = base_complex_elem_type(type);
  199. TB_CharUnits elem_size = cast(TB_CharUnits)type_size_of(et);
  200. TB_DebugType *elem = cg_debug_type(m, et);
  201. // @QuaternionLayout
  202. TB_DebugType **fields = tb_debug_record_begin(record, 4);
  203. fields[0] = tb_debug_create_field(m->mod, elem, -1, "imag", 0*elem_size);
  204. fields[1] = tb_debug_create_field(m->mod, elem, -1, "jmag", 1*elem_size);
  205. fields[2] = tb_debug_create_field(m->mod, elem, -1, "kmag", 2*elem_size);
  206. fields[3] = tb_debug_create_field(m->mod, elem, -1, "real", 3*elem_size);
  207. tb_debug_record_end(record, size, align);
  208. return record;
  209. }
  210. case Basic_int: return tb_debug_get_integer(m->mod, is_signed, bits);
  211. case Basic_uint: return tb_debug_get_integer(m->mod, is_signed, bits);
  212. case Basic_uintptr: return tb_debug_get_integer(m->mod, is_signed, bits);
  213. case Basic_rawptr:
  214. return tb_debug_create_ptr(m->mod, tb_debug_get_void(m->mod));
  215. case Basic_string:
  216. {
  217. String name = basic_types[type->Basic.kind].Basic.name;
  218. TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
  219. // @QuaternionLayout
  220. TB_DebugType **fields = tb_debug_record_begin(record, 2);
  221. fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, t_u8_ptr), -1, "data", 0*int_size);
  222. fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "len", 1*int_size);
  223. tb_debug_record_end(record, size, align);
  224. return record;
  225. }
  226. case Basic_cstring:
  227. return tb_debug_create_ptr(m->mod, tb_debug_get_integer(m->mod, false, 8));
  228. case Basic_any:
  229. {
  230. String name = basic_types[type->Basic.kind].Basic.name;
  231. TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
  232. // @QuaternionLayout
  233. TB_DebugType **fields = tb_debug_record_begin(record, 2);
  234. fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, t_rawptr), -1, "data", 0*ptr_size);
  235. fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_typeid), -1, "id", 1*ptr_size);
  236. tb_debug_record_end(record, size, align);
  237. return record;
  238. }
  239. case Basic_typeid: return tb_debug_get_integer(m->mod, false, bits);
  240. case Basic_i16le: return tb_debug_get_integer(m->mod, is_signed, bits);
  241. case Basic_u16le: return tb_debug_get_integer(m->mod, is_signed, bits);
  242. case Basic_i32le: return tb_debug_get_integer(m->mod, is_signed, bits);
  243. case Basic_u32le: return tb_debug_get_integer(m->mod, is_signed, bits);
  244. case Basic_i64le: return tb_debug_get_integer(m->mod, is_signed, bits);
  245. case Basic_u64le: return tb_debug_get_integer(m->mod, is_signed, bits);
  246. case Basic_i128le: return tb_debug_get_integer(m->mod, is_signed, bits);
  247. case Basic_u128le: return tb_debug_get_integer(m->mod, is_signed, bits);
  248. case Basic_i16be: return tb_debug_get_integer(m->mod, is_signed, bits);
  249. case Basic_u16be: return tb_debug_get_integer(m->mod, is_signed, bits);
  250. case Basic_i32be: return tb_debug_get_integer(m->mod, is_signed, bits);
  251. case Basic_u32be: return tb_debug_get_integer(m->mod, is_signed, bits);
  252. case Basic_i64be: return tb_debug_get_integer(m->mod, is_signed, bits);
  253. case Basic_u64be: return tb_debug_get_integer(m->mod, is_signed, bits);
  254. case Basic_i128be: return tb_debug_get_integer(m->mod, is_signed, bits);
  255. case Basic_u128be: return tb_debug_get_integer(m->mod, is_signed, bits);
  256. case Basic_f16le: return tb_debug_get_integer(m->mod, false, bits);
  257. case Basic_f32le: return tb_debug_get_float(m->mod, TB_FLT_32);
  258. case Basic_f64le: return tb_debug_get_float(m->mod, TB_FLT_64);
  259. case Basic_f16be: return tb_debug_get_integer(m->mod, false, bits);
  260. case Basic_f32be: return tb_debug_get_float(m->mod, TB_FLT_32);
  261. case Basic_f64be: return tb_debug_get_float(m->mod, TB_FLT_64);
  262. }
  263. break;
  264. case Type_Generic:
  265. GB_PANIC("SHOULD NEVER HIT");
  266. break;
  267. case Type_Pointer:
  268. return tb_debug_create_ptr(m->mod, cg_debug_type(m, type->Pointer.elem));
  269. case Type_MultiPointer:
  270. return tb_debug_create_ptr(m->mod, cg_debug_type(m, type->MultiPointer.elem));
  271. case Type_Array:
  272. return tb_debug_create_array(m->mod, cg_debug_type(m, type->Array.elem), type->Array.count);
  273. case Type_EnumeratedArray:
  274. return tb_debug_create_array(m->mod, cg_debug_type(m, type->EnumeratedArray.elem), type->EnumeratedArray.count);
  275. case Type_Slice:
  276. {
  277. String name = {};
  278. TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
  279. TB_DebugType **fields = tb_debug_record_begin(record, 2);
  280. fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, alloc_type_pointer(type->Slice.elem)), -1, "data", 0*int_size);
  281. fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "len", 1*int_size);
  282. tb_debug_record_end(record, size, align);
  283. return record;
  284. }
  285. case Type_DynamicArray:
  286. {
  287. String name = {};
  288. TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
  289. TB_DebugType **fields = tb_debug_record_begin(record, 4);
  290. fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, alloc_type_pointer(type->Slice.elem)), -1, "data", 0*int_size);
  291. fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "len", 1*int_size);
  292. fields[2] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "cap", 2*int_size);
  293. fields[3] = tb_debug_create_field(m->mod, cg_debug_type(m, t_allocator), -1, "allocator", 3*int_size);
  294. tb_debug_record_end(record, size, align);
  295. return record;
  296. }
  297. case Type_Map:
  298. return cg_debug_type(m, t_raw_map);
  299. case Type_Struct:
  300. case Type_Tuple:
  301. case Type_Union:
  302. return cg_debug_type_internal_record(m, type, {});
  303. case Type_Enum:
  304. return tb_debug_get_integer(m->mod, is_signed, bits);
  305. case Type_Proc:
  306. {
  307. TypeProc *pt = &type->Proc;
  308. isize param_count = 0;
  309. isize return_count = 0;
  310. bool is_odin_cc = is_calling_convention_odin(pt->calling_convention);
  311. if (pt->params) for (Entity *e : pt->params->Tuple.variables) {
  312. if (e->kind == Entity_Variable) {
  313. param_count += 1;
  314. }
  315. }
  316. if (pt->result_count > 0) {
  317. if (is_odin_cc) {
  318. // Split returns
  319. param_count += pt->result_count-1;
  320. return_count = 1;
  321. } else {
  322. return_count = 1;
  323. }
  324. }
  325. if (pt->calling_convention == ProcCC_Odin) {
  326. // `context` ptr
  327. param_count += 1;
  328. }
  329. TB_DebugType *func = tb_debug_create_func(m->mod, TB_CDECL, param_count, return_count, pt->c_vararg);
  330. map_set(&m->proc_debug_type_map, original_type, func);
  331. map_set(&m->proc_debug_type_map, type, func);
  332. TB_DebugType *func_ptr = tb_debug_create_ptr(m->mod, func);
  333. map_set(&m->debug_type_map, original_type, func_ptr);
  334. map_set(&m->debug_type_map, type, func_ptr);
  335. TB_DebugType **params = tb_debug_func_params(func);
  336. TB_DebugType **returns = tb_debug_func_returns(func);
  337. isize param_index = 0;
  338. isize return_index = 0;
  339. if (pt->params) for (Entity *e : pt->params->Tuple.variables) {
  340. if (e->kind == Entity_Variable) {
  341. Type *type = e->type;
  342. if (is_type_proc(type)) {
  343. type = t_rawptr;
  344. }
  345. String name = e->token.string;
  346. if (name.len == 0) {
  347. name = str_lit("_");
  348. }
  349. params[param_index++] = tb_debug_create_field(m->mod, cg_debug_type(m, type), name.len, cast(char const *)name.text, 0);
  350. }
  351. }
  352. if (pt->result_count) {
  353. GB_ASSERT(pt->results);
  354. if (is_odin_cc) {
  355. // Split Returns
  356. for (isize i = 0; i < pt->results->Tuple.variables.count-1; i++) {
  357. Entity *e = pt->results->Tuple.variables[i];
  358. GB_ASSERT(e->kind == Entity_Variable);
  359. Type *type = e->type;
  360. if (is_type_proc(e->type)) {
  361. type = t_rawptr;
  362. }
  363. type = alloc_type_pointer(type);
  364. String name = e->token.string;
  365. if (name.len == 0) {
  366. name = str_lit("_");
  367. }
  368. params[param_index++] = tb_debug_create_field(m->mod, cg_debug_type(m, type), name.len, cast(char const *)name.text, 0);
  369. }
  370. Type *last_type = pt->results->Tuple.variables[pt->results->Tuple.variables.count-1]->type;
  371. if (is_type_proc(last_type)) {
  372. last_type = t_rawptr;
  373. }
  374. returns[return_index++] = cg_debug_type(m, last_type);
  375. } else {
  376. returns[return_index++] = cg_debug_type(m, pt->results);
  377. }
  378. }
  379. if (pt->calling_convention == ProcCC_Odin) {
  380. Type *type = t_context_ptr;
  381. String name = str_lit("__.context_ptr");
  382. params[param_index++] = tb_debug_create_field(m->mod, cg_debug_type(m, type), name.len, cast(char const *)name.text, 0);
  383. }
  384. GB_ASSERT_MSG(param_index == param_count, "%td vs %td for %s", param_index, param_count, type_to_string(type));
  385. GB_ASSERT_MSG(return_index == return_count, "%td vs %td for %s", return_index, return_count, type_to_string(type));
  386. return func_ptr;
  387. }
  388. break;
  389. case Type_BitSet:
  390. return cg_debug_type(m, bit_set_to_int(type));
  391. case Type_SimdVector:
  392. return tb_debug_create_array(m->mod, cg_debug_type(m, type->SimdVector.elem), type->SimdVector.count);
  393. case Type_RelativePointer:
  394. return cg_debug_type(m, type->RelativePointer.base_integer);
  395. case Type_RelativeSlice:
  396. {
  397. String name = {};
  398. TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
  399. TB_DebugType *base_integer = cg_debug_type(m, type->RelativeSlice.base_integer);
  400. TB_CharUnits bi_size = cast(TB_CharUnits)type_size_of(type->RelativeSlice.base_integer);
  401. TB_DebugType **fields = tb_debug_record_begin(record, 2);
  402. fields[0] = tb_debug_create_field(m->mod, base_integer, -1, "data", 0*bi_size);
  403. fields[1] = tb_debug_create_field(m->mod, base_integer, -1, "len", 1*bi_size);
  404. tb_debug_record_end(record, size, align);
  405. return record;
  406. }
  407. case Type_Matrix:
  408. {
  409. i64 count = matrix_type_total_internal_elems(type);
  410. return tb_debug_create_array(m->mod, cg_debug_type(m, type->Matrix.elem), count);
  411. }
  412. case Type_SoaPointer:
  413. {
  414. String name = {};
  415. TB_DebugType *record = tb_debug_create_struct(m->mod, name.len, cast(char const *)name.text);
  416. TB_DebugType **fields = tb_debug_record_begin(record, 2);
  417. fields[0] = tb_debug_create_field(m->mod, cg_debug_type(m, alloc_type_pointer(type->SoaPointer.elem)), -1, "ptr", 0*int_size);
  418. fields[1] = tb_debug_create_field(m->mod, cg_debug_type(m, t_int), -1, "offset", 1*int_size);
  419. tb_debug_record_end(record, size, align);
  420. return record;
  421. }
  422. }
  423. // TODO(bill): cg_debug_type
  424. return tb_debug_get_void(m->mod);
  425. }