type.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779
  1. struct Scope;
  2. enum BasicKind {
  3. Basic_Invalid,
  4. Basic_bool,
  5. Basic_i8,
  6. Basic_i16,
  7. Basic_i32,
  8. Basic_i64,
  9. Basic_i128,
  10. Basic_u8,
  11. Basic_u16,
  12. Basic_u32,
  13. Basic_u64,
  14. Basic_u128,
  15. Basic_f32,
  16. Basic_f64,
  17. Basic_int,
  18. Basic_uint,
  19. Basic_rawptr,
  20. Basic_string,
  21. Basic_UntypedBool,
  22. Basic_UntypedInteger,
  23. Basic_UntypedFloat,
  24. Basic_UntypedPointer,
  25. Basic_UntypedString,
  26. Basic_UntypedRune,
  27. Basic_Count,
  28. Basic_byte = Basic_u8,
  29. Basic_rune = Basic_i32,
  30. };
  31. enum BasicFlag : u32 {
  32. BasicFlag_Boolean = GB_BIT(0),
  33. BasicFlag_Integer = GB_BIT(1),
  34. BasicFlag_Unsigned = GB_BIT(2),
  35. BasicFlag_Float = GB_BIT(3),
  36. BasicFlag_Pointer = GB_BIT(4),
  37. BasicFlag_String = GB_BIT(5),
  38. BasicFlag_Rune = GB_BIT(6),
  39. BasicFlag_Untyped = GB_BIT(7),
  40. BasicFlag_Numeric = BasicFlag_Integer | BasicFlag_Float,
  41. BasicFlag_Ordered = BasicFlag_Numeric | BasicFlag_String | BasicFlag_Pointer,
  42. BasicFlag_ConstantType = BasicFlag_Boolean | BasicFlag_Numeric | BasicFlag_Pointer | BasicFlag_String | BasicFlag_Rune,
  43. };
  44. struct BasicType {
  45. BasicKind kind;
  46. u32 flags;
  47. String name;
  48. };
  49. #define TYPE_KINDS \
  50. TYPE_KIND(Invalid), \
  51. TYPE_KIND(Basic), \
  52. TYPE_KIND(Array), \
  53. TYPE_KIND(Vector), \
  54. TYPE_KIND(Slice), \
  55. TYPE_KIND(Structure), \
  56. TYPE_KIND(Pointer), \
  57. TYPE_KIND(Named), \
  58. TYPE_KIND(Tuple), \
  59. TYPE_KIND(Proc), \
  60. TYPE_KIND(Count),
  61. enum TypeKind {
  62. #define TYPE_KIND(k) GB_JOIN2(Type_, k)
  63. TYPE_KINDS
  64. #undef TYPE_KIND
  65. };
  66. String const type_strings[] = {
  67. #define TYPE_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1}
  68. TYPE_KINDS
  69. #undef TYPE_KIND
  70. };
  71. enum TypeFlag {
  72. TypeFlag_thread_local = GB_BIT(0),
  73. TypeFlag_volatile = GB_BIT(1),
  74. };
  75. struct Type {
  76. u32 flags;
  77. TypeKind kind;
  78. union {
  79. BasicType basic;
  80. struct {
  81. Type *elem;
  82. i64 count;
  83. } array;
  84. struct {
  85. Type *elem;
  86. i64 count;
  87. } vector;
  88. struct {
  89. Type *elem;
  90. } slice;
  91. struct {
  92. // Theses are arrays
  93. Entity **fields; // Entity_Variable
  94. isize field_count; // == offset_count
  95. i64 * offsets;
  96. b32 are_offsets_set;
  97. b32 is_packed;
  98. } structure;
  99. struct { Type *elem; } pointer;
  100. struct {
  101. String name;
  102. Type * base;
  103. Entity *type_name; // Entity_TypeName
  104. } named;
  105. struct {
  106. Entity **variables; // Entity_Variable
  107. isize variable_count;
  108. } tuple;
  109. struct {
  110. Scope *scope;
  111. Type * params; // Type_Tuple
  112. Type * results; // Type_Tuple
  113. isize param_count;
  114. isize result_count;
  115. } proc;
  116. };
  117. };
  118. Type *get_base_type(Type *t) {
  119. while (t->kind == Type_Named) {
  120. t = t->named.base;
  121. }
  122. return t;
  123. }
  124. void set_base_type(Type *t, Type *base) {
  125. if (t && t->kind == Type_Named) {
  126. t->named.base = base;
  127. }
  128. }
  129. Type *alloc_type(gbAllocator a, TypeKind kind) {
  130. Type *t = gb_alloc_item(a, Type);
  131. t->kind = kind;
  132. return t;
  133. }
  134. Type *make_type_basic(gbAllocator a, BasicType basic) {
  135. Type *t = alloc_type(a, Type_Basic);
  136. t->basic = basic;
  137. return t;
  138. }
  139. Type *make_type_array(gbAllocator a, Type *elem, i64 count) {
  140. Type *t = alloc_type(a, Type_Array);
  141. t->array.elem = elem;
  142. t->array.count = count;
  143. return t;
  144. }
  145. Type *make_type_vector(gbAllocator a, Type *elem, i64 count) {
  146. Type *t = alloc_type(a, Type_Vector);
  147. t->vector.elem = elem;
  148. t->vector.count = count;
  149. return t;
  150. }
  151. Type *make_type_slice(gbAllocator a, Type *elem) {
  152. Type *t = alloc_type(a, Type_Slice);
  153. t->array.elem = elem;
  154. return t;
  155. }
  156. Type *make_type_structure(gbAllocator a) {
  157. Type *t = alloc_type(a, Type_Structure);
  158. return t;
  159. }
  160. Type *make_type_pointer(gbAllocator a, Type *elem) {
  161. Type *t = alloc_type(a, Type_Pointer);
  162. t->pointer.elem = elem;
  163. return t;
  164. }
  165. Type *make_type_named(gbAllocator a, String name, Type *base, Entity *type_name) {
  166. Type *t = alloc_type(a, Type_Named);
  167. t->named.name = name;
  168. t->named.base = base;
  169. t->named.type_name = type_name;
  170. return t;
  171. }
  172. Type *make_type_tuple(gbAllocator a) {
  173. Type *t = alloc_type(a, Type_Tuple);
  174. return t;
  175. }
  176. Type *make_type_proc(gbAllocator a, Scope *scope, Type *params, isize param_count, Type *results, isize result_count) {
  177. Type *t = alloc_type(a, Type_Proc);
  178. t->proc.scope = scope;
  179. t->proc.params = params;
  180. t->proc.param_count = param_count;
  181. t->proc.results = results;
  182. t->proc.result_count = result_count;
  183. return t;
  184. }
  185. Type *type_deref(Type *t) {
  186. if (t != NULL) {
  187. Type *bt = get_base_type(t);
  188. if (bt != NULL && bt->kind == Type_Pointer)
  189. return bt->pointer.elem;
  190. }
  191. return t;
  192. }
  193. #define STR_LIT(x) {cast(u8 *)(x), gb_size_of(x)-1}
  194. gb_global Type basic_types[] = {
  195. {0, Type_Basic, {Basic_Invalid, 0, STR_LIT("invalid type")}},
  196. {0, Type_Basic, {Basic_bool, BasicFlag_Boolean, STR_LIT("bool")}},
  197. {0, Type_Basic, {Basic_i8, BasicFlag_Integer, STR_LIT("i8")}},
  198. {0, Type_Basic, {Basic_i16, BasicFlag_Integer, STR_LIT("i16")}},
  199. {0, Type_Basic, {Basic_i32, BasicFlag_Integer, STR_LIT("i32")}},
  200. {0, Type_Basic, {Basic_i64, BasicFlag_Integer, STR_LIT("i64")}},
  201. {0, Type_Basic, {Basic_i128, BasicFlag_Integer, STR_LIT("i128")}},
  202. {0, Type_Basic, {Basic_u8, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u8")}},
  203. {0, Type_Basic, {Basic_u16, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u16")}},
  204. {0, Type_Basic, {Basic_u32, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u32")}},
  205. {0, Type_Basic, {Basic_u64, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u64")}},
  206. {0, Type_Basic, {Basic_u128, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("u128")}},
  207. {0, Type_Basic, {Basic_f32, BasicFlag_Float, STR_LIT("f32")}},
  208. {0, Type_Basic, {Basic_f64, BasicFlag_Float, STR_LIT("f64")}},
  209. {0, Type_Basic, {Basic_int, BasicFlag_Integer, STR_LIT("int")}},
  210. {0, Type_Basic, {Basic_uint, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("uint")}},
  211. {0, Type_Basic, {Basic_rawptr, BasicFlag_Pointer, STR_LIT("rawptr")}},
  212. {0, Type_Basic, {Basic_string, BasicFlag_String, STR_LIT("string")}},
  213. {0, Type_Basic, {Basic_UntypedBool, BasicFlag_Boolean | BasicFlag_Untyped, STR_LIT("untyped bool")}},
  214. {0, Type_Basic, {Basic_UntypedInteger, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped integer")}},
  215. {0, Type_Basic, {Basic_UntypedFloat, BasicFlag_Float | BasicFlag_Untyped, STR_LIT("untyped float")}},
  216. {0, Type_Basic, {Basic_UntypedPointer, BasicFlag_Pointer | BasicFlag_Untyped, STR_LIT("untyped pointer")}},
  217. {0, Type_Basic, {Basic_UntypedString, BasicFlag_String | BasicFlag_Untyped, STR_LIT("untyped string")}},
  218. {0, Type_Basic, {Basic_UntypedRune, BasicFlag_Integer | BasicFlag_Untyped, STR_LIT("untyped rune")}},
  219. };
  220. gb_global Type basic_type_aliases[] = {
  221. {0, Type_Basic, {Basic_byte, BasicFlag_Integer | BasicFlag_Unsigned, STR_LIT("byte")}},
  222. {0, Type_Basic, {Basic_rune, BasicFlag_Integer, STR_LIT("rune")}},
  223. };
  224. gb_global Type *t_invalid = &basic_types[Basic_Invalid];
  225. gb_global Type *t_bool = &basic_types[Basic_bool];
  226. gb_global Type *t_i8 = &basic_types[Basic_i8];
  227. gb_global Type *t_i16 = &basic_types[Basic_i16];
  228. gb_global Type *t_i32 = &basic_types[Basic_i32];
  229. gb_global Type *t_i64 = &basic_types[Basic_i64];
  230. gb_global Type *t_i128 = &basic_types[Basic_i128];
  231. gb_global Type *t_u8 = &basic_types[Basic_u8];
  232. gb_global Type *t_u16 = &basic_types[Basic_u16];
  233. gb_global Type *t_u32 = &basic_types[Basic_u32];
  234. gb_global Type *t_u64 = &basic_types[Basic_u64];
  235. gb_global Type *t_u128 = &basic_types[Basic_u128];
  236. gb_global Type *t_f32 = &basic_types[Basic_f32];
  237. gb_global Type *t_f64 = &basic_types[Basic_f64];
  238. gb_global Type *t_int = &basic_types[Basic_int];
  239. gb_global Type *t_uint = &basic_types[Basic_uint];
  240. gb_global Type *t_rawptr = &basic_types[Basic_rawptr];
  241. gb_global Type *t_string = &basic_types[Basic_string];
  242. gb_global Type *t_untyped_bool = &basic_types[Basic_UntypedBool];
  243. gb_global Type *t_untyped_integer = &basic_types[Basic_UntypedInteger];
  244. gb_global Type *t_untyped_float = &basic_types[Basic_UntypedFloat];
  245. gb_global Type *t_untyped_pointer = &basic_types[Basic_UntypedPointer];
  246. gb_global Type *t_untyped_string = &basic_types[Basic_UntypedString];
  247. gb_global Type *t_untyped_rune = &basic_types[Basic_UntypedRune];
  248. gb_global Type *t_byte = &basic_type_aliases[Basic_byte];
  249. gb_global Type *t_rune = &basic_type_aliases[Basic_rune];
  250. b32 is_type_named(Type *t) {
  251. if (t->kind == Type_Basic)
  252. return true;
  253. return t->kind == Type_Named;
  254. }
  255. b32 is_type_boolean(Type *t) {
  256. t = get_base_type(t);
  257. if (t->kind == Type_Basic)
  258. return (t->basic.flags & BasicFlag_Boolean) != 0;
  259. return false;
  260. }
  261. b32 is_type_integer(Type *t) {
  262. t = get_base_type(t);
  263. if (t->kind == Type_Basic)
  264. return (t->basic.flags & BasicFlag_Integer) != 0;
  265. return false;
  266. }
  267. b32 is_type_unsigned(Type *t) {
  268. t = get_base_type(t);
  269. if (t->kind == Type_Basic)
  270. return (t->basic.flags & BasicFlag_Unsigned) != 0;
  271. return false;
  272. }
  273. b32 is_type_numeric(Type *t) {
  274. t = get_base_type(t);
  275. if (t->kind == Type_Basic)
  276. return (t->basic.flags & BasicFlag_Numeric) != 0;
  277. if (t->kind == Type_Vector)
  278. return is_type_numeric(t->vector.elem);
  279. return false;
  280. }
  281. b32 is_type_string(Type *t) {
  282. t = get_base_type(t);
  283. if (t->kind == Type_Basic)
  284. return (t->basic.flags & BasicFlag_String) != 0;
  285. return false;
  286. }
  287. b32 is_type_typed(Type *t) {
  288. t = get_base_type(t);
  289. if (t->kind == Type_Basic)
  290. return (t->basic.flags & BasicFlag_Untyped) == 0;
  291. return true;
  292. }
  293. b32 is_type_untyped(Type *t) {
  294. t = get_base_type(t);
  295. if (t->kind == Type_Basic)
  296. return (t->basic.flags & BasicFlag_Untyped) != 0;
  297. return false;
  298. }
  299. b32 is_type_ordered(Type *t) {
  300. t = get_base_type(t);
  301. if (t->kind == Type_Basic)
  302. return (t->basic.flags & BasicFlag_Ordered) != 0;
  303. if (t->kind == Type_Pointer)
  304. return true;
  305. return false;
  306. }
  307. b32 is_type_constant_type(Type *t) {
  308. t = get_base_type(t);
  309. if (t->kind == Type_Basic)
  310. return (t->basic.flags & BasicFlag_ConstantType) != 0;
  311. return false;
  312. }
  313. b32 is_type_float(Type *t) {
  314. t = get_base_type(t);
  315. if (t->kind == Type_Basic)
  316. return (t->basic.flags & BasicFlag_Float) != 0;
  317. return false;
  318. }
  319. b32 is_type_pointer(Type *t) {
  320. t = get_base_type(t);
  321. if (t->kind == Type_Basic)
  322. return (t->basic.flags & BasicFlag_Pointer) != 0;
  323. return t->kind == Type_Pointer;
  324. }
  325. b32 is_type_int_or_uint(Type *t) {
  326. if (t->kind == Type_Basic)
  327. return (t->basic.kind == Basic_int) || (t->basic.kind == Basic_uint);
  328. return false;
  329. }
  330. b32 is_type_rawptr(Type *t) {
  331. if (t->kind == Type_Basic)
  332. return t->basic.kind == Basic_rawptr;
  333. return false;
  334. }
  335. b32 is_type_u8(Type *t) {
  336. if (t->kind == Type_Basic)
  337. return t->basic.kind == Basic_u8;
  338. return false;
  339. }
  340. b32 is_type_slice(Type *t) {
  341. t = get_base_type(t);
  342. return t->kind == Type_Slice;
  343. }
  344. b32 is_type_u8_slice(Type *t) {
  345. t = get_base_type(t);
  346. if (t->kind == Type_Slice)
  347. return is_type_u8(t->slice.elem);
  348. return false;
  349. }
  350. b32 is_type_vector(Type *t) {
  351. return t->kind == Type_Vector;
  352. }
  353. b32 is_type_proc(Type *t) {
  354. t = get_base_type(t);
  355. return t->kind == Type_Proc;
  356. }
  357. Type *base_vector_type(Type *t) {
  358. if (is_type_vector(t)) {
  359. return t->vector.elem;
  360. }
  361. return t;
  362. }
  363. b32 is_type_comparable(Type *t) {
  364. t = get_base_type(t);
  365. switch (t->kind) {
  366. case Type_Basic:
  367. return true;
  368. case Type_Pointer:
  369. return true;
  370. case Type_Structure: {
  371. for (isize i = 0; i < t->structure.field_count; i++) {
  372. if (!is_type_comparable(t->structure.fields[i]->type))
  373. return false;
  374. }
  375. return true;
  376. } break;
  377. case Type_Array:
  378. return is_type_comparable(t->array.elem);
  379. case Type_Vector:
  380. return is_type_comparable(t->vector.elem);
  381. case Type_Proc:
  382. return true;
  383. }
  384. return false;
  385. }
  386. b32 are_types_identical(Type *x, Type *y) {
  387. if (x == y)
  388. return true;
  389. if ((x == NULL && y != NULL) ||
  390. (x != NULL && y == NULL)) {
  391. return false;
  392. }
  393. switch (x->kind) {
  394. case Type_Basic:
  395. if (y->kind == Type_Basic)
  396. return x->basic.kind == y->basic.kind;
  397. break;
  398. case Type_Array:
  399. if (y->kind == Type_Array)
  400. return (x->array.count == y->array.count) && are_types_identical(x->array.elem, y->array.elem);
  401. break;
  402. case Type_Vector:
  403. if (y->kind == Type_Vector)
  404. return (x->vector.count == y->vector.count) && are_types_identical(x->vector.elem, y->vector.elem);
  405. break;
  406. case Type_Slice:
  407. if (y->kind == Type_Slice)
  408. return are_types_identical(x->slice.elem, y->slice.elem);
  409. break;
  410. case Type_Structure:
  411. if (y->kind == Type_Structure) {
  412. if (x->structure.field_count == y->structure.field_count) {
  413. for (isize i = 0; i < x->structure.field_count; i++) {
  414. if (!are_types_identical(x->structure.fields[i]->type, y->structure.fields[i]->type)) {
  415. return false;
  416. }
  417. }
  418. return true;
  419. }
  420. }
  421. break;
  422. case Type_Pointer:
  423. if (y->kind == Type_Pointer)
  424. return are_types_identical(x->pointer.elem, y->pointer.elem);
  425. break;
  426. case Type_Named:
  427. if (y->kind == Type_Named)
  428. return x->named.base == y->named.base;
  429. break;
  430. case Type_Tuple:
  431. if (y->kind == Type_Tuple) {
  432. if (x->tuple.variable_count == y->tuple.variable_count) {
  433. for (isize i = 0; i < x->tuple.variable_count; i++) {
  434. if (!are_types_identical(x->tuple.variables[i]->type, y->tuple.variables[i]->type))
  435. return false;
  436. }
  437. return true;
  438. }
  439. }
  440. break;
  441. case Type_Proc:
  442. if (y->kind == Type_Proc) {
  443. return are_types_identical(x->proc.params, y->proc.params) &&
  444. are_types_identical(x->proc.results, y->proc.results);
  445. }
  446. break;
  447. }
  448. return false;
  449. }
  450. Type *default_type(Type *type) {
  451. if (type->kind == Type_Basic) {
  452. switch (type->basic.kind) {
  453. case Basic_UntypedBool: return &basic_types[Basic_bool];
  454. case Basic_UntypedInteger: return &basic_types[Basic_int];
  455. case Basic_UntypedFloat: return &basic_types[Basic_f64];
  456. case Basic_UntypedString: return &basic_types[Basic_string];
  457. case Basic_UntypedRune: return &basic_types[Basic_rune];
  458. case Basic_UntypedPointer: return &basic_types[Basic_rawptr];
  459. }
  460. }
  461. return type;
  462. }
  463. // NOTE(bill): Internal sizes of certain types
  464. // string: 2*word_size (ptr+len)
  465. // slice: 3*word_size (ptr+len+cap)
  466. // array: count*size_of(elem) aligned
  467. // NOTE(bill): Alignment of structures and other types are to be compatible with C
  468. struct BaseTypeSizes {
  469. i64 word_size;
  470. i64 max_align;
  471. };
  472. // TODO(bill): Change
  473. gb_global i64 basic_type_sizes[] = {
  474. 0, // Basic_Invalid
  475. 1, // Basic_bool
  476. 1, // Basic_i8
  477. 2, // Basic_i16
  478. 4, // Basic_i32
  479. 8, // Basic_i64
  480. 16, // Basic_i128
  481. 1, // Basic_u8
  482. 2, // Basic_u16
  483. 4, // Basic_u32
  484. 8, // Basic_u64
  485. 16, // Basic_u128
  486. 4, // Basic_f32
  487. 8, // Basic_f64
  488. };
  489. i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t);
  490. i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t);
  491. i64 type_offset_of(BaseTypeSizes s, gbAllocator allocator, Type *t, i64 index);
  492. i64 align_formula(i64 size, i64 align) {
  493. i64 result = size + align-1;
  494. return result - result%align;
  495. }
  496. i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
  497. t = get_base_type(t);
  498. switch (t->kind) {
  499. case Type_Array:
  500. return type_align_of(s, allocator, t->array.elem);
  501. case Type_Vector: {
  502. i64 size = type_size_of(s, allocator, t->vector.elem);
  503. size *= t->vector.count;
  504. size = next_pow2(size);
  505. // TODO(bill): Type_Vector type_align_of
  506. return gb_clamp(size, s.max_align, 4*s.max_align);
  507. } break;
  508. case Type_Structure: {
  509. if (!t->structure.is_packed) {
  510. i64 max = 1;
  511. for (isize i = 0; i < t->structure.field_count; i++) {
  512. i64 align = type_align_of(s, allocator, t->structure.fields[i]->type);
  513. if (max < align)
  514. max = align;
  515. }
  516. return max;
  517. }
  518. } break;
  519. }
  520. return gb_clamp(next_pow2(type_size_of(s, allocator, t)), 1, s.max_align);
  521. }
  522. i64 *type_set_offsets_of(BaseTypeSizes s, gbAllocator allocator, Entity **fields, isize field_count, b32 is_packed) {
  523. // TODO(bill): use arena allocation
  524. i64 *offsets = gb_alloc_array(allocator, i64, field_count);
  525. i64 curr_offset = 0;
  526. if (is_packed) {
  527. for (isize i = 0; i < field_count; i++) {
  528. offsets[i] = curr_offset;
  529. curr_offset += type_size_of(s, allocator, fields[i]->type);
  530. }
  531. } else {
  532. for (isize i = 0; i < field_count; i++) {
  533. i64 align = type_align_of(s, allocator, fields[i]->type);
  534. curr_offset = align_formula(curr_offset, align);
  535. offsets[i] = curr_offset;
  536. curr_offset += type_size_of(s, allocator, fields[i]->type);
  537. }
  538. }
  539. return offsets;
  540. }
  541. b32 type_set_offsets(BaseTypeSizes s, gbAllocator allocator, Type *t) {
  542. GB_ASSERT(t->kind == Type_Structure);
  543. if (!t->structure.are_offsets_set) {
  544. t->structure.offsets = type_set_offsets_of(s, allocator, t->structure.fields, t->structure.field_count, t->structure.is_packed);
  545. t->structure.are_offsets_set = true;
  546. return true;
  547. }
  548. return false;
  549. }
  550. i64 type_size_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
  551. t = get_base_type(t);
  552. switch (t->kind) {
  553. case Type_Basic: {
  554. GB_ASSERT(is_type_typed(t));
  555. BasicKind kind = t->basic.kind;
  556. if (kind < gb_count_of(basic_type_sizes)) {
  557. i64 size = basic_type_sizes[kind];
  558. if (size > 0)
  559. return size;
  560. }
  561. if (kind == Basic_string)
  562. return 2 * s.word_size;
  563. } break;
  564. case Type_Array: {
  565. i64 count = t->array.count;
  566. if (count == 0)
  567. return 0;
  568. i64 align = type_align_of(s, allocator, t->array.elem);
  569. i64 size = type_size_of(s, allocator, t->array.elem);
  570. i64 alignment = align_formula(size, align);
  571. return alignment*(count-1) + size;
  572. } break;
  573. case Type_Vector: {
  574. i64 count = t->vector.count;
  575. if (count == 0)
  576. return 0;
  577. // i64 align = type_align_of(s, allocator, t->vector.elem);
  578. i64 bit_size = 8*type_size_of(s, allocator, t->vector.elem);
  579. if (is_type_boolean(t->vector.elem)) {
  580. bit_size = 1; // NOTE(bill): LLVM can store booleans as 1 bit because a boolean _is_ an `i1`
  581. // Silly LLVM spec
  582. }
  583. i64 total_size_in_bits = bit_size * count;
  584. i64 total_size = (total_size_in_bits+7)/8;
  585. return total_size;
  586. // i64 alignment = align_formula(size, align);
  587. // return alignment*(count-1) + size;
  588. } break;
  589. case Type_Slice: // ptr + len + cap
  590. return 3 * s.word_size;
  591. case Type_Structure: {
  592. i64 count = t->structure.field_count;
  593. if (count == 0)
  594. return 0;
  595. type_set_offsets(s, allocator, t);
  596. return t->structure.offsets[count-1] + type_size_of(s, allocator, t->structure.fields[count-1]->type);
  597. } break;
  598. }
  599. // Catch all
  600. return s.word_size;
  601. }
  602. i64 type_offset_of(BaseTypeSizes s, gbAllocator allocator, Type *t, isize index) {
  603. if (t->kind == Type_Structure) {
  604. type_set_offsets(s, allocator, t);
  605. if (gb_is_between(index, 0, t->structure.field_count-1)) {
  606. return t->structure.offsets[index];
  607. }
  608. }
  609. return 0;
  610. }
  611. gbString write_type_to_string(gbString str, Type *type) {
  612. if (type == NULL) {
  613. return gb_string_appendc(str, "<no type>");
  614. }
  615. switch (type->kind) {
  616. case Type_Basic:
  617. str = gb_string_append_length(str, type->basic.name.text, type->basic.name.len);
  618. break;
  619. case Type_Array:
  620. str = gb_string_appendc(str, gb_bprintf("[%td]", type->array.count));
  621. str = write_type_to_string(str, type->array.elem);
  622. break;
  623. case Type_Vector:
  624. str = gb_string_appendc(str, gb_bprintf("{%td}", type->vector.count));
  625. str = write_type_to_string(str, type->vector.elem);
  626. break;
  627. case Type_Slice:
  628. str = gb_string_appendc(str, "[]");
  629. str = write_type_to_string(str, type->array.elem);
  630. break;
  631. case Type_Structure: {
  632. str = gb_string_appendc(str, "struct{");
  633. for (isize i = 0; i < type->structure.field_count; i++) {
  634. Entity *f = type->structure.fields[i];
  635. GB_ASSERT(f->kind == Entity_Variable);
  636. if (i > 0)
  637. str = gb_string_appendc(str, "; ");
  638. str = gb_string_append_length(str, f->token.string.text, f->token.string.len);
  639. str = gb_string_appendc(str, ": ");
  640. str = write_type_to_string(str, f->type);
  641. }
  642. str = gb_string_appendc(str, "}");
  643. } break;
  644. case Type_Pointer:
  645. str = gb_string_appendc(str, "^");
  646. str = write_type_to_string(str, type->pointer.elem);
  647. break;
  648. case Type_Named:
  649. if (type->named.type_name != NULL) {
  650. str = gb_string_append_length(str, type->named.name.text, type->named.name.len);
  651. } else {
  652. // NOTE(bill): Just in case
  653. str = gb_string_appendc(str, "<named type>");
  654. }
  655. break;
  656. case Type_Tuple:
  657. if (type->tuple.variable_count > 0) {
  658. for (isize i = 0; i < type->tuple.variable_count; i++) {
  659. Entity *var = type->tuple.variables[i];
  660. if (var != NULL) {
  661. GB_ASSERT(var->kind == Entity_Variable);
  662. if (i > 0)
  663. str = gb_string_appendc(str, ", ");
  664. str = write_type_to_string(str, var->type);
  665. }
  666. }
  667. }
  668. break;
  669. case Type_Proc:
  670. str = gb_string_appendc(str, "proc(");
  671. if (type->proc.params)
  672. str = write_type_to_string(str, type->proc.params);
  673. str = gb_string_appendc(str, ")");
  674. if (type->proc.results) {
  675. str = gb_string_appendc(str, " -> ");
  676. str = write_type_to_string(str, type->proc.results);
  677. }
  678. break;
  679. }
  680. return str;
  681. }
  682. gbString type_to_string(Type *type, gbAllocator a = gb_heap_allocator()) {
  683. gbString str = gb_string_make(a, "");
  684. return write_type_to_string(str, type);
  685. }