type.c (22941B)
1 /* C type construction. 2 * 3 * Types are interned per-Pool: a single `type_void(pool)` returns the same 4 * Type* on every call against the same pool, and structurally-equal calls 5 * to type_prim/type_ptr/type_func collapse to the same Type*. The cache is 6 * a small open structure stored through Pool.type_cache (opaque to other 7 * consumers). 8 * 9 * Storage: every Type and every supporting array (TY_FUNC param vectors, 10 * TY_STRUCT field arrays) is allocated from the Pool's arena, so pointers 11 * are stable for the Pool's lifetime. 12 * 13 * v1 covers what the cg test harness drives: 14 * void / scalars / pointer / function / struct / union 15 * Other constructors (array, qualified, enum) and predicates have minimal 16 * implementations sufficient for the cg test surface; they will grow with 17 * the parser. */ 18 19 #include "type/type.h" 20 21 #include <stdint.h> 22 #include <string.h> 23 24 #define NUM_PRIM_KINDS ((unsigned)TY_LDOUBLE + 1u) 25 26 typedef struct TypeListNode TypeListNode; 27 struct TypeListNode { 28 TypeListNode* next; 29 Type ty; 30 }; 31 32 typedef struct CgRecordMemo CgRecordMemo; 33 struct CgRecordMemo { 34 CgRecordMemo* next; 35 const KitCompiler* compiler; 36 const Type* type; 37 KitCgTypeId id; 38 }; 39 40 typedef struct PoolTypeCache { 41 /* Direct slots for void + primitive kinds (TY_VOID..TY_LDOUBLE). */ 42 const Type* prim[NUM_PRIM_KINDS]; 43 /* Linked list of every other type allocated through this pool. */ 44 TypeListNode* derived; 45 /* Completed record layout ids are compiler-local. */ 46 CgRecordMemo* cg_record_memos; 47 /* Tag id allocator (1-based; TAG_NONE = 0). */ 48 u32 next_tag; 49 } PoolTypeCache; 50 51 static PoolTypeCache* cache_get(Pool* p) { 52 PoolTypeCache* c = (PoolTypeCache*)p->type_cache; 53 if (c) return c; 54 c = arena_new(p->arena, PoolTypeCache); 55 if (!c) return NULL; 56 memset(c, 0, sizeof *c); 57 c->next_tag = 1; 58 p->type_cache = c; 59 return c; 60 } 61 62 static Type* alloc_type_node(Pool* p, PoolTypeCache* c) { 63 TypeListNode* n = arena_new(p->arena, TypeListNode); 64 if (!n) return NULL; 65 memset(n, 0, sizeof *n); 66 n->next = c->derived; 67 c->derived = n; 68 return &n->ty; 69 } 70 71 const Type* type_void(Pool* p) { return type_prim(p, TY_VOID); } 72 73 const Type* type_prim(Pool* p, TypeKind kind) { 74 PoolTypeCache* c = cache_get(p); 75 if (!c) return NULL; 76 if ((unsigned)kind >= NUM_PRIM_KINDS) return NULL; 77 if (c->prim[kind]) return c->prim[kind]; 78 Type* t = alloc_type_node(p, c); 79 if (!t) return NULL; 80 t->kind = (u16)kind; 81 t->qual = 0; 82 c->prim[kind] = t; 83 return t; 84 } 85 86 const Type* type_ptr(Pool* p, const Type* pointee) { 87 PoolTypeCache* c = cache_get(p); 88 if (!c) return NULL; 89 /* Linear search; small N in practice. */ 90 for (TypeListNode* n = c->derived; n; n = n->next) { 91 if (n->ty.kind == TY_PTR && n->ty.qual == 0 && 92 n->ty.ptr.pointee == pointee) { 93 return &n->ty; 94 } 95 } 96 Type* t = alloc_type_node(p, c); 97 if (!t) return NULL; 98 t->kind = TY_PTR; 99 t->qual = 0; 100 t->ptr.pointee = pointee; 101 return t; 102 } 103 104 const Type* type_array(Pool* p, const Type* elem, u32 count, int incomplete) { 105 PoolTypeCache* c = cache_get(p); 106 if (!c) return NULL; 107 for (TypeListNode* n = c->derived; n; n = n->next) { 108 if (n->ty.kind == TY_ARRAY && n->ty.qual == 0 && n->ty.arr.elem == elem && 109 n->ty.arr.count == count && 110 n->ty.arr.incomplete == (u8)(incomplete ? 1 : 0)) { 111 return &n->ty; 112 } 113 } 114 Type* t = alloc_type_node(p, c); 115 if (!t) return NULL; 116 t->kind = TY_ARRAY; 117 t->qual = 0; 118 t->arr.elem = elem; 119 t->arr.count = count; 120 t->arr.incomplete = (u8)(incomplete ? 1 : 0); 121 return t; 122 } 123 124 static int param_arrays_eq(const Type* const* a, const Type* const* b, u16 n) { 125 for (u16 i = 0; i < n; ++i) 126 if (a[i] != b[i]) return 0; 127 return 1; 128 } 129 130 const Type* type_func(Pool* p, const Type* ret, const Type** params, u16 n, 131 int variadic) { 132 PoolTypeCache* c = cache_get(p); 133 if (!c) return NULL; 134 for (TypeListNode* nd = c->derived; nd; nd = nd->next) { 135 if (nd->ty.kind == TY_FUNC && nd->ty.qual == 0 && nd->ty.fn.ret == ret && 136 nd->ty.fn.nparams == n && 137 nd->ty.fn.variadic == (u8)(variadic ? 1 : 0) && 138 param_arrays_eq(nd->ty.fn.params, params, n)) { 139 return &nd->ty; 140 } 141 } 142 Type* t = alloc_type_node(p, c); 143 if (!t) return NULL; 144 t->kind = TY_FUNC; 145 t->qual = 0; 146 t->fn.ret = ret; 147 t->fn.nparams = n; 148 t->fn.variadic = (u8)(variadic ? 1 : 0); 149 if (n) { 150 const Type** dst = arena_array(p->arena, const Type*, n); 151 if (!dst) return NULL; 152 for (u16 i = 0; i < n; ++i) dst[i] = params[i]; 153 t->fn.params = dst; 154 } else { 155 t->fn.params = NULL; 156 } 157 return t; 158 } 159 160 const Type* type_qualified(Pool* p, const Type* base, u16 qual) { 161 PoolTypeCache* c; 162 Type tmpl; 163 Type* t; 164 if (!base || qual == 0) return base; 165 c = cache_get(p); 166 if (!c) return NULL; 167 /* Build the comparison template once, via assignment (not aggregate 168 * initialization). Struct assignment copies the full object representation, 169 * including padding bytes, so the memcmp below is byte-stable against the 170 * interned nodes (which are likewise produced by `*t = tmpl`). An aggregate 171 * *initializer* (`Type tmpl = *base;`) is lowered as a field-by-field copy 172 * that leaves padding unspecified, which would make this memcmp miss and 173 * intern a duplicate qualified type. See type_unqual for the same idiom. */ 174 tmpl = *base; 175 tmpl.qual = qual; 176 for (TypeListNode* n = c->derived; n; n = n->next) { 177 if (n->ty.kind == base->kind && n->ty.qual == qual && 178 memcmp(&n->ty, &tmpl, sizeof(Type)) == 0) { 179 return &n->ty; 180 } 181 } 182 t = alloc_type_node(p, c); 183 if (!t) return NULL; 184 *t = tmpl; 185 return t; 186 } 187 188 /* ---- aggregates ---- */ 189 190 struct TypeRecordBuilder { 191 Pool* pool; 192 TypeKind kind; /* TY_STRUCT or TY_UNION */ 193 TagId tag_id; 194 Sym tag; 195 Field* fields; 196 u32 nfields; 197 u32 cap; 198 TypeRecordOpts opts; 199 }; 200 201 TagId type_tag_new(Pool* p, TagDeclKind kind, Sym spelling, SrcLoc loc) { 202 PoolTypeCache* c = cache_get(p); 203 if (!c) return TAG_NONE; 204 (void)kind; 205 (void)spelling; 206 (void)loc; 207 return (TagId)(c->next_tag++); 208 } 209 210 const TagDecl* type_tag_get(Pool* p, TagId id) { 211 (void)p; 212 (void)id; 213 /* TagDecl table is parser-territory; not modeled in v1. */ 214 return NULL; 215 } 216 217 TypeRecordBuilder* type_record_begin(Pool* p, TypeKind kind, TagId tag_id, 218 Sym tag) { 219 TypeRecordOpts opts; 220 memset(&opts, 0, sizeof opts); 221 return type_record_begin_ex(p, kind, tag_id, tag, opts); 222 } 223 224 TypeRecordBuilder* type_record_begin_ex(Pool* p, TypeKind kind, TagId tag_id, 225 Sym tag, TypeRecordOpts opts) { 226 TypeRecordBuilder* b = arena_new(p->arena, TypeRecordBuilder); 227 if (!b) return NULL; 228 memset(b, 0, sizeof *b); 229 b->pool = p; 230 b->kind = kind; 231 b->tag_id = tag_id; 232 b->tag = tag; 233 b->opts = opts; 234 return b; 235 } 236 237 void type_record_field(TypeRecordBuilder* b, Field f) { 238 if (b->nfields == b->cap) { 239 u32 nc = b->cap ? b->cap * 2 : 4; 240 Field* nf = arena_array(b->pool->arena, Field, nc); 241 if (!nf) return; 242 if (b->fields) memcpy(nf, b->fields, sizeof(Field) * b->nfields); 243 b->fields = nf; 244 b->cap = nc; 245 } 246 b->fields[b->nfields++] = f; 247 } 248 249 const Type* type_record_end(Pool* p, TypeRecordBuilder* b) { 250 PoolTypeCache* c = cache_get(p); 251 if (!c) return NULL; 252 Type* t = alloc_type_node(p, c); 253 if (!t) return NULL; 254 t->kind = (u16)b->kind; 255 t->qual = 0; 256 t->rec.tag_id = b->tag_id; 257 t->rec.tag = b->tag; 258 t->rec.fields = b->fields; 259 t->rec.nfields = (u16)b->nfields; 260 t->rec.incomplete = 0; 261 t->rec.packed = b->opts.packed; 262 t->rec.max_align = b->opts.max_align; 263 t->rec.align_override = b->opts.align_override; 264 return t; 265 } 266 267 Type* type_record_forward(Pool* p, TypeKind kind, TagId tag_id, Sym tag) { 268 PoolTypeCache* c = cache_get(p); 269 if (!c) return NULL; 270 Type* t = alloc_type_node(p, c); 271 if (!t) return NULL; 272 t->kind = (u16)kind; 273 t->qual = 0; 274 t->rec.tag_id = tag_id; 275 t->rec.tag = tag; 276 t->rec.fields = NULL; 277 t->rec.nfields = 0; 278 t->rec.incomplete = 1; 279 t->rec.packed = 0; 280 t->rec.max_align = 0; 281 t->rec.align_override = 0; 282 return t; 283 } 284 285 void type_record_install(Type* forward, const Field* fields, u16 nfields) { 286 if (!forward) return; 287 forward->rec.fields = fields; 288 forward->rec.nfields = nfields; 289 forward->rec.incomplete = 0; 290 } 291 292 const Type* type_enum(Pool* p, TagId tag_id, Sym tag, const Type* base) { 293 PoolTypeCache* c = cache_get(p); 294 if (!c) return NULL; 295 Type* t = alloc_type_node(p, c); 296 if (!t) return NULL; 297 t->kind = TY_ENUM; 298 t->qual = 0; 299 t->enm.tag_id = tag_id; 300 t->enm.tag = tag; 301 t->enm.base = base; 302 return t; 303 } 304 305 /* ---- predicates / utilities ---- */ 306 307 const Type* type_unqual(Pool* p, const Type* t) { 308 PoolTypeCache* c; 309 Type tmpl; 310 Type* nt; 311 if (!t || t->qual == 0) return t; 312 if ((unsigned)t->kind < NUM_PRIM_KINDS) 313 return type_prim(p, (TypeKind)t->kind); 314 c = cache_get(p); 315 if (!c) return NULL; 316 if ((t->kind == TY_STRUCT || t->kind == TY_UNION) && 317 t->rec.tag_id != TAG_NONE) { 318 for (TypeListNode* n = c->derived; n; n = n->next) { 319 if (n->ty.kind == t->kind && n->ty.qual == 0 && 320 n->ty.rec.tag_id == t->rec.tag_id && !n->ty.rec.incomplete) { 321 return &n->ty; 322 } 323 } 324 } 325 tmpl = *t; 326 tmpl.qual = 0; 327 for (TypeListNode* n = c->derived; n; n = n->next) { 328 if (memcmp(&n->ty, &tmpl, sizeof(Type)) == 0) return &n->ty; 329 } 330 nt = alloc_type_node(p, c); 331 if (!nt) return NULL; 332 *nt = tmpl; 333 return nt; 334 } 335 336 const Type* type_promoted(Pool* p, const Type* t) { 337 if (!t) return t; 338 switch (t->kind) { 339 case TY_BOOL: 340 case TY_CHAR: 341 case TY_SCHAR: 342 case TY_UCHAR: 343 case TY_SHORT: 344 case TY_USHORT: 345 return type_prim(p, TY_INT); 346 default: 347 return t; 348 } 349 } 350 351 static int type_compatible_inner(const Type* a, const Type* b, unsigned depth) { 352 u16 i; 353 if (depth > 64) return 0; 354 if (a == b) return 1; 355 if (!a || !b) return 0; 356 if (a->qual != b->qual) return 0; 357 if (a->kind != b->kind) return 0; 358 switch (a->kind) { 359 case TY_VOID: 360 case TY_BOOL: 361 case TY_CHAR: 362 case TY_SCHAR: 363 case TY_UCHAR: 364 case TY_SHORT: 365 case TY_USHORT: 366 case TY_INT: 367 case TY_UINT: 368 case TY_LONG: 369 case TY_ULONG: 370 case TY_LLONG: 371 case TY_ULLONG: 372 case TY_INT128: 373 case TY_UINT128: 374 case TY_FLOAT: 375 case TY_DOUBLE: 376 case TY_LDOUBLE: 377 return 1; 378 case TY_PTR: 379 return type_compatible_inner(a->ptr.pointee, b->ptr.pointee, depth + 1); 380 case TY_ARRAY: 381 if (!type_compatible_inner(a->arr.elem, b->arr.elem, depth + 1)) return 0; 382 if (a->arr.incomplete || b->arr.incomplete) return 1; 383 return a->arr.count == b->arr.count; 384 case TY_FUNC: 385 if (a->fn.variadic != b->fn.variadic) return 0; 386 if (a->fn.nparams != b->fn.nparams) return 0; 387 if (!type_compatible_inner(a->fn.ret, b->fn.ret, depth + 1)) return 0; 388 for (i = 0; i < a->fn.nparams; ++i) { 389 if (!type_compatible_inner(a->fn.params[i], b->fn.params[i], depth + 1)) 390 return 0; 391 } 392 return 1; 393 case TY_STRUCT: 394 case TY_UNION: 395 return a->rec.tag_id != TAG_NONE && a->rec.tag_id == b->rec.tag_id; 396 case TY_ENUM: 397 if (a->enm.tag_id != TAG_NONE || b->enm.tag_id != TAG_NONE) 398 return a->enm.tag_id == b->enm.tag_id; 399 return type_compatible_inner(a->enm.base, b->enm.base, depth + 1); 400 default: 401 return 0; 402 } 403 } 404 405 int type_compatible(const Type* a, const Type* b) { 406 return type_compatible_inner(a, b, 0); 407 } 408 409 const Type* type_composite(Pool* p, const Type* a, const Type* b) { 410 const Type* elem; 411 const Type** params; 412 u16 i; 413 if (!type_compatible(a, b)) return NULL; 414 if (a == b) return a; 415 if (!a || !b) return NULL; 416 switch (a->kind) { 417 case TY_ARRAY: 418 elem = type_composite(p, a->arr.elem, b->arr.elem); 419 if (!elem) elem = a->arr.elem; 420 if (a->arr.incomplete && !b->arr.incomplete) 421 return type_array(p, elem, b->arr.count, 0); 422 if (b->arr.incomplete && !a->arr.incomplete) 423 return type_array(p, elem, a->arr.count, 0); 424 return type_array(p, elem, a->arr.count, a->arr.incomplete); 425 case TY_PTR: { 426 const Type* pointee = type_composite(p, a->ptr.pointee, b->ptr.pointee); 427 if (!pointee) pointee = a->ptr.pointee; 428 /* Preserve the pointer's own qualifiers (e.g. the inner `const` of 429 * `const char* const*`); type_ptr alone yields an unqualified pointer. */ 430 return type_qualified(p, type_ptr(p, pointee), a->qual); 431 } 432 case TY_FUNC: 433 if (a->fn.nparams == 0) return a; 434 params = arena_array(p->arena, const Type*, a->fn.nparams); 435 if (!params) return NULL; 436 for (i = 0; i < a->fn.nparams; ++i) { 437 params[i] = type_composite(p, a->fn.params[i], b->fn.params[i]); 438 if (!params[i]) params[i] = a->fn.params[i]; 439 } 440 return type_func(p, type_composite(p, a->fn.ret, b->fn.ret), params, 441 a->fn.nparams, a->fn.variadic); 442 default: 443 return a; 444 } 445 } 446 447 /* Single source of truth for per-TypeKind scalar facts. Indexed directly by 448 * TypeKind (sized to TY_ENUM + 1); the aggregate kinds PTR/ARRAY/FUNC/STRUCT/ 449 * UNION are zero-filled holes. Columns: 450 * is_signed - signed integer (drives sign-extension / signed cg ops) 451 * is_int - integer type (bool/char/.../enum) 452 * is_fp - floating-point type 453 * rank - C integer conversion rank (0 for non-integers) 454 * uvariant - corresponding unsigned TypeKind (TY_UINT for non-integers, 455 * matching the historical default) 456 * Accessors below read this table instead of re-enumerating the kinds. */ 457 typedef struct TypeKindProps { 458 u8 is_signed; 459 u8 is_int; 460 u8 is_fp; 461 u8 rank; 462 u8 uvariant; /* TypeKind */ 463 } TypeKindProps; 464 465 static const TypeKindProps kTypeKindProps[TY_ENUM + 1] = { 466 [TY_VOID] = {0, 0, 0, 0, TY_UINT}, 467 [TY_BOOL] = {0, 1, 0, 1, TY_UINT}, 468 [TY_CHAR] = {1, 1, 0, 2, TY_UINT}, 469 [TY_SCHAR] = {1, 1, 0, 2, TY_UINT}, 470 [TY_UCHAR] = {0, 1, 0, 2, TY_UINT}, 471 [TY_SHORT] = {1, 1, 0, 3, TY_UINT}, 472 [TY_USHORT] = {0, 1, 0, 3, TY_UINT}, 473 [TY_INT] = {1, 1, 0, 4, TY_UINT}, 474 [TY_UINT] = {0, 1, 0, 4, TY_UINT}, 475 [TY_LONG] = {1, 1, 0, 5, TY_ULONG}, 476 [TY_ULONG] = {0, 1, 0, 5, TY_ULONG}, 477 [TY_LLONG] = {1, 1, 0, 6, TY_ULLONG}, 478 [TY_ULLONG] = {0, 1, 0, 6, TY_ULLONG}, 479 [TY_INT128] = {1, 1, 0, 7, TY_UINT128}, 480 [TY_UINT128] = {0, 1, 0, 7, TY_UINT128}, 481 [TY_FLOAT] = {0, 0, 1, 0, TY_UINT}, 482 [TY_DOUBLE] = {0, 0, 1, 0, TY_UINT}, 483 [TY_LDOUBLE] = {0, 0, 1, 0, TY_UINT}, 484 /* PTR/ARRAY/FUNC/STRUCT/UNION: zero-filled holes (uvariant 0 == TY_VOID 485 * is never read for non-integers; callers map non-int to TY_UINT). */ 486 [TY_ENUM] = {1, 1, 0, 4, TY_UINT}, 487 }; 488 489 static const TypeKindProps* type_kind_props(TypeKind k) { 490 if ((unsigned)k > (unsigned)TY_ENUM) return &kTypeKindProps[TY_VOID]; 491 return &kTypeKindProps[k]; 492 } 493 494 int type_kind_is_int(TypeKind k) { return type_kind_props(k)->is_int; } 495 int type_kind_is_fp(TypeKind k) { return type_kind_props(k)->is_fp; } 496 int type_kind_is_signed_integer(TypeKind k) { 497 return type_kind_props(k)->is_signed; 498 } 499 u32 type_kind_int_rank(TypeKind k) { return type_kind_props(k)->rank; } 500 TypeKind type_kind_unsigned_variant(TypeKind k) { 501 const TypeKindProps* p = type_kind_props(k); 502 return p->is_int ? (TypeKind)p->uvariant : TY_UINT; 503 } 504 505 int type_is_int(const Type* t) { 506 return t ? type_kind_is_int((TypeKind)t->kind) : 0; 507 } 508 509 int type_is_arith(const Type* t) { 510 if (!t) return 0; 511 return type_kind_is_int((TypeKind)t->kind) || 512 type_kind_is_fp((TypeKind)t->kind); 513 } 514 515 int type_is_ptr(const Type* t) { return t && t->kind == TY_PTR; } 516 517 int type_is_signed_integer(const Type* t) { 518 return t ? type_kind_is_signed_integer((TypeKind)t->kind) : 0; 519 } 520 521 static KitCgTypeId type_cg_builtin(KitCompiler* c, TypeKind kind) { 522 KitCgBuiltinTypes b = kit_cg_builtin_types(c); 523 KitTargetSpec target = kit_compiler_target_spec(c); 524 switch (kind) { 525 case TY_VOID: 526 return b.id[KIT_CG_BUILTIN_VOID]; 527 case TY_BOOL: 528 return b.id[KIT_CG_BUILTIN_BOOL]; 529 case TY_CHAR: 530 case TY_SCHAR: 531 case TY_UCHAR: 532 return b.id[KIT_CG_BUILTIN_I8]; 533 case TY_SHORT: 534 case TY_USHORT: 535 return b.id[KIT_CG_BUILTIN_I16]; 536 case TY_INT: 537 case TY_UINT: 538 return b.id[KIT_CG_BUILTIN_I32]; 539 case TY_LONG: 540 case TY_ULONG: 541 return b.id[kit_target_uses_lp64(target) ? KIT_CG_BUILTIN_I64 542 : KIT_CG_BUILTIN_I32]; 543 case TY_LLONG: 544 case TY_ULLONG: 545 return b.id[KIT_CG_BUILTIN_I64]; 546 case TY_INT128: 547 case TY_UINT128: 548 return b.id[KIT_CG_BUILTIN_I128]; 549 case TY_FLOAT: 550 return b.id[KIT_CG_BUILTIN_F32]; 551 case TY_DOUBLE: 552 return b.id[KIT_CG_BUILTIN_F64]; 553 case TY_LDOUBLE: 554 /* `long double` is IEEE-754 binary128 on targets that follow the quad 555 * psABI (RISC-V, aarch64-linux, wasm32); elsewhere it aliases `double`. 556 * See kit_target_long_double_is_binary128. */ 557 if (kit_target_long_double_is_binary128(target)) 558 return b.id[KIT_CG_BUILTIN_F128]; 559 return b.id[KIT_CG_BUILTIN_F64]; 560 default: 561 break; 562 } 563 return KIT_CG_TYPE_NONE; 564 } 565 566 static int same_record_type(const Type* a, const Type* b) { 567 if (a == b) return 1; 568 if (!a || !b) return 0; 569 if (a->kind != b->kind) return 0; 570 if (a->kind != TY_STRUCT && a->kind != TY_UNION) return 0; 571 return a->rec.tag_id != TAG_NONE && a->rec.tag_id == b->rec.tag_id; 572 } 573 574 typedef enum TypeCgMode { 575 TYPE_CG_VALUE, 576 TYPE_CG_RECORD_FIELD, 577 } TypeCgMode; 578 579 typedef struct TypeCgLower { 580 KitCompiler* c; 581 Pool* p; 582 PoolTypeCache* cache; 583 } TypeCgLower; 584 585 static KitCgTypeId type_cg_lower(TypeCgLower* l, const Type* t, 586 TypeCgMode mode); 587 588 static KitCgTypeId type_cg_record_memo_get(PoolTypeCache* cache, KitCompiler* c, 589 const Type* t) { 590 if (!cache) return KIT_CG_TYPE_NONE; 591 for (CgRecordMemo* m = cache->cg_record_memos; m; m = m->next) { 592 if (m->compiler == c && (m->type == t || same_record_type(m->type, t))) { 593 return m->id; 594 } 595 } 596 return KIT_CG_TYPE_NONE; 597 } 598 599 static void type_cg_record_memo_put(Pool* p, PoolTypeCache* cache, 600 KitCompiler* c, const Type* t, 601 KitCgTypeId id) { 602 CgRecordMemo* m; 603 if (!p || !cache || !c || !t || id == KIT_CG_TYPE_NONE) return; 604 if (t->kind != TY_STRUCT && t->kind != TY_UNION) return; 605 if (t->rec.incomplete) return; 606 for (m = cache->cg_record_memos; m; m = m->next) { 607 if (m->compiler == c && (m->type == t || same_record_type(m->type, t))) { 608 m->id = id; 609 return; 610 } 611 } 612 m = arena_new(p->arena, CgRecordMemo); 613 if (!m) return; 614 m->compiler = c; 615 m->type = t; 616 m->id = id; 617 m->next = cache->cg_record_memos; 618 cache->cg_record_memos = m; 619 } 620 621 static KitCgTypeId type_cg_record_layout(TypeCgLower* l, const Type* t) { 622 KitCgField* fields = NULL; 623 KitCgRecordDesc desc; 624 KitCgTypeId id; 625 if (!l || !t || (t->kind != TY_STRUCT && t->kind != TY_UNION)) { 626 return KIT_CG_TYPE_NONE; 627 } 628 if (t->rec.incomplete) return type_cg_builtin(l->c, TY_VOID); 629 id = type_cg_record_memo_get(l->cache, l->c, t); 630 if (id != KIT_CG_TYPE_NONE) return id; 631 if (t->rec.nfields) { 632 fields = arena_zarray(l->p->arena, KitCgField, t->rec.nfields); 633 if (!fields) return KIT_CG_TYPE_NONE; 634 for (u32 i = 0; i < t->rec.nfields; ++i) { 635 fields[i].name = t->rec.fields[i].name; 636 fields[i].type = 637 type_cg_lower(l, t->rec.fields[i].type, TYPE_CG_RECORD_FIELD); 638 fields[i].align_override = t->rec.fields[i].align_override; 639 fields[i].max_align = t->rec.fields[i].max_align; 640 if (t->rec.max_align && 641 (fields[i].max_align == 0 || t->rec.max_align < fields[i].max_align)) 642 fields[i].max_align = t->rec.max_align; 643 if (t->rec.fields[i].flags & FIELD_BITFIELD) { 644 fields[i].flags |= KIT_CG_FIELD_BITFIELD; 645 fields[i].bit_width = t->rec.fields[i].bitfield_width; 646 fields[i].bit_signed = 647 type_is_signed_integer(t->rec.fields[i].type); 648 if (t->rec.fields[i].flags & FIELD_ZERO_WIDTH) { 649 fields[i].flags |= KIT_CG_FIELD_ZERO_WIDTH; 650 } 651 } 652 if (t->rec.fields[i].packed && fields[i].align_override == 0) { 653 fields[i].align_override = 1; 654 } 655 if (t->rec.packed && fields[i].align_override == 0) { 656 fields[i].align_override = 1; 657 } 658 } 659 } 660 memset(&desc, 0, sizeof desc); 661 desc.tag = t->rec.tag; 662 desc.fields = fields; 663 desc.nfields = t->rec.nfields; 664 desc.is_union = t->kind == TY_UNION; 665 desc.align_override = t->rec.align_override; 666 id = kit_cg_type_record_ex(l->c, &desc); 667 type_cg_record_memo_put(l->p, l->cache, l->c, t, id); 668 return id; 669 } 670 671 static KitCgTypeId type_cg_lower(TypeCgLower* l, const Type* t, 672 TypeCgMode mode) { 673 KitCgTypeId id; 674 if (!l || !t) return KIT_CG_TYPE_NONE; 675 id = type_cg_builtin(l->c, (TypeKind)t->kind); 676 if (id != KIT_CG_TYPE_NONE) return id; 677 switch ((TypeKind)t->kind) { 678 case TY_PTR: 679 if (mode == TYPE_CG_RECORD_FIELD) { 680 return kit_cg_type_ptr(l->c, type_cg_builtin(l->c, TY_VOID), 0); 681 } 682 return kit_cg_type_ptr( 683 l->c, type_cg_lower(l, t->ptr.pointee, TYPE_CG_VALUE), 0); 684 case TY_ARRAY: 685 return kit_cg_type_array(l->c, type_cg_lower(l, t->arr.elem, mode), 686 t->arr.count); 687 case TY_FUNC: { 688 KitCgFuncParam* params = NULL; 689 KitCgFuncSig sig; 690 memset(&sig, 0, sizeof sig); 691 if (t->fn.ret->kind != TY_VOID) 692 sig.result.type = type_cg_lower(l, t->fn.ret, TYPE_CG_VALUE); 693 sig.nparams = t->fn.nparams; 694 sig.abi_variadic = t->fn.variadic; 695 sig.call_conv = KIT_CG_CC_TARGET_C; 696 if (t->fn.nparams) { 697 params = arena_zarray(l->p->arena, KitCgFuncParam, t->fn.nparams); 698 if (!params) return KIT_CG_TYPE_NONE; 699 for (u32 i = 0; i < t->fn.nparams; ++i) { 700 params[i].type = 701 type_cg_lower(l, t->fn.params[i], TYPE_CG_RECORD_FIELD); 702 } 703 } 704 sig.params = params; 705 return kit_cg_type_func(l->c, sig); 706 } 707 case TY_STRUCT: 708 case TY_UNION: 709 return type_cg_record_layout(l, t); 710 case TY_ENUM: 711 return kit_cg_type_enum(l->c, t->enm.tag, 712 type_cg_lower(l, t->enm.base, mode), NULL, 0); 713 default: 714 return KIT_CG_TYPE_NONE; 715 } 716 } 717 718 KitCgTypeId type_cg_id_in_pool(KitCompiler* c, Pool* p, const Type* t) { 719 TypeCgLower l; 720 if (!p) return KIT_CG_TYPE_NONE; 721 memset(&l, 0, sizeof l); 722 l.c = c; 723 l.p = p; 724 l.cache = cache_get(p); 725 return type_cg_lower(&l, t, TYPE_CG_VALUE); 726 } 727 728 KitCgTypeId type_cg_id(KitCompiler* c, const Type* t) { 729 KitCgTypeId id; 730 Pool* p = c_pool_new(c); 731 if (!p) return KIT_CG_TYPE_NONE; 732 id = type_cg_id_in_pool(c, p, t); 733 c_pool_free(p); 734 return id; 735 }