kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

type.c (31101B)


      1 #include "arch/arch.h"
      2 #include "cg/internal.h"
      3 #include "obj/obj.h"
      4 
      5 typedef enum CgApiTypeKind {
      6   CG_API_TYPE_PTR,
      7   CG_API_TYPE_ARRAY,
      8   CG_API_TYPE_ALIAS,
      9   CG_API_TYPE_RECORD,
     10   CG_API_TYPE_ENUM,
     11   CG_API_TYPE_FUNC,
     12 } CgApiTypeKind;
     13 
     14 typedef struct CgApiType {
     15   CgType cg;
     16   KitCgTypeId base;
     17   KitSym name;
     18   u32 count;
     19   u32 flags;
     20   u32 address_space;
     21   u64 array_count;
     22   const KitCgField* fields;
     23   const KitCgEnumValue* values;
     24   const KitCgFuncParam* params;
     25   KitCgFuncResult result; /* result.type == KIT_CG_TYPE_NONE == void */
     26   KitCgCallConv call_conv;
     27   u8 kind;
     28   u8 abi_variadic;
     29   u8 pad[2];
     30 } CgApiType;
     31 
     32 SEGVEC_DEFINE(CgApiTypes, CgApiType, CG_API_TYPE_SEG_SHIFT);
     33 
     34 typedef struct CgApiState {
     35   Heap* heap;
     36   CgApiTypes types;
     37   CgType builtins[KIT_CG_BUILTIN_COUNT];
     38   u8 builtins_init;
     39   u8 pad[3];
     40 } CgApiState;
     41 
     42 static KitCgTypeId type_id_from_tuple(u32 seg, u32 index) {
     43   return (KitCgTypeId)((seg << CG_API_TYPE_SEG_SHIFT) |
     44                        (index & CG_API_TYPE_SEG_MASK));
     45 }
     46 
     47 KitCgTypeId builtin_id(KitCgBuiltinType t) {
     48   return type_id_from_tuple(CG_API_TYPE_BUILTIN_SEG, (u32)t);
     49 }
     50 
     51 static int decode_user_id(KitCgTypeId id, u32* index_out) {
     52   u32 seg = id >> CG_API_TYPE_SEG_SHIFT;
     53   u32 off = id & CG_API_TYPE_SEG_MASK;
     54   if (seg < CG_API_TYPE_USER_SEG_BIAS) return 0;
     55   *index_out =
     56       ((seg - CG_API_TYPE_USER_SEG_BIAS) << CG_API_TYPE_SEG_SHIFT) | off;
     57   return 1;
     58 }
     59 
     60 static KitCgTypeId user_id_from_index(u32 index) {
     61   u32 raw_seg = index >> CG_API_TYPE_SEG_SHIFT;
     62   u32 off = index & CG_API_TYPE_SEG_MASK;
     63   u32 seg_limit = UINT32_MAX >> CG_API_TYPE_SEG_SHIFT;
     64   if (raw_seg > seg_limit - CG_API_TYPE_USER_SEG_BIAS) {
     65     return KIT_CG_TYPE_NONE;
     66   }
     67   return type_id_from_tuple(raw_seg + CG_API_TYPE_USER_SEG_BIAS, off);
     68 }
     69 
     70 static KitCgTypeId type_id_for_user_index(u32 index) {
     71   return user_id_from_index(index);
     72 }
     73 
     74 static u64 cg_align_to(u64 n, u32 align) {
     75   u64 a = align ? (u64)align : 1u;
     76   return ((n + a - 1u) / a) * a;
     77 }
     78 
     79 static void builtin_cg_type_init(Compiler* c, CgType* out, KitCgBuiltinType t) {
     80   memset(out, 0, sizeof(*out));
     81   switch (t) {
     82     case KIT_CG_BUILTIN_VOID:
     83       out->kind = KIT_CG_TYPE_VOID;
     84       out->align = 1;
     85       break;
     86     case KIT_CG_BUILTIN_BOOL:
     87       out->kind = KIT_CG_TYPE_BOOL;
     88       out->size = 1;
     89       out->align = 1;
     90       out->integer.width = 8;
     91       break;
     92     case KIT_CG_BUILTIN_I8:
     93       out->kind = KIT_CG_TYPE_INT;
     94       out->size = 1;
     95       out->align = 1;
     96       out->integer.width = 8;
     97       break;
     98     case KIT_CG_BUILTIN_I16:
     99       out->kind = KIT_CG_TYPE_INT;
    100       out->size = 2;
    101       out->align = 2;
    102       out->integer.width = 16;
    103       break;
    104     case KIT_CG_BUILTIN_I32:
    105       out->kind = KIT_CG_TYPE_INT;
    106       out->size = 4;
    107       out->align = 4;
    108       out->integer.width = 32;
    109       break;
    110     case KIT_CG_BUILTIN_I64:
    111       out->kind = KIT_CG_TYPE_INT;
    112       out->size = 8;
    113       out->align = 8;
    114       out->integer.width = 64;
    115       break;
    116     case KIT_CG_BUILTIN_I128:
    117       out->kind = KIT_CG_TYPE_INT;
    118       out->size = 16;
    119       out->align = 16;
    120       out->integer.width = 128;
    121       break;
    122     case KIT_CG_BUILTIN_F32:
    123       out->kind = KIT_CG_TYPE_FLOAT;
    124       out->size = 4;
    125       out->align = 4;
    126       out->fp.width = 32;
    127       break;
    128     case KIT_CG_BUILTIN_F64:
    129       out->kind = KIT_CG_TYPE_FLOAT;
    130       out->size = 8;
    131       out->align = 8;
    132       out->fp.width = 64;
    133       break;
    134     case KIT_CG_BUILTIN_F128:
    135       out->kind = KIT_CG_TYPE_FLOAT;
    136       out->size = 16;
    137       out->align = 16;
    138       out->fp.width = 128;
    139       break;
    140     case KIT_CG_BUILTIN_VARARG_STATE: {
    141       ABITypeInfo info = abi_va_list_info(c->abi);
    142       out->kind = KIT_CG_TYPE_VARARG_STATE;
    143       out->size = info.size;
    144       out->align = info.align ? info.align : 1;
    145       break;
    146     }
    147     case KIT_CG_BUILTIN_COUNT:
    148       break;
    149   }
    150 }
    151 
    152 static void cg_api_init_builtins(Compiler* c, CgApiState* s) {
    153   if (s->builtins_init) return;
    154   for (u32 i = 0; i < KIT_CG_BUILTIN_COUNT; ++i) {
    155     builtin_cg_type_init(c, &s->builtins[i], (KitCgBuiltinType)i);
    156   }
    157   s->builtins_init = 1;
    158 }
    159 
    160 static CgApiState* cg_api_get(Compiler* c) {
    161   Heap* h;
    162   CgApiState* s;
    163   if (!c) return NULL;
    164   if (c->cg_api) return (CgApiState*)c->cg_api;
    165   h = (Heap*)c->ctx->heap;
    166   s = (CgApiState*)h->alloc(h, sizeof(*s), _Alignof(CgApiState));
    167   if (!s) return NULL;
    168   memset(s, 0, sizeof(*s));
    169   s->heap = h;
    170   CgApiTypes_init(&s->types, h);
    171   c->cg_api = s;
    172   c->cg_api_free = cg_api_fini;
    173   cg_api_init_builtins(c, s);
    174   return s;
    175 }
    176 
    177 static CgApiType* api_type_from_id(Compiler* c, KitCgTypeId id);
    178 
    179 const CgType* cg_type_get(Compiler* c, KitCgTypeId id) {
    180   u32 seg;
    181   u32 off;
    182   CgApiState* s;
    183   CgApiType* e;
    184   if (!c || id == KIT_CG_TYPE_NONE) return NULL;
    185   seg = id >> CG_API_TYPE_SEG_SHIFT;
    186   off = id & CG_API_TYPE_SEG_MASK;
    187   if (seg == CG_API_TYPE_BUILTIN_SEG) {
    188     if (off >= KIT_CG_BUILTIN_COUNT) return NULL;
    189     s = cg_api_get(c);
    190     if (!s) return NULL;
    191     cg_api_init_builtins(c, s);
    192     return &s->builtins[off];
    193   }
    194   e = api_type_from_id(c, id);
    195   return e ? &e->cg : NULL;
    196 }
    197 
    198 uint64_t cg_type_size(Compiler* c, KitCgTypeId id) {
    199   const CgType* ty = cg_type_get(c, id);
    200   return ty ? ty->size : 0;
    201 }
    202 
    203 uint32_t cg_type_align(Compiler* c, KitCgTypeId id) {
    204   const CgType* ty = cg_type_get(c, id);
    205   return ty ? ty->align : 0;
    206 }
    207 
    208 int cg_type_is_int(Compiler* c, KitCgTypeId id) {
    209   const CgType* ty = cg_type_get(c, id);
    210   if (ty && ty->kind == KIT_CG_TYPE_ALIAS) {
    211     return cg_type_is_int(c, ty->alias.base);
    212   }
    213   return ty && (ty->kind == KIT_CG_TYPE_INT || ty->kind == KIT_CG_TYPE_BOOL ||
    214                 ty->kind == KIT_CG_TYPE_ENUM);
    215 }
    216 
    217 int cg_type_is_float(Compiler* c, KitCgTypeId id) {
    218   const CgType* ty = cg_type_get(c, id);
    219   if (ty && ty->kind == KIT_CG_TYPE_ALIAS) {
    220     return cg_type_is_float(c, ty->alias.base);
    221   }
    222   return ty && ty->kind == KIT_CG_TYPE_FLOAT;
    223 }
    224 
    225 int cg_type_is_ptr(Compiler* c, KitCgTypeId id) {
    226   const CgType* ty = cg_type_get(c, id);
    227   if (ty && ty->kind == KIT_CG_TYPE_ALIAS) {
    228     return cg_type_is_ptr(c, ty->alias.base);
    229   }
    230   return ty && ty->kind == KIT_CG_TYPE_PTR;
    231 }
    232 
    233 int cg_type_is_record(Compiler* c, KitCgTypeId id) {
    234   const CgType* ty = cg_type_get(c, id);
    235   if (ty && ty->kind == KIT_CG_TYPE_ALIAS) {
    236     return cg_type_is_record(c, ty->alias.base);
    237   }
    238   return ty && ty->kind == KIT_CG_TYPE_RECORD;
    239 }
    240 
    241 int cg_type_is_void(Compiler* c, KitCgTypeId id) {
    242   const CgType* ty = cg_type_get(c, id);
    243   if (ty && ty->kind == KIT_CG_TYPE_ALIAS)
    244     return cg_type_is_void(c, ty->alias.base);
    245   return ty && ty->kind == KIT_CG_TYPE_VOID;
    246 }
    247 
    248 int cg_type_is_aggregate(Compiler* c, KitCgTypeId id) {
    249   return cg_type_is_record(c, id);
    250 }
    251 
    252 KitCgTypeId cg_type_ptr_to(Compiler* c, KitCgTypeId pointee) {
    253   return kit_cg_type_ptr(c, pointee, 0);
    254 }
    255 
    256 KitCgTypeId cg_type_pointee(Compiler* c, KitCgTypeId id) {
    257   const CgType* ty = cg_type_get(c, id);
    258   if (ty && ty->kind == KIT_CG_TYPE_ALIAS)
    259     return cg_type_pointee(c, ty->alias.base);
    260   return ty && ty->kind == KIT_CG_TYPE_PTR ? ty->ptr.pointee : KIT_CG_TYPE_NONE;
    261 }
    262 
    263 KitCgTypeId cg_type_func_ret_id(Compiler* c, KitCgTypeId id) {
    264   const CgType* ty = cg_type_get(c, id);
    265   if (ty && ty->kind == KIT_CG_TYPE_ALIAS)
    266     return cg_type_func_ret_id(c, ty->alias.base);
    267   if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return KIT_CG_TYPE_NONE;
    268   return ty->func.result.type ? ty->func.result.type
    269                               : builtin_id(KIT_CG_BUILTIN_VOID);
    270 }
    271 
    272 KitCgTypeId cg_func_ret_type(const CgType* fnty) {
    273   return fnty->func.result.type ? fnty->func.result.type
    274                                 : builtin_id(KIT_CG_BUILTIN_VOID);
    275 }
    276 
    277 KitCgTypeId cg_type_func_result_id(Compiler* c, KitCgTypeId id) {
    278   const CgType* ty = cg_type_get(c, id);
    279   if (ty && ty->kind == KIT_CG_TYPE_ALIAS)
    280     return cg_type_func_result_id(c, ty->alias.base);
    281   if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return KIT_CG_TYPE_NONE;
    282   return ty->func.result.type;
    283 }
    284 
    285 KitCgTypeId cg_type_func_param_id(Compiler* c, KitCgTypeId id, u32 index) {
    286   const CgType* ty = cg_type_get(c, id);
    287   if (ty && ty->kind == KIT_CG_TYPE_ALIAS)
    288     return cg_type_func_param_id(c, ty->alias.base, index);
    289   if (!ty || ty->kind != KIT_CG_TYPE_FUNC || index >= ty->func.nparams)
    290     return KIT_CG_TYPE_NONE;
    291   return ty->func.params[index].type;
    292 }
    293 
    294 static CgApiType* type_alloc(Compiler* c, KitCgTypeId* id_out) {
    295   CgApiState* s = cg_api_get(c);
    296   CgApiType* e;
    297   u32 index;
    298   if (!s) return NULL;
    299   e = CgApiTypes_push(&s->types, &index);
    300   if (!e) return NULL;
    301   *id_out = user_id_from_index(index);
    302   if (*id_out == KIT_CG_TYPE_NONE) return NULL;
    303   return e;
    304 }
    305 
    306 static KitCgTypeId find_ptr_type_id(Compiler* c, KitCgTypeId pointee,
    307                                     u32 address_space) {
    308   CgApiState* s;
    309   u32 n;
    310   if (!c || !c->cg_api) return KIT_CG_TYPE_NONE;
    311   s = (CgApiState*)c->cg_api;
    312   n = CgApiTypes_count(&s->types);
    313   for (u32 i = 0; i < n; ++i) {
    314     CgApiType* e = CgApiTypes_at(&s->types, i);
    315     if (e && e->kind == CG_API_TYPE_PTR && e->base == pointee &&
    316         e->address_space == address_space)
    317       return type_id_for_user_index(i);
    318   }
    319   return KIT_CG_TYPE_NONE;
    320 }
    321 
    322 static KitCgTypeId find_array_type_id(Compiler* c, KitCgTypeId elem,
    323                                       u64 count) {
    324   CgApiState* s;
    325   u32 n;
    326   if (!c || !c->cg_api) return KIT_CG_TYPE_NONE;
    327   s = (CgApiState*)c->cg_api;
    328   n = CgApiTypes_count(&s->types);
    329   for (u32 i = 0; i < n; ++i) {
    330     CgApiType* e = CgApiTypes_at(&s->types, i);
    331     if (e && e->kind == CG_API_TYPE_ARRAY && e->base == elem &&
    332         e->array_count == count)
    333       return type_id_for_user_index(i);
    334   }
    335   return KIT_CG_TYPE_NONE;
    336 }
    337 
    338 static int cg_params_eq(const KitCgFuncParam* a, const KitCgFuncParam* b,
    339                         u32 n) {
    340   for (u32 i = 0; i < n; ++i)
    341     if (a[i].type != b[i].type ||
    342         memcmp(&a[i].attrs, &b[i].attrs, sizeof(a[i].attrs)) != 0) {
    343       return 0;
    344     }
    345   return 1;
    346 }
    347 
    348 static int cg_result_eq(const KitCgFuncResult* a, const KitCgFuncResult* b) {
    349   return a->type == b->type &&
    350          memcmp(&a->attrs, &b->attrs, sizeof(a->attrs)) == 0;
    351 }
    352 
    353 static KitCgTypeId find_func_type_id(Compiler* c, KitCgFuncSig sig) {
    354   CgApiState* s;
    355   u32 n;
    356   if (!c || !c->cg_api) return KIT_CG_TYPE_NONE;
    357   s = (CgApiState*)c->cg_api;
    358   n = CgApiTypes_count(&s->types);
    359   for (u32 i = 0; i < n; ++i) {
    360     CgApiType* e = CgApiTypes_at(&s->types, i);
    361     if (!e || e->kind != CG_API_TYPE_FUNC) continue;
    362     if (e->count != sig.nparams) continue;
    363     if (e->abi_variadic != (sig.abi_variadic != 0)) continue;
    364     if (e->call_conv != sig.call_conv) continue;
    365     if (!cg_result_eq(&e->result, &sig.result)) continue;
    366     if (sig.nparams && !cg_params_eq(e->params, sig.params, sig.nparams)) {
    367       continue;
    368     }
    369     return type_id_for_user_index(i);
    370   }
    371   return KIT_CG_TYPE_NONE;
    372 }
    373 
    374 static CgApiType* api_type_from_id(Compiler* c, KitCgTypeId id) {
    375   u32 index;
    376   CgApiState* s;
    377   CgApiType* e;
    378   if (!c || id == KIT_CG_TYPE_NONE) return NULL;
    379   if ((id >> CG_API_TYPE_SEG_SHIFT) == CG_API_TYPE_BUILTIN_SEG) return NULL;
    380   if (!decode_user_id(id, &index)) return NULL;
    381   s = (CgApiState*)c->cg_api;
    382   if (!s) return NULL;
    383   e = CgApiTypes_at(&s->types, index);
    384   return e;
    385 }
    386 
    387 KitCgTypeId resolve_type(Compiler* c, KitCgTypeId id) {
    388   return cg_type_get(c, id) ? id : KIT_CG_TYPE_NONE;
    389 }
    390 
    391 KitCgTypeId api_unalias_type(Compiler* c, KitCgTypeId id) {
    392   const CgType* ty = cg_type_get(c, id);
    393   while (ty && ty->kind == KIT_CG_TYPE_ALIAS) {
    394     id = ty->alias.base;
    395     ty = cg_type_get(c, id);
    396   }
    397   return ty ? id : KIT_CG_TYPE_NONE;
    398 }
    399 
    400 static KitCgFuncParam* copy_cg_params(Compiler* c, const KitCgFuncParam* src,
    401                                       u32 n) {
    402   KitCgFuncParam* dst;
    403   if (!n) return NULL;
    404   if (!src) return NULL;
    405   dst = arena_array(&c->global->arena, KitCgFuncParam, n);
    406   if (!dst) return NULL;
    407   memcpy(dst, src, sizeof(*dst) * n);
    408   return dst;
    409 }
    410 
    411 static CgTypeField* copy_cg_fields(Compiler* c, const KitCgField* src, u32 n) {
    412   CgTypeField* dst;
    413   if (!n) return NULL;
    414   if (!src) return NULL;
    415   dst = arena_array(&c->global->arena, CgTypeField, n);
    416   if (!dst) return NULL;
    417   memset(dst, 0, sizeof(*dst) * n);
    418   for (u32 i = 0; i < n; ++i) {
    419     dst[i].name = src[i].name;
    420     dst[i].type = src[i].type;
    421     dst[i].align_override = src[i].align_override;
    422     dst[i].max_align = src[i].max_align;
    423     dst[i].flags = src[i].flags;
    424     dst[i].bit_width = src[i].bit_width;
    425     dst[i].bit_signed = src[i].bit_signed != 0;
    426   }
    427   return dst;
    428 }
    429 
    430 static int cg_type_layout_record(Compiler* c, CgType* cg) {
    431   u32 max_align = 1;
    432   u64 size = 0;
    433   if (!c || !cg || cg->kind != KIT_CG_TYPE_RECORD) return 0;
    434   if (cg->record.nfields && !cg->record.fields) return 0;
    435   if (cg->record.is_union) {
    436     for (u32 i = 0; i < cg->record.nfields; ++i) {
    437       CgTypeField* f = &cg->record.fields[i];
    438       u64 fsize = cg_type_size(c, f->type);
    439       u32 falign = cg_type_align(c, f->type);
    440       if (!falign) return 0;
    441       if (f->max_align && falign > f->max_align) falign = f->max_align;
    442       if (f->align_override == 1u) {
    443         falign = 1;
    444       } else if (f->align_override > falign) {
    445         falign = f->align_override;
    446       }
    447       if (falign > max_align) max_align = falign;
    448       if ((f->flags & KIT_CG_FIELD_BITFIELD) != 0) {
    449         f->offset = 0;
    450         f->bit_offset = 0;
    451         f->bit_storage_size = (u32)fsize;
    452         if (f->bit_width == 0) continue;
    453       }
    454       if (fsize > size) size = fsize;
    455       f->offset = 0;
    456     }
    457   } else {
    458     u64 off = 0;
    459     int active_bitfield_unit = 0;
    460     u64 unit_off = 0;
    461     u32 unit_bits = 0;
    462     u32 unit_size = 0;
    463     u32 next_bit = 0;
    464     for (u32 i = 0; i < cg->record.nfields; ++i) {
    465       CgTypeField* f = &cg->record.fields[i];
    466       u64 fsize = cg_type_size(c, f->type);
    467       u32 falign = cg_type_align(c, f->type);
    468       if (!falign) return 0;
    469       if (f->max_align && falign > f->max_align) falign = f->max_align;
    470       if (f->align_override == 1u) {
    471         falign = 1;
    472       } else if (f->align_override > falign) {
    473         falign = f->align_override;
    474       }
    475       if (falign > max_align) max_align = falign;
    476       if ((f->flags & KIT_CG_FIELD_BITFIELD) != 0) {
    477         if (fsize > UINT32_MAX / 8u) return 0;
    478         if (f->bit_width == 0) {
    479           if (active_bitfield_unit) off = unit_off + unit_size;
    480           off = cg_align_to(off, falign);
    481           f->offset = off;
    482           f->bit_offset = 0;
    483           f->bit_storage_size = (u32)fsize;
    484           active_bitfield_unit = 0;
    485           next_bit = 0;
    486           continue;
    487         }
    488         if (f->bit_width > fsize * 8u) return 0;
    489         if (!active_bitfield_unit || unit_size != (u32)fsize ||
    490             next_bit + f->bit_width > unit_bits) {
    491           if (active_bitfield_unit) off = unit_off + unit_size;
    492           off = cg_align_to(off, falign);
    493           unit_off = off;
    494           unit_size = (u32)fsize;
    495           unit_bits = unit_size * 8u;
    496           next_bit = 0;
    497           active_bitfield_unit = 1;
    498         }
    499         f->offset = unit_off;
    500         f->bit_offset = (u16)next_bit;
    501         f->bit_storage_size = unit_size;
    502         next_bit += f->bit_width;
    503         off = unit_off + unit_size;
    504         continue;
    505       }
    506       active_bitfield_unit = 0;
    507       off = cg_align_to(off, falign);
    508       f->offset = off;
    509       off += fsize;
    510     }
    511     size = off;
    512   }
    513   if (cg->record.align_override > max_align) {
    514     max_align = cg->record.align_override;
    515   }
    516   cg->align = max_align;
    517   cg->size = cg_align_to(size, max_align);
    518   return 1;
    519 }
    520 
    521 static int cg_type_set_ptr(Compiler* c, CgApiType* e, KitCgTypeId pointee,
    522                            u32 address_space) {
    523   u32 ptr_size;
    524   u32 ptr_align;
    525   if (!cg_type_get(c, pointee)) return 0;
    526   memset(&e->cg, 0, sizeof(e->cg));
    527   ptr_size = c->target.ptr_size ? c->target.ptr_size : 8;
    528   ptr_align = c->target.ptr_align ? c->target.ptr_align : ptr_size;
    529   e->cg.kind = KIT_CG_TYPE_PTR;
    530   e->cg.size = ptr_size;
    531   e->cg.align = ptr_align;
    532   e->cg.ptr.pointee = pointee;
    533   e->cg.ptr.address_space = address_space;
    534   return 1;
    535 }
    536 
    537 static int cg_type_set_array(Compiler* c, CgApiType* e, KitCgTypeId elem,
    538                              u64 count) {
    539   const CgType* ety = cg_type_get(c, elem);
    540   if (!ety) return 0;
    541   memset(&e->cg, 0, sizeof(e->cg));
    542   e->cg.kind = KIT_CG_TYPE_ARRAY;
    543   e->cg.size = ety->size * count;
    544   e->cg.align = ety->align;
    545   e->cg.array.elem = elem;
    546   e->cg.array.count = count;
    547   return 1;
    548 }
    549 
    550 static int cg_type_set_alias(Compiler* c, CgApiType* e, KitSym name,
    551                              KitCgTypeId base) {
    552   const CgType* bty = cg_type_get(c, base);
    553   if (!bty) return 0;
    554   memset(&e->cg, 0, sizeof(e->cg));
    555   e->cg.kind = KIT_CG_TYPE_ALIAS;
    556   e->cg.size = bty->size;
    557   e->cg.align = bty->align;
    558   e->cg.alias.name = name;
    559   e->cg.alias.base = base;
    560   return 1;
    561 }
    562 
    563 static int cg_type_set_record(Compiler* c, CgApiType* e, KitSym tag,
    564                               const KitCgField* fields, u32 nfields,
    565                               int is_union, u32 align_override, u32 flags) {
    566   CgTypeField* copied = copy_cg_fields(c, fields, nfields);
    567   if (nfields && !copied) return 0;
    568   memset(&e->cg, 0, sizeof(e->cg));
    569   e->cg.kind = KIT_CG_TYPE_RECORD;
    570   e->cg.record.tag = tag;
    571   e->cg.record.fields = copied;
    572   e->cg.record.nfields = nfields;
    573   e->cg.record.is_union = is_union != 0;
    574   e->cg.record.align_override = align_override;
    575   e->cg.record.flags = flags;
    576   return cg_type_layout_record(c, &e->cg);
    577 }
    578 
    579 static int cg_type_set_enum(Compiler* c, CgApiType* e, KitSym tag,
    580                             KitCgTypeId base, KitCgEnumValue* values,
    581                             u32 nvalues) {
    582   const CgType* bty;
    583   if (base == KIT_CG_TYPE_NONE) base = builtin_id(KIT_CG_BUILTIN_I32);
    584   bty = cg_type_get(c, base);
    585   if (!bty ||
    586       !(bty->kind == KIT_CG_TYPE_INT || bty->kind == KIT_CG_TYPE_BOOL)) {
    587     return 0;
    588   }
    589   memset(&e->cg, 0, sizeof(e->cg));
    590   e->cg.kind = KIT_CG_TYPE_ENUM;
    591   e->cg.size = bty->size;
    592   e->cg.align = bty->align;
    593   e->cg.enum_.tag = tag;
    594   e->cg.enum_.base = base;
    595   e->cg.enum_.values = values;
    596   e->cg.enum_.nvalues = nvalues;
    597   return 1;
    598 }
    599 
    600 static int cg_type_set_func(Compiler* c, CgApiType* e, KitCgFuncSig sig,
    601                             KitCgFuncParam* params) {
    602   if (sig.result.type && !cg_type_get(c, sig.result.type)) return 0;
    603   for (u32 i = 0; i < sig.nparams; ++i) {
    604     if (!cg_type_get(c, sig.params[i].type)) return 0;
    605   }
    606   memset(&e->cg, 0, sizeof(e->cg));
    607   e->cg.kind = KIT_CG_TYPE_FUNC;
    608   e->cg.size = 1;
    609   e->cg.align = 1;
    610   e->cg.func.result = sig.result;
    611   e->cg.func.params = params;
    612   e->cg.func.nparams = sig.nparams;
    613   e->cg.func.call_conv = sig.call_conv;
    614   e->cg.func.abi_variadic = sig.abi_variadic != 0;
    615   return 1;
    616 }
    617 
    618 KitCgBuiltinTypes kit_cg_builtin_types(KitCompiler* c) {
    619   KitCgBuiltinTypes out;
    620   (void)c;
    621   memset(&out, 0, sizeof(out));
    622   for (u32 i = 0; i < KIT_CG_BUILTIN_COUNT; ++i) {
    623     out.id[i] = builtin_id((KitCgBuiltinType)i);
    624   }
    625   return out;
    626 }
    627 
    628 KitCgTypeId kit_cg_type_ptr(KitCompiler* c, KitCgTypeId pointee,
    629                             uint32_t address_space) {
    630   KitCgTypeId id;
    631   CgApiType* e;
    632   if (!cg_type_get(c, pointee)) return KIT_CG_TYPE_NONE;
    633   id = find_ptr_type_id(c, pointee, address_space);
    634   if (id != KIT_CG_TYPE_NONE) return id;
    635   e = type_alloc(c, &id);
    636   if (!e) return KIT_CG_TYPE_NONE;
    637   e->base = pointee;
    638   e->address_space = address_space;
    639   e->kind = CG_API_TYPE_PTR;
    640   if (!cg_type_set_ptr(c, e, pointee, address_space)) {
    641     return KIT_CG_TYPE_NONE;
    642   }
    643   return id;
    644 }
    645 
    646 KitCgTypeId kit_cg_type_array(KitCompiler* c, KitCgTypeId elem,
    647                               uint64_t count) {
    648   KitCgTypeId id;
    649   CgApiType* e;
    650   if (!cg_type_get(c, elem) || count > UINT32_MAX) return KIT_CG_TYPE_NONE;
    651   id = find_array_type_id(c, elem, count);
    652   if (id != KIT_CG_TYPE_NONE) return id;
    653   e = type_alloc(c, &id);
    654   if (!e) return KIT_CG_TYPE_NONE;
    655   e->base = elem;
    656   e->array_count = count;
    657   e->kind = CG_API_TYPE_ARRAY;
    658   if (!cg_type_set_array(c, e, elem, count)) {
    659     return KIT_CG_TYPE_NONE;
    660   }
    661   return id;
    662 }
    663 
    664 KitCgTypeId kit_cg_type_alias(KitCompiler* c, KitSym name, KitCgTypeId base) {
    665   KitCgTypeId id;
    666   CgApiType* e;
    667   if (!cg_type_get(c, base)) return KIT_CG_TYPE_NONE;
    668   e = type_alloc(c, &id);
    669   if (!e) return KIT_CG_TYPE_NONE;
    670   e->base = base;
    671   e->name = name;
    672   e->kind = CG_API_TYPE_ALIAS;
    673   return cg_type_set_alias(c, e, name, base) ? id : KIT_CG_TYPE_NONE;
    674 }
    675 
    676 KitCgTypeId kit_cg_type_record(KitCompiler* c, KitSym tag,
    677                                const KitCgField* fields, uint32_t nfields) {
    678   KitCgRecordDesc desc;
    679   memset(&desc, 0, sizeof desc);
    680   desc.tag = tag;
    681   desc.fields = fields;
    682   desc.nfields = nfields;
    683   return kit_cg_type_record_ex(c, &desc);
    684 }
    685 
    686 KitCgTypeId kit_cg_type_record_ex(KitCompiler* c, const KitCgRecordDesc* desc) {
    687   KitCgTypeId id;
    688   CgApiType* e;
    689   KitCgField* copied = NULL;
    690   if (!c || !desc || (desc->nfields && !desc->fields) ||
    691       desc->nfields > UINT16_MAX) {
    692     return KIT_CG_TYPE_NONE;
    693   }
    694   if (desc->nfields) {
    695     copied = arena_array(&c->global->arena, KitCgField, desc->nfields);
    696     if (!copied) return KIT_CG_TYPE_NONE;
    697   }
    698 
    699   for (u32 i = 0; i < desc->nfields; ++i) {
    700     if (!cg_type_get(c, desc->fields[i].type)) return KIT_CG_TYPE_NONE;
    701     copied[i] = desc->fields[i];
    702   }
    703   e = type_alloc(c, &id);
    704   if (!e) return KIT_CG_TYPE_NONE;
    705   e->name = desc->tag;
    706   e->count = desc->nfields;
    707   e->fields = copied;
    708   e->kind = CG_API_TYPE_RECORD;
    709   if (!cg_type_set_record(c, e, desc->tag, desc->fields, desc->nfields,
    710                           desc->is_union, desc->align_override, 0)) {
    711     return KIT_CG_TYPE_NONE;
    712   }
    713   return id;
    714 }
    715 
    716 KitCgTypeId kit_cg_type_enum(KitCompiler* c, KitSym tag, KitCgTypeId base,
    717                              const KitCgEnumValue* values, uint32_t nvalues) {
    718   KitCgEnumValue* copied = NULL;
    719   KitCgTypeId id;
    720   CgApiType* e;
    721   if (!c || (nvalues && !values)) return KIT_CG_TYPE_NONE;
    722   if (base == KIT_CG_TYPE_NONE) base = builtin_id(KIT_CG_BUILTIN_I32);
    723   if (!cg_type_is_int(c, base)) return KIT_CG_TYPE_NONE;
    724   if (nvalues) {
    725     copied = arena_array(&c->global->arena, KitCgEnumValue, nvalues);
    726     if (!copied) return KIT_CG_TYPE_NONE;
    727     memcpy(copied, values, sizeof(*copied) * nvalues);
    728   }
    729   e = type_alloc(c, &id);
    730   if (!e) return KIT_CG_TYPE_NONE;
    731   e->base = base;
    732   e->name = tag;
    733   e->count = nvalues;
    734   e->values = copied;
    735   e->kind = CG_API_TYPE_ENUM;
    736   if (!cg_type_set_enum(c, e, tag, base, copied, nvalues)) {
    737     return KIT_CG_TYPE_NONE;
    738   }
    739   return id;
    740 }
    741 
    742 KitCgTypeId kit_cg_type_func(KitCompiler* c, KitCgFuncSig sig) {
    743   KitCgFuncParam* copied = NULL;
    744   KitCgTypeId id;
    745   CgApiType* e;
    746   if (!c || (sig.nparams && !sig.params) || sig.nparams > UINT16_MAX) {
    747     return KIT_CG_TYPE_NONE;
    748   }
    749   if (sig.result.type && !cg_type_get(c, sig.result.type))
    750     return KIT_CG_TYPE_NONE;
    751   id = find_func_type_id(c, sig);
    752   if (id != KIT_CG_TYPE_NONE) return id;
    753   if (sig.nparams) {
    754     copied = copy_cg_params(c, sig.params, sig.nparams);
    755     if (!copied) return KIT_CG_TYPE_NONE;
    756     for (u32 i = 0; i < sig.nparams; ++i) {
    757       if (!cg_type_get(c, sig.params[i].type)) return KIT_CG_TYPE_NONE;
    758     }
    759   }
    760   e = type_alloc(c, &id);
    761   if (!e) return KIT_CG_TYPE_NONE;
    762   e->count = sig.nparams;
    763   e->params = copied;
    764   e->result = sig.result;
    765   e->call_conv = sig.call_conv;
    766   e->abi_variadic = sig.abi_variadic != 0;
    767   e->kind = CG_API_TYPE_FUNC;
    768   if (!cg_type_set_func(c, e, sig, copied)) {
    769     return KIT_CG_TYPE_NONE;
    770   }
    771   return id;
    772 }
    773 
    774 uint64_t kit_cg_type_size(KitCompiler* c, KitCgTypeId id) {
    775   return cg_type_size(c, id);
    776 }
    777 
    778 uint32_t kit_cg_type_align(KitCompiler* c, KitCgTypeId id) {
    779   return cg_type_align(c, id);
    780 }
    781 
    782 KitCgTypeKind kit_cg_type_kind(KitCompiler* c, KitCgTypeId id) {
    783   const CgType* ty = cg_type_get(c, id);
    784   return ty ? ty->kind : KIT_CG_TYPE_VOID;
    785 }
    786 
    787 uint32_t kit_cg_type_int_width(KitCompiler* c, KitCgTypeId id) {
    788   const CgType* ty = cg_type_get(c, id);
    789   if (!ty) return 0;
    790   if (ty->kind == KIT_CG_TYPE_INT || ty->kind == KIT_CG_TYPE_BOOL) {
    791     return ty->integer.width;
    792   }
    793   if (ty->kind == KIT_CG_TYPE_ENUM) {
    794     return (uint32_t)ty->size * 8u;
    795   }
    796   if (ty->kind == KIT_CG_TYPE_ALIAS) {
    797     return kit_cg_type_int_width(c, ty->alias.base);
    798   }
    799   return 0;
    800 }
    801 
    802 uint32_t kit_cg_type_float_width(KitCompiler* c, KitCgTypeId id) {
    803   const CgType* ty = cg_type_get(c, id);
    804   if (!ty) return 0;
    805   if (ty->kind == KIT_CG_TYPE_FLOAT) return ty->fp.width;
    806   if (ty->kind == KIT_CG_TYPE_ALIAS) {
    807     return kit_cg_type_float_width(c, ty->alias.base);
    808   }
    809   return 0;
    810 }
    811 
    812 KitCgTypeId kit_cg_type_ptr_pointee(KitCompiler* c, KitCgTypeId id) {
    813   const CgType* ty = cg_type_get(c, id);
    814   return (ty && ty->kind == KIT_CG_TYPE_PTR) ? ty->ptr.pointee
    815                                              : KIT_CG_TYPE_NONE;
    816 }
    817 
    818 KitCgTypeId kit_cg_type_array_elem(KitCompiler* c, KitCgTypeId id) {
    819   const CgType* ty = cg_type_get(c, id);
    820   return (ty && ty->kind == KIT_CG_TYPE_ARRAY) ? ty->array.elem
    821                                                : KIT_CG_TYPE_NONE;
    822 }
    823 
    824 uint32_t kit_cg_type_ptr_address_space(KitCompiler* c, KitCgTypeId id) {
    825   const CgType* ty = cg_type_get(c, id);
    826   return (ty && ty->kind == KIT_CG_TYPE_PTR) ? ty->ptr.address_space : 0u;
    827 }
    828 
    829 uint64_t kit_cg_type_array_count(KitCompiler* c, KitCgTypeId id) {
    830   const CgType* ty = cg_type_get(c, id);
    831   return (ty && ty->kind == KIT_CG_TYPE_ARRAY) ? ty->array.count : 0u;
    832 }
    833 
    834 KitCgFuncResult kit_cg_type_func_result(KitCompiler* c, KitCgTypeId id) {
    835   const CgType* ty = cg_type_get(c, id);
    836   KitCgFuncResult empty;
    837   memset(&empty, 0, sizeof(empty));
    838   if (!ty || ty->kind != KIT_CG_TYPE_FUNC) return empty;
    839   return ty->func.result;
    840 }
    841 
    842 uint32_t kit_cg_type_func_nparams(KitCompiler* c, KitCgTypeId id) {
    843   const CgType* ty = cg_type_get(c, id);
    844   return (ty && ty->kind == KIT_CG_TYPE_FUNC) ? ty->func.nparams : 0;
    845 }
    846 
    847 KitCgFuncParam kit_cg_type_func_param(KitCompiler* c, KitCgTypeId id,
    848                                       uint32_t index) {
    849   const CgType* ty = cg_type_get(c, id);
    850   KitCgFuncParam empty;
    851   memset(&empty, 0, sizeof(empty));
    852   if (!ty || ty->kind != KIT_CG_TYPE_FUNC || index >= ty->func.nparams) {
    853     return empty;
    854   }
    855   return ty->func.params[index];
    856 }
    857 
    858 KitCgCallConv kit_cg_type_func_call_conv(KitCompiler* c, KitCgTypeId id) {
    859   const CgType* ty = cg_type_get(c, id);
    860   return (ty && ty->kind == KIT_CG_TYPE_FUNC) ? ty->func.call_conv
    861                                               : KIT_CG_CC_TARGET_C;
    862 }
    863 
    864 int kit_cg_type_func_is_variadic(KitCompiler* c, KitCgTypeId id) {
    865   const CgType* ty = cg_type_get(c, id);
    866   return ty && ty->kind == KIT_CG_TYPE_FUNC && ty->func.abi_variadic;
    867 }
    868 
    869 uint32_t kit_cg_type_record_nfields(KitCompiler* c, KitCgTypeId id) {
    870   const CgType* ty = cg_type_get(c, id);
    871   return (ty && ty->kind == KIT_CG_TYPE_RECORD) ? ty->record.nfields : 0;
    872 }
    873 
    874 KitStatus kit_cg_type_record_field(KitCompiler* c, KitCgTypeId id,
    875                                    uint32_t index, KitCgField* out,
    876                                    uint64_t* offset_out) {
    877   const CgType* ty = cg_type_get(c, id);
    878   const CgTypeField* f;
    879   if (!ty || ty->kind != KIT_CG_TYPE_RECORD || index >= ty->record.nfields) {
    880     return KIT_NOT_FOUND;
    881   }
    882   f = &ty->record.fields[index];
    883   if (out) {
    884     out->name = f->name;
    885     out->type = f->type;
    886     out->align_override = f->align_override;
    887     out->max_align = f->max_align;
    888     out->flags = f->flags;
    889     out->bit_width = f->bit_width;
    890     out->bit_offset = f->bit_offset;
    891     out->bit_storage_size = f->bit_storage_size;
    892     out->bit_signed = f->bit_signed;
    893   }
    894   if (offset_out) *offset_out = f->offset;
    895   return KIT_OK;
    896 }
    897 
    898 int kit_cg_target_supports_call_conv(KitCompiler* c, KitCgCallConv cc) {
    899   const ArchImpl* a;
    900   if (!c) return 0;
    901   /* TARGET_C is always available, including for arches with no codegen backend
    902    * (x86_32/arm_32, where arch_for_compiler is NULL). */
    903   if (cc == KIT_CG_CC_TARGET_C) return 1;
    904   a = arch_for_compiler(c);
    905   if (!a || !a->supports_call_conv) return 0;
    906   return a->supports_call_conv(c, cc);
    907 }
    908 
    909 int kit_cg_target_supports_symbol_feature(KitCompiler* c,
    910                                           KitCgSymbolFeature feat) {
    911   if (!c) return 0;
    912   switch (feat) {
    913     case KIT_CG_SYMFEAT_WEAK:
    914     case KIT_CG_SYMFEAT_PROTECTED_VISIBILITY:
    915     case KIT_CG_SYMFEAT_COMDAT:
    916     case KIT_CG_SYMFEAT_COMMON:
    917       return 1;
    918     case KIT_CG_SYMFEAT_TLS_LOCAL_EXEC:
    919       /* Local-exec is the only TLS model kit emits.  Whether it is actually
    920        * available still depends on the object format being able to represent a
    921        * TLS access at all (ELF/Mach-O yes; COFF/Wasm no). */
    922       return obj_format_supports_symbol_feature(c, (int)feat);
    923     case KIT_CG_SYMFEAT_TLS_INITIAL_EXEC:
    924     case KIT_CG_SYMFEAT_TLS_LOCAL_DYNAMIC:
    925     case KIT_CG_SYMFEAT_TLS_GENERAL_DYNAMIC:
    926       /* kit has no initial-exec / local-dynamic / general-dynamic codegen and
    927        * no dynamic-TLS runtime (__tls_get_addr), so it never emits these even
    928        * where the object format could represent them.  Report the truth so a
    929        * caller can't request a dynamic model and silently get local-exec; the
    930        * linker enforces the same contract (see link_require_local_tls). */
    931       return 0;
    932     case KIT_CG_SYMFEAT_DLLIMPORT:
    933     case KIT_CG_SYMFEAT_DLLEXPORT:
    934     case KIT_CG_SYMFEAT_MERGE_SECTIONS:
    935     case KIT_CG_SYMFEAT_CONSTRUCTOR_PRIORITY:
    936       return 0;
    937   }
    938   return 0;
    939 }
    940 
    941 KitCgVaListKind kit_cg_target_va_list_kind(const KitCompiler* c) {
    942   ABIVaListInfo va;
    943   if (!c) return KIT_CG_VALIST_OPAQUE;
    944   va = abi_va_list_layout(c->abi);
    945   switch ((ABIVaListKind)va.kind) {
    946     case ABI_VA_LIST_OPAQUE:
    947       return KIT_CG_VALIST_OPAQUE;
    948     case ABI_VA_LIST_POINTER:
    949       return KIT_CG_VALIST_POINTER;
    950     case ABI_VA_LIST_AAPCS64:
    951       return KIT_CG_VALIST_AAPCS64;
    952     case ABI_VA_LIST_SYSV_X64:
    953       return KIT_CG_VALIST_SYSV_X64;
    954   }
    955   return KIT_CG_VALIST_OPAQUE;
    956 }
    957 
    958 const char* kit_cg_target_c_label_prefix(const KitCompiler* c) {
    959   return obj_format_c_label_prefix(c);
    960 }
    961 
    962 int kit_cg_target_supports_intrinsic(KitCompiler* c, KitCgIntrinsic intrin) {
    963   const ArchImpl* a;
    964   if (!c) return 0;
    965   a = arch_for_compiler(c);
    966   if (!a || !a->supports_intrinsic) return 0;
    967   return a->supports_intrinsic(c, intrin);
    968 }
    969 
    970 uint64_t kit_cg_target_backend_features(KitCompiler* c) {
    971   const ArchImpl* a;
    972   if (!c) return 0;
    973   a = arch_for_compiler(c);
    974   /* Arches with no registered codegen backend (x86_32) fall back to the
    975    * conservative strict-alignment baseline. */
    976   if (!a) return KIT_CG_BACKEND_STRICT_ALIGNMENT;
    977   return a->backend_features;
    978 }
    979 
    980 void cg_api_fini(Compiler* c) {
    981   CgApiState* s;
    982   if (!c || !c->cg_api) return;
    983   s = (CgApiState*)c->cg_api;
    984   CgApiTypes_fini(&s->types);
    985   s->heap->free(s->heap, s, sizeof(*s));
    986   c->cg_api = NULL;
    987   c->cg_api_free = NULL;
    988 }
    989 
    990 /* ============================================================
    991  * KitCg: public codegen API implementation
    992  *
    993  * Drives CgTarget directly with its own value stack.
    994  * ============================================================ */