kit

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

parse_expr.c (110618B)


      1 /* parse_expr.c — precedence climbing, unary/primary, literal decoding,
      2  * constant evaluation. */
      3 
      4 #include "parse/literal_unicode.h"
      5 #include "parse/parse_priv.h"
      6 
      7 static const Type* ty_int(Parser* p) { return type_prim(p->pool, TY_INT); }
      8 static const Type* ty_size_t(Parser* p) {
      9   return c_abi_size_type(p->abi, p->pool);
     10 }
     11 static int type_is_fp(const Type* t);
     12 
     13 static CKw ident_kw(const Parser* p, Sym name) {
     14   return ident_kw_inline(p, name);
     15 }
     16 
     17 static int accept_kw(Parser* p, CKw k) {
     18   if (is_kw(p, &p->cur, k)) {
     19     advance(p);
     20     return 1;
     21   }
     22   return 0;
     23 }
     24 
     25 static int type_is_incomplete(const Type* t) {
     26   if (!t) return 1;
     27   if (t->kind == TY_VOID) return 1;
     28   if ((t->kind == TY_STRUCT || t->kind == TY_UNION) && t->rec.incomplete)
     29     return 1;
     30   if (t->kind == TY_ARRAY && t->arr.incomplete) return 1;
     31   return 0;
     32 }
     33 
     34 static void require_sizeof_type(Parser* p, const Type* ty) {
     35   if (!ty || type_is_incomplete(ty) || ty->kind == TY_FUNC) {
     36     perr(p, "sizeof operand has incomplete or function type");
     37   }
     38 }
     39 
     40 static int type_is_void_ptr(const Type* ty) {
     41   return ty && ty->kind == TY_PTR && ty->ptr.pointee &&
     42          ty->ptr.pointee->kind == TY_VOID;
     43 }
     44 
     45 static const Type* ty_char16(Parser* p) {
     46   return type_prim(p->pool, TY_USHORT);
     47 }
     48 
     49 static const Type* ty_char32(Parser* p) { return type_prim(p->pool, TY_UINT); }
     50 
     51 static const Type* ty_wchar(Parser* p) {
     52   /* sizeof(wchar_t) is a resolved data-model fact (2 on Windows, 4 else);
     53    * key on the width rather than re-deriving from the OS identity. */
     54   KitTargetSpec target = kit_compiler_target_spec(p->c);
     55   return target.wchar_size == 2 ? ty_char16(p) : ty_int(p);
     56 }
     57 
     58 static int pointer_pointees_compatible(Parser* p, const Type* lhs,
     59                                        const Type* rhs) {
     60   const Type* lp;
     61   const Type* rp;
     62   if (!lhs || !rhs || lhs->kind != TY_PTR || rhs->kind != TY_PTR) return 0;
     63   lp = lhs->ptr.pointee;
     64   rp = rhs->ptr.pointee;
     65   if (!lp || !rp) return 0;
     66   return type_compatible(type_unqual(p->pool, lp), type_unqual(p->pool, rp));
     67 }
     68 
     69 static int null_pointer_constant(Parser* p, const Type* ty) {
     70   i64 v = 1;
     71   return type_is_int(ty) && (pcg_top_is_null_ptr_const(p) ||
     72                              (kit_cg_top_const_int(p->cg, &v) && v == 0));
     73 }
     74 
     75 static void require_scalar(Parser* p, const Type* ty, const char* what) {
     76   if (!c_type_is_scalar(ty))
     77     perr(p, "%.*s requires scalar operand",
     78          KIT_SLICE_ARG(kit_slice_cstr(what)));
     79 }
     80 
     81 static void require_arith(Parser* p, const Type* ty, const char* what) {
     82   if (!type_is_arith(ty))
     83     perr(p, "%.*s requires arithmetic operand",
     84          KIT_SLICE_ARG(kit_slice_cstr(what)));
     85 }
     86 
     87 static const Type* conditional_pointer_type(Parser* p, const Type* then_ty,
     88                                             int then_null, const Type* else_ty,
     89                                             int else_null) {
     90   if (then_ty && then_ty->kind == TY_PTR && else_null) return then_ty;
     91   if (else_ty && else_ty->kind == TY_PTR && then_null) return else_ty;
     92   if (!then_ty || !else_ty || then_ty->kind != TY_PTR ||
     93       else_ty->kind != TY_PTR)
     94     return NULL;
     95   if (type_is_void_ptr(then_ty)) return then_ty;
     96   if (type_is_void_ptr(else_ty)) return else_ty;
     97   if (pointer_pointees_compatible(p, then_ty, else_ty)) return then_ty;
     98   return NULL;
     99 }
    100 
    101 /* ============================================================
    102  * Literal parsing
    103  * ============================================================ */
    104 
    105 static u32 cint_bits(Parser* p, const Type* ty);
    106 static int cint_signed(Parser* p, const Type* ty);
    107 
    108 static u64 parse_int_literal_u64(Parser* p, const Tok* t, int* decimal_out) {
    109   KitSlice spell_sl = kit_sym_str(p->pool->c, t->spelling);
    110   size_t len = spell_sl.len;
    111   const char* s = spell_sl.s;
    112   size_t i = 0;
    113   u64 base = 10;
    114   u64 acc = 0;
    115   int decimal = 1;
    116   if (!s) perr(p, "bad numeric literal");
    117   if (len >= 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
    118     base = 16;
    119     decimal = 0;
    120     i = 2;
    121   } else if (len >= 2 && s[0] == '0' && (s[1] == 'b' || s[1] == 'B')) {
    122     base = 2;
    123     decimal = 0;
    124     i = 2;
    125   } else if (len >= 1 && s[0] == '0') {
    126     base = 8;
    127     decimal = 0;
    128     i = 1;
    129   }
    130   for (; i < len; ++i) {
    131     int c = (unsigned char)s[i];
    132     int dv;
    133     if (c == 'u' || c == 'U' || c == 'l' || c == 'L') break;
    134     if (c >= '0' && c <= '9')
    135       dv = c - '0';
    136     else if (c >= 'a' && c <= 'f')
    137       dv = c - 'a' + 10;
    138     else if (c >= 'A' && c <= 'F')
    139       dv = c - 'A' + 10;
    140     else
    141       perr(p, "bad digit in numeric literal");
    142     if ((u64)dv >= base) perr(p, "digit out of range for base");
    143     if (acc > (~0ull - (u64)dv) / base) perr(p, "integer literal too large");
    144     acc = acc * base + dv;
    145   }
    146   if (decimal_out) *decimal_out = decimal;
    147   return acc;
    148 }
    149 
    150 static int uint_fits_type(Parser* p, u64 v, const Type* ty) {
    151   u32 nb = cint_bits(p, ty);
    152   if (cint_signed(p, ty)) {
    153     if (nb >= 64) return v <= 0x7fffffffffffffffull;
    154     return v <= ((1ull << (nb - 1u)) - 1ull);
    155   }
    156   if (nb >= 64) return 1;
    157   return v <= ((1ull << nb) - 1ull);
    158 }
    159 
    160 static const Type* first_fitting_type(Parser* p, u64 v, const TypeKind* kinds,
    161                                       u32 nkinds) {
    162   u32 i;
    163   for (i = 0; i < nkinds; ++i) {
    164     const Type* ty = type_prim(p->pool, kinds[i]);
    165     if (uint_fits_type(p, v, ty)) return ty;
    166   }
    167   perr(p, "integer literal too large for supported integer types");
    168 }
    169 
    170 i64 parse_int_literal(Parser* p, const Tok* t) {
    171   return (i64)parse_int_literal_u64(p, t, NULL);
    172 }
    173 
    174 static const Type* int_literal_type(Parser* p, const Tok* t) {
    175   int u = (t->flags & TF_INT_U) != 0;
    176   int l = (t->flags & TF_INT_L) != 0;
    177   int ll = (t->flags & TF_INT_LL) != 0;
    178   int decimal = 1;
    179   u64 v = parse_int_literal_u64(p, t, &decimal);
    180   if (u && ll) {
    181     static const TypeKind order[] = {TY_ULLONG};
    182     return first_fitting_type(p, v, order,
    183                               (u32)(sizeof order / sizeof order[0]));
    184   }
    185   if (!u && ll) {
    186     static const TypeKind dec_order[] = {TY_LLONG};
    187     static const TypeKind other_order[] = {TY_LLONG, TY_ULLONG};
    188     return decimal ? first_fitting_type(
    189                          p, v, dec_order,
    190                          (u32)(sizeof dec_order / sizeof dec_order[0]))
    191                    : first_fitting_type(
    192                          p, v, other_order,
    193                          (u32)(sizeof other_order / sizeof other_order[0]));
    194   }
    195   if (u && l) {
    196     static const TypeKind order[] = {TY_ULONG, TY_ULLONG};
    197     return first_fitting_type(p, v, order,
    198                               (u32)(sizeof order / sizeof order[0]));
    199   }
    200   if (!u && l) {
    201     static const TypeKind dec_order[] = {TY_LONG, TY_LLONG};
    202     static const TypeKind other_order[] = {TY_LONG, TY_ULONG, TY_LLONG,
    203                                            TY_ULLONG};
    204     return decimal ? first_fitting_type(
    205                          p, v, dec_order,
    206                          (u32)(sizeof dec_order / sizeof dec_order[0]))
    207                    : first_fitting_type(
    208                          p, v, other_order,
    209                          (u32)(sizeof other_order / sizeof other_order[0]));
    210   }
    211   if (u) {
    212     static const TypeKind order[] = {TY_UINT, TY_ULONG, TY_ULLONG};
    213     return first_fitting_type(p, v, order,
    214                               (u32)(sizeof order / sizeof order[0]));
    215   }
    216   if (decimal) {
    217     static const TypeKind order[] = {TY_INT, TY_LONG, TY_LLONG};
    218     return first_fitting_type(p, v, order,
    219                               (u32)(sizeof order / sizeof order[0]));
    220   } else {
    221     static const TypeKind order[] = {TY_INT,   TY_UINT,  TY_LONG,
    222                                      TY_ULONG, TY_LLONG, TY_ULLONG};
    223     return first_fitting_type(p, v, order,
    224                               (u32)(sizeof order / sizeof order[0]));
    225   }
    226 }
    227 
    228 double parse_float_literal(Parser* p, const Tok* t) {
    229   KitSlice spell_sl = kit_sym_str(p->pool->c, t->spelling);
    230   size_t len = spell_sl.len;
    231   const char* s = spell_sl.s;
    232   size_t i = 0;
    233   int is_hex = 0;
    234   double v = 0.0;
    235   int exp = 0;
    236   int dec_exp = 0;
    237   int frac_seen = 0;
    238   if (!s) perr(p, "bad float literal");
    239   if (len >= 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
    240     is_hex = 1;
    241     i = 2;
    242   }
    243   while (i < len) {
    244     int c = (unsigned char)s[i];
    245     int dv;
    246     if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P' || c == 'f' ||
    247         c == 'F' || c == 'l' || c == 'L')
    248       break;
    249     if (c >= '0' && c <= '9')
    250       dv = c - '0';
    251     else if (is_hex && c >= 'a' && c <= 'f')
    252       dv = c - 'a' + 10;
    253     else if (is_hex && c >= 'A' && c <= 'F')
    254       dv = c - 'A' + 10;
    255     else
    256       perr(p, "bad digit in float literal");
    257     v = v * (is_hex ? 16.0 : 10.0) + (double)dv;
    258     i++;
    259   }
    260   if (i < len && s[i] == '.') {
    261     i++;
    262     while (i < len) {
    263       int c = (unsigned char)s[i];
    264       int dv;
    265       if (c == 'e' || c == 'E' || c == 'p' || c == 'P' || c == 'f' ||
    266           c == 'F' || c == 'l' || c == 'L')
    267         break;
    268       if (c >= '0' && c <= '9')
    269         dv = c - '0';
    270       else if (is_hex && c >= 'a' && c <= 'f')
    271         dv = c - 'a' + 10;
    272       else if (is_hex && c >= 'A' && c <= 'F')
    273         dv = c - 'A' + 10;
    274       else
    275         perr(p, "bad digit in float literal");
    276       v = v * (is_hex ? 16.0 : 10.0) + (double)dv;
    277       exp -= 1;
    278       frac_seen = 1;
    279       i++;
    280     }
    281   }
    282   (void)frac_seen;
    283   if (i < len && (s[i] == 'e' || s[i] == 'E' || s[i] == 'p' || s[i] == 'P')) {
    284     int neg = 0;
    285     int n = 0;
    286     int hex_exp = (s[i] == 'p' || s[i] == 'P');
    287     i++;
    288     if (i < len && (s[i] == '+' || s[i] == '-')) {
    289       if (s[i] == '-') neg = 1;
    290       i++;
    291     }
    292     while (i < len) {
    293       int c = (unsigned char)s[i];
    294       if (c < '0' || c > '9') break;
    295       n = n * 10 + (c - '0');
    296       i++;
    297     }
    298     dec_exp = neg ? -n : n;
    299     if (hex_exp) {
    300       dec_exp += exp * 4;
    301       exp = 0;
    302     }
    303   }
    304   while (exp < 0) {
    305     v /= (is_hex ? 16.0 : 10.0);
    306     exp++;
    307   }
    308   while (exp > 0) {
    309     v *= (is_hex ? 16.0 : 10.0);
    310     exp--;
    311   }
    312   if (is_hex) {
    313     while (dec_exp < 0) {
    314       v /= 2.0;
    315       dec_exp++;
    316     }
    317     while (dec_exp > 0) {
    318       v *= 2.0;
    319       dec_exp--;
    320     }
    321   } else {
    322     while (dec_exp < 0) {
    323       v /= 10.0;
    324       dec_exp++;
    325     }
    326     while (dec_exp > 0) {
    327       v *= 10.0;
    328       dec_exp--;
    329     }
    330   }
    331   return v;
    332 }
    333 
    334 static const Type* float_literal_type(Parser* p, const Tok* t) {
    335   if (t->flags & TF_FLT_F) return type_prim(p->pool, TY_FLOAT);
    336   if (t->flags & TF_FLT_L) return type_prim(p->pool, TY_LDOUBLE);
    337   return type_prim(p->pool, TY_DOUBLE);
    338 }
    339 
    340 const Type* char_literal_type(Parser* p, const Tok* t) {
    341   if (t->flags & TF_STR_U16) return ty_char16(p);
    342   if (t->flags & TF_STR_U32) return ty_char32(p);
    343   return ty_int(p);
    344 }
    345 
    346 static CLitStringEnc literal_string_encoding(const Tok* t) {
    347   if (t->flags & TF_STR_U8) return C_LIT_STR_UTF8;
    348   if (t->flags & TF_STR_U16) return C_LIT_STR_UTF16;
    349   if (t->flags & (TF_STR_WIDE | TF_STR_U32)) return C_LIT_STR_UTF32;
    350   return C_LIT_STR_ORDINARY;
    351 }
    352 
    353 const Type* string_literal_elem_type(Parser* p, const Tok* t) {
    354   if (t->flags & TF_STR_WIDE) return ty_wchar(p);
    355   if (t->flags & TF_STR_U16) return ty_char16(p);
    356   if (t->flags & TF_STR_U32) return ty_char32(p);
    357   return type_prim(p->pool, TY_CHAR);
    358 }
    359 
    360 int string_literal_initializes_array(Parser* p, const Type* elem,
    361                                      const Tok* t) {
    362   const Type* uelem;
    363   if (!elem || !t || t->kind != TOK_STR) return 0;
    364   uelem = type_unqual(p->pool, elem);
    365   if (!(t->flags & (TF_STR_WIDE | TF_STR_U16 | TF_STR_U32))) {
    366     return is_char_kind(uelem);
    367   }
    368   return type_compatible(uelem, string_literal_elem_type(p, t));
    369 }
    370 
    371 i64 decode_char_literal(Parser* p, const Tok* t) {
    372   KitSlice spell_sl = kit_sym_str(p->pool->c, t->spelling);
    373   size_t len = spell_sl.len;
    374   const char* s = spell_sl.s;
    375   size_t i = 0;
    376   CLitUnit unit;
    377   const char* err = NULL;
    378   u32 v;
    379   u32 bits = 8;
    380   CLitStringEnc enc = literal_string_encoding(t);
    381   if (!s) perr(p, "bad char literal");
    382   if (t->flags & TF_STR_U8)
    383     i = 2;
    384   else if (t->flags & (TF_STR_WIDE | TF_STR_U16 | TF_STR_U32))
    385     i = 1;
    386   if (t->flags & TF_STR_U16)
    387     bits = 16;
    388   else if (t->flags & (TF_STR_WIDE | TF_STR_U32))
    389     bits = 32;
    390   if (i >= len || s[i] != '\'') perr(p, "malformed character literal");
    391   i++;
    392   if (i >= len || s[i] == '\'') perr(p, "empty character literal");
    393   if (!c_lit_decode_unit(s, len, &i, &unit, &err)) {
    394     compiler_panic(
    395         p->c, t->loc, "%.*s",
    396         KIT_SLICE_ARG(kit_slice_cstr(err ? err : "bad character literal")));
    397   }
    398   if (!c_lit_encode_char_unit(enc, bits, unit, &v, &err)) {
    399     compiler_panic(
    400         p->c, t->loc, "%.*s",
    401         KIT_SLICE_ARG(kit_slice_cstr(err ? err : "bad character literal")));
    402   }
    403   if (i >= len || s[i] != '\'') {
    404     perr(p, "multi-character constants are not supported");
    405   }
    406   return (i64)v;
    407 }
    408 
    409 u8* decode_string_literal(Parser* p, const Tok* t, size_t* nlen_out) {
    410   KitSlice spell_sl = kit_sym_str(p->pool->c, t->spelling);
    411   size_t len = spell_sl.len;
    412   const char* s = spell_sl.s;
    413   size_t i = 0;
    414   Heap* h = kit_compiler_context(p->c)->heap;
    415   u8* buf;
    416   size_t k = 0;
    417   const Type* elem_ty;
    418   u32 elem_size;
    419   CLitStringEnc enc = literal_string_encoding(t);
    420   const char* err = NULL;
    421   if (!s) perr(p, "bad string literal");
    422   if (t->flags & TF_STR_U8)
    423     i = 2;
    424   else if (t->flags & (TF_STR_WIDE | TF_STR_U16 | TF_STR_U32))
    425     i = 1;
    426   elem_ty = string_literal_elem_type(p, t);
    427   elem_size = c_abi_sizeof(p->abi, elem_ty);
    428   if (i >= len || s[i] != '"') perr(p, "malformed string literal");
    429   i++;
    430   buf = (u8*)h->alloc(h, (len + 1u) * elem_size, 1);
    431   if (!buf) perr(p, "out of memory in string literal");
    432   while (i < len && s[i] != '"') {
    433     CLitUnit unit;
    434     if (!c_lit_decode_unit(s, len, &i, &unit, &err)) {
    435       compiler_panic(
    436           p->c, t->loc, "%.*s",
    437           KIT_SLICE_ARG(kit_slice_cstr(err ? err : "bad string literal")));
    438     }
    439     if (!c_lit_append_string_unit(buf, &k, enc, elem_size, unit, &err)) {
    440       compiler_panic(
    441           p->c, t->loc, "%.*s",
    442           KIT_SLICE_ARG(kit_slice_cstr(err ? err : "bad string literal")));
    443     }
    444   }
    445   c_lit_encode_uint_le(buf + k, elem_size, 0);
    446   k += elem_size;
    447   *nlen_out = k;
    448   return buf;
    449 }
    450 
    451 KitCgSym emit_string_to_rodata(Parser* p, const u8* bytes, size_t n) {
    452   const Type* arr_ty =
    453       type_array(p->pool, type_prim(p->pool, TY_CHAR), (u32)n, 0);
    454   return kit_cg_const_data(p->cg, bytes, n, 1u, pcg_tid(p, arr_ty));
    455 }
    456 
    457 KitCgSym emit_string_literal_to_rodata(Parser* p, const u8* bytes,
    458                                        size_t nbytes, const Type* elem_ty) {
    459   u32 elem_size = c_abi_sizeof(p->abi, elem_ty);
    460   u32 count = elem_size ? (u32)(nbytes / elem_size) : 0;
    461   const Type* arr_ty = type_array(p->pool, elem_ty, count, 0);
    462   return kit_cg_const_data(p->cg, bytes, nbytes, c_abi_alignof(p->abi, elem_ty),
    463                            pcg_tid(p, arr_ty));
    464 }
    465 
    466 /* ============================================================
    467  * Constant expression evaluator (cexpr_*)
    468  * ============================================================ */
    469 
    470 static CConstInt cexpr_unary(Parser* p, SrcLoc loc);
    471 static CConstInt cexpr_cond(Parser* p, SrcLoc loc);
    472 static const Type* offsetof_designator(Parser* p, const Type* base, u32* off);
    473 static const Type* common_fp_type(Parser* p, const Type* a, const Type* b);
    474 static void coerce_fp_cmp_operands(Parser* p, const Type* common);
    475 
    476 static u32 cint_bits(Parser* p, const Type* ty) {
    477   u32 sz = ty ? c_abi_sizeof(p->abi, ty) : 8u;
    478   if (ty && (ty->kind == TY_INT128 || ty->kind == TY_UINT128)) return 128;
    479   if (sz >= 8) return 64;
    480   return sz * 8u;
    481 }
    482 
    483 static int cint_signed(Parser* p, const Type* ty) {
    484   if (!ty) return 1;
    485   return c_abi_type_info(p->abi, ty).signed_ != 0;
    486 }
    487 
    488 static void cint_mask_to_bits(CConstInt* v, u32 bits) {
    489   if (bits < 64) {
    490     v->lo &= (1ull << bits) - 1ull;
    491     v->hi = 0;
    492   } else if (bits < 128) {
    493     v->hi &= (1ull << (bits - 64u)) - 1ull;
    494   }
    495 }
    496 
    497 static CConstInt cint_make_u64(Parser* p, const Type* ty, u64 bits) {
    498   CConstInt v;
    499   u32 nb;
    500   if (!ty) ty = ty_int(p);
    501   nb = cint_bits(p, ty);
    502   v.type = ty;
    503   v.lo = bits;
    504   v.hi = 0;
    505   cint_mask_to_bits(&v, nb);
    506   if (ty->kind == TY_BOOL) {
    507     v.lo = (v.lo || v.hi) ? 1u : 0u;
    508     v.hi = 0;
    509   }
    510   return v;
    511 }
    512 
    513 static CConstInt cint_make_pair(Parser* p, const Type* ty, u64 lo, u64 hi) {
    514   CConstInt v;
    515   if (!ty) ty = ty_int(p);
    516   v.type = ty;
    517   v.lo = lo;
    518   v.hi = hi;
    519   cint_mask_to_bits(&v, cint_bits(p, ty));
    520   if (ty->kind == TY_BOOL) {
    521     v.lo = (v.lo || v.hi) ? 1u : 0u;
    522     v.hi = 0;
    523   }
    524   return v;
    525 }
    526 
    527 static int cint_nonzero(CConstInt v) { return v.lo != 0 || v.hi != 0; }
    528 
    529 static int cint_eq(CConstInt a, CConstInt b) {
    530   return a.lo == b.lo && a.hi == b.hi;
    531 }
    532 
    533 static int cint_cmp_u(CConstInt a, CConstInt b) {
    534   if (a.hi != b.hi) return a.hi < b.hi ? -1 : 1;
    535   if (a.lo != b.lo) return a.lo < b.lo ? -1 : 1;
    536   return 0;
    537 }
    538 
    539 static CConstInt cint_add(Parser* p, const Type* ty, CConstInt a, CConstInt b) {
    540   u64 lo = a.lo + b.lo;
    541   return cint_make_pair(p, ty, lo, a.hi + b.hi + (lo < a.lo));
    542 }
    543 
    544 static CConstInt cint_sub(Parser* p, const Type* ty, CConstInt a, CConstInt b) {
    545   return cint_make_pair(p, ty, a.lo - b.lo, a.hi - b.hi - (a.lo < b.lo));
    546 }
    547 
    548 static CConstInt cint_shl(Parser* p, const Type* ty, CConstInt a, u32 sh) {
    549   if (sh >= 128) return cint_make_u64(p, ty, 0);
    550   if (sh == 0) return cint_make_pair(p, ty, a.lo, a.hi);
    551   if (sh >= 64) return cint_make_pair(p, ty, 0, a.lo << (sh - 64u));
    552   return cint_make_pair(p, ty, a.lo << sh, (a.hi << sh) | (a.lo >> (64u - sh)));
    553 }
    554 
    555 static CConstInt cint_shr_u(Parser* p, const Type* ty, CConstInt a, u32 sh) {
    556   if (sh >= 128) return cint_make_u64(p, ty, 0);
    557   if (sh == 0) return cint_make_pair(p, ty, a.lo, a.hi);
    558   if (sh >= 64) return cint_make_pair(p, ty, a.hi >> (sh - 64u), 0);
    559   return cint_make_pair(p, ty, (a.lo >> sh) | (a.hi << (64u - sh)), a.hi >> sh);
    560 }
    561 
    562 static CConstInt cint_neg(Parser* p, const Type* ty, CConstInt a) {
    563   CConstInt zero = cint_make_u64(p, ty, 0);
    564   return cint_sub(p, ty, zero, a);
    565 }
    566 
    567 static CConstInt cint_bnot(Parser* p, const Type* ty, CConstInt a) {
    568   return cint_make_pair(p, ty, ~a.lo, ~a.hi);
    569 }
    570 
    571 static CConstInt cint_mul(Parser* p, const Type* ty, CConstInt a, CConstInt b) {
    572   CConstInt r = cint_make_u64(p, ty, 0);
    573   CConstInt x = a;
    574   for (u32 i = 0; i < 128; ++i) {
    575     if ((i < 64 ? (b.lo >> i) : (b.hi >> (i - 64u))) & 1ull)
    576       r = cint_add(p, ty, r, x);
    577     x = cint_shl(p, ty, x, 1);
    578   }
    579   return r;
    580 }
    581 
    582 i64 const_int_as_i64(Parser* p, CConstInt v) {
    583   u32 nb = cint_bits(p, v.type);
    584   u64 u = v.lo;
    585   if (cint_signed(p, v.type) && nb < 64) {
    586     u64 mask = (1ull << nb) - 1ull;
    587     u64 sign = 1ull << (nb - 1u);
    588     u &= mask;
    589     if (u & sign) u |= ~mask;
    590   }
    591   return (i64)u;
    592 }
    593 
    594 static CConstInt cint_cast(Parser* p, CConstInt v, const Type* ty) {
    595   const Type* dst = type_unqual(p->pool, ty);
    596   if (!dst || !type_is_int(dst)) {
    597     perr(p, "integer constant expression cast requires integer type");
    598   }
    599   return cint_make_pair(p, dst, v.lo, v.hi);
    600 }
    601 
    602 static u32 cint_rank(const Type* ty) {
    603   return ty ? type_kind_int_rank((TypeKind)ty->kind) : 0;
    604 }
    605 
    606 static const Type* cint_unsigned_variant(Parser* p, const Type* ty) {
    607   TypeKind k = ty ? (TypeKind)ty->kind : TY_UINT;
    608   return type_prim(p->pool, type_kind_unsigned_variant(k));
    609 }
    610 
    611 static const Type* cint_promote_type(Parser* p, const Type* ty) {
    612   const Type* u = type_unqual(p->pool, ty);
    613   if (u && u->kind == TY_ENUM) return type_prim(p->pool, TY_INT);
    614   return type_promoted(p->pool, u);
    615 }
    616 
    617 static const Type* cint_common_type(Parser* p, const Type* a, const Type* b) {
    618   const Type* ap = cint_promote_type(p, a);
    619   const Type* bp = cint_promote_type(p, b);
    620   int as = cint_signed(p, ap);
    621   int bs = cint_signed(p, bp);
    622   u32 ar = cint_rank(ap);
    623   u32 br = cint_rank(bp);
    624   if (type_compatible(ap, bp)) return ap;
    625   if (as == bs) return ar >= br ? ap : bp;
    626   if (!as && ar >= br) return ap;
    627   if (!bs && br >= ar) return bp;
    628   if (as && cint_bits(p, ap) > cint_bits(p, bp)) return ap;
    629   if (bs && cint_bits(p, bp) > cint_bits(p, ap)) return bp;
    630   return cint_unsigned_variant(p, as ? ap : bp);
    631 }
    632 
    633 static CConstInt cint_convert(Parser* p, CConstInt v, const Type* ty) {
    634   return cint_make_pair(p, ty, v.lo, v.hi);
    635 }
    636 
    637 static int cint_truth(Parser* p, CConstInt v) {
    638   (void)p;
    639   return cint_nonzero(v);
    640 }
    641 
    642 static CConstInt cint_bool(Parser* p, int truth) {
    643   return cint_make_u64(p, ty_int(p), truth ? 1u : 0u);
    644 }
    645 
    646 static CConstInt cexpr_mul(Parser* p, SrcLoc loc) {
    647   CConstInt v = cexpr_unary(p, loc);
    648   for (;;) {
    649     int op = 0;
    650     CConstInt r;
    651     const Type* ct;
    652     if (accept_punct(p, '*')) {
    653       op = '*';
    654     } else if (accept_punct(p, '/')) {
    655       op = '/';
    656     } else if (accept_punct(p, '%')) {
    657       op = '%';
    658     } else {
    659       break;
    660     }
    661     r = cexpr_unary(p, loc);
    662     ct = cint_common_type(p, v.type, r.type);
    663     v = cint_convert(p, v, ct);
    664     r = cint_convert(p, r, ct);
    665     if (op == '*') {
    666       v = cint_mul(p, ct, v, r);
    667     } else {
    668       if (!cint_nonzero(r))
    669         compiler_panic(p->c, loc,
    670                        op == '/' ? "division by zero in constant"
    671                                  : "modulo by zero in constant");
    672       if (cint_signed(p, ct)) {
    673         i64 lv = const_int_as_i64(p, v);
    674         i64 rv = const_int_as_i64(p, r);
    675         v = cint_make_u64(p, ct, op == '/' ? (u64)(lv / rv) : (u64)(lv % rv));
    676       } else {
    677         v = cint_make_u64(p, ct, op == '/' ? v.lo / r.lo : v.lo % r.lo);
    678       }
    679     }
    680   }
    681   return v;
    682 }
    683 static CConstInt cexpr_add(Parser* p, SrcLoc loc) {
    684   CConstInt v = cexpr_mul(p, loc);
    685   for (;;) {
    686     int sub = 0;
    687     CConstInt r;
    688     const Type* ct;
    689     if (accept_punct(p, '+')) {
    690       sub = 0;
    691     } else if (accept_punct(p, '-')) {
    692       sub = 1;
    693     } else {
    694       break;
    695     }
    696     r = cexpr_mul(p, loc);
    697     ct = cint_common_type(p, v.type, r.type);
    698     v = cint_convert(p, v, ct);
    699     r = cint_convert(p, r, ct);
    700     v = sub ? cint_sub(p, ct, v, r) : cint_add(p, ct, v, r);
    701   }
    702   return v;
    703 }
    704 static CConstInt cexpr_shift(Parser* p, SrcLoc loc) {
    705   CConstInt v = cexpr_add(p, loc);
    706   for (;;) {
    707     int left = 0;
    708     CConstInt r;
    709     i64 sh;
    710     const Type* vt;
    711     if (accept_punct(p, P_SHL)) {
    712       left = 1;
    713     } else if (accept_punct(p, P_SHR)) {
    714       left = 0;
    715     } else {
    716       break;
    717     }
    718     r = cexpr_add(p, loc);
    719     vt = cint_promote_type(p, v.type);
    720     v = cint_convert(p, v, vt);
    721     sh = const_int_as_i64(p, r);
    722     if (sh < 0 || sh >= (i64)cint_bits(p, vt))
    723       perr(p, "shift count out of range in constant expression");
    724     if (left) {
    725       if (cint_signed(p, vt) && const_int_as_i64(p, v) < 0)
    726         perr(p, "left shift of negative value in constant expression");
    727       v = cint_shl(p, vt, v, (u32)sh);
    728     } else if (cint_signed(p, vt)) {
    729       v = cint_make_u64(p, vt, (u64)(const_int_as_i64(p, v) >> (u32)sh));
    730     } else {
    731       v = cint_shr_u(p, vt, v, (u32)sh);
    732     }
    733   }
    734   return v;
    735 }
    736 static CConstInt cexpr_rel(Parser* p, SrcLoc loc) {
    737   CConstInt v = cexpr_shift(p, loc);
    738   for (;;) {
    739     int op = 0;
    740     CConstInt r;
    741     const Type* ct;
    742     int res;
    743     if (accept_punct(p, P_LE)) {
    744       op = P_LE;
    745     } else if (accept_punct(p, P_GE)) {
    746       op = P_GE;
    747     } else if (is_punct(&p->cur, '<')) {
    748       advance(p);
    749       op = '<';
    750     } else if (is_punct(&p->cur, '>')) {
    751       advance(p);
    752       op = '>';
    753     } else {
    754       break;
    755     }
    756     r = cexpr_shift(p, loc);
    757     ct = cint_common_type(p, v.type, r.type);
    758     v = cint_convert(p, v, ct);
    759     r = cint_convert(p, r, ct);
    760     if (cint_signed(p, ct)) {
    761       i64 lv = const_int_as_i64(p, v);
    762       i64 rv = const_int_as_i64(p, r);
    763       res = op == P_LE   ? lv <= rv
    764             : op == P_GE ? lv >= rv
    765             : op == '<'  ? lv < rv
    766                          : lv > rv;
    767     } else {
    768       int cmp = cint_cmp_u(v, r);
    769       res = op == P_LE   ? cmp <= 0
    770             : op == P_GE ? cmp >= 0
    771             : op == '<'  ? cmp < 0
    772                          : cmp > 0;
    773     }
    774     v = cint_bool(p, res);
    775   }
    776   return v;
    777 }
    778 static CConstInt cexpr_eq(Parser* p, SrcLoc loc) {
    779   CConstInt v = cexpr_rel(p, loc);
    780   for (;;) {
    781     int ne = 0;
    782     CConstInt r;
    783     const Type* ct;
    784     if (accept_punct(p, P_EQ)) {
    785       ne = 0;
    786     } else if (accept_punct(p, P_NE)) {
    787       ne = 1;
    788     } else {
    789       break;
    790     }
    791     r = cexpr_rel(p, loc);
    792     ct = cint_common_type(p, v.type, r.type);
    793     v = cint_convert(p, v, ct);
    794     r = cint_convert(p, r, ct);
    795     v = cint_bool(p, ne ? !cint_eq(v, r) : cint_eq(v, r));
    796   }
    797   return v;
    798 }
    799 static CConstInt cexpr_band(Parser* p, SrcLoc loc) {
    800   CConstInt v = cexpr_eq(p, loc);
    801   while (is_punct(&p->cur, '&') && !is_punct(&p->cur, P_AND)) {
    802     CConstInt r;
    803     const Type* ct;
    804     advance(p);
    805     r = cexpr_eq(p, loc);
    806     ct = cint_common_type(p, v.type, r.type);
    807     v = cint_convert(p, v, ct);
    808     r = cint_convert(p, r, ct);
    809     v = cint_make_pair(p, ct, v.lo & r.lo, v.hi & r.hi);
    810   }
    811   return v;
    812 }
    813 static CConstInt cexpr_bxor(Parser* p, SrcLoc loc) {
    814   CConstInt v = cexpr_band(p, loc);
    815   while (accept_punct(p, '^')) {
    816     CConstInt r = cexpr_band(p, loc);
    817     const Type* ct = cint_common_type(p, v.type, r.type);
    818     v = cint_convert(p, v, ct);
    819     r = cint_convert(p, r, ct);
    820     v = cint_make_pair(p, ct, v.lo ^ r.lo, v.hi ^ r.hi);
    821   }
    822   return v;
    823 }
    824 static CConstInt cexpr_bor(Parser* p, SrcLoc loc) {
    825   CConstInt v = cexpr_bxor(p, loc);
    826   while (is_punct(&p->cur, '|') && !is_punct(&p->cur, P_OR)) {
    827     CConstInt r;
    828     const Type* ct;
    829     advance(p);
    830     r = cexpr_bxor(p, loc);
    831     ct = cint_common_type(p, v.type, r.type);
    832     v = cint_convert(p, v, ct);
    833     r = cint_convert(p, r, ct);
    834     v = cint_make_pair(p, ct, v.lo | r.lo, v.hi | r.hi);
    835   }
    836   return v;
    837 }
    838 static CConstInt cexpr_land(Parser* p, SrcLoc loc) {
    839   CConstInt v = cexpr_bor(p, loc);
    840   while (accept_punct(p, P_AND)) {
    841     CConstInt r = cexpr_bor(p, loc);
    842     v = cint_bool(p, cint_truth(p, v) && cint_truth(p, r));
    843   }
    844   return v;
    845 }
    846 static CConstInt cexpr_lor(Parser* p, SrcLoc loc) {
    847   CConstInt v = cexpr_land(p, loc);
    848   while (accept_punct(p, P_OR)) {
    849     CConstInt r = cexpr_land(p, loc);
    850     v = cint_bool(p, cint_truth(p, v) || cint_truth(p, r));
    851   }
    852   return v;
    853 }
    854 static CConstInt cexpr_cond(Parser* p, SrcLoc loc) {
    855   CConstInt v = cexpr_lor(p, loc);
    856   if (accept_punct(p, '?')) {
    857     CConstInt then_v = cexpr_cond(p, loc);
    858     CConstInt else_v;
    859     const Type* ct;
    860     expect_punct(p, ':', "':' in constant conditional expression");
    861     else_v = cexpr_cond(p, loc);
    862     ct = cint_common_type(p, then_v.type, else_v.type);
    863     then_v = cint_convert(p, then_v, ct);
    864     else_v = cint_convert(p, else_v, ct);
    865     v = cint_truth(p, v) ? then_v : else_v;
    866   }
    867   return v;
    868 }
    869 
    870 static CConstInt cexpr_unary(Parser* p, SrcLoc loc) {
    871   if (accept_punct(p, '+')) return cexpr_unary(p, loc);
    872   if (accept_punct(p, '-')) {
    873     CConstInt v = cexpr_unary(p, loc);
    874     const Type* pt = cint_promote_type(p, v.type);
    875     v = cint_convert(p, v, pt);
    876     return cint_neg(p, pt, v);
    877   }
    878   if (accept_punct(p, '~')) {
    879     CConstInt v = cexpr_unary(p, loc);
    880     const Type* pt = cint_promote_type(p, v.type);
    881     v = cint_convert(p, v, pt);
    882     return cint_bnot(p, pt, v);
    883   }
    884   if (accept_punct(p, '!'))
    885     return cint_bool(p, !cint_truth(p, cexpr_unary(p, loc)));
    886   if (accept_kw(p, KW_SIZEOF)) {
    887     if (is_punct(&p->cur, '(')) {
    888       Tok n = peek1(p);
    889       if (starts_type_name(p, &n)) {
    890         advance(p);
    891         {
    892           const Type* t = parse_type_name(p);
    893           expect_punct(p, ')', "')' after sizeof type-name");
    894           require_sizeof_type(p, t);
    895           return cint_make_u64(p, ty_size_t(p), c_abi_sizeof(p->abi, t));
    896         }
    897       }
    898     }
    899     parse_unary(p);
    900     {
    901       const Type* ty = pcg_top_type(p);
    902       if (pcg_top_is_bitfield(p)) perr(p, "sizeof bit-field");
    903       require_sizeof_type(p, ty);
    904       i64 sz = (i64)c_abi_sizeof(p->abi, ty);
    905       pcg_drop(p);
    906       return cint_make_u64(p, ty_size_t(p), (u64)sz);
    907     }
    908   }
    909   if (accept_kw(p, KW_ALIGNOF)) {
    910     if (is_punct(&p->cur, '(')) {
    911       Tok n = peek1(p);
    912       if (starts_type_name(p, &n)) {
    913         advance(p);
    914         {
    915           const Type* t = parse_type_name(p);
    916           expect_punct(p, ')', "')' after _Alignof type-name");
    917           return cint_make_u64(p, ty_size_t(p), c_abi_alignof(p->abi, t));
    918         }
    919       }
    920     }
    921     parse_unary(p);
    922     {
    923       const Type* ty = pcg_top_type(p);
    924       i64 al = (i64)c_abi_alignof(p->abi, ty);
    925       pcg_drop(p);
    926       return cint_make_u64(p, ty_size_t(p), (u64)al);
    927     }
    928   }
    929   if (accept_punct(p, '(')) {
    930     if (starts_type_name(p, &p->cur)) {
    931       const Type* t = parse_type_name(p);
    932       expect_punct(p, ')', "')' after cast type-name");
    933       {
    934         const Type* tu = type_unqual(p->pool, t);
    935         if (p->cur.kind == TOK_FLT) {
    936           double fv;
    937           if (!tu || !type_is_int(tu)) {
    938             perr(p, "integer constant expression cast requires integer type");
    939           }
    940           fv = parse_float_literal(p, &p->cur);
    941           advance(p);
    942           return cint_make_u64(p, tu, (u64)(i64)fv);
    943         }
    944         CConstInt v = cexpr_unary(p, loc);
    945         return cint_cast(p, v, t);
    946       }
    947     }
    948     {
    949       CConstInt v = cexpr_cond(p, loc);
    950       expect_punct(p, ')', "')' in constant expression");
    951       return v;
    952     }
    953   }
    954   if (p->cur.kind == TOK_NUM) {
    955     i64 v = parse_int_literal(p, &p->cur);
    956     const Type* ty = int_literal_type(p, &p->cur);
    957     advance(p);
    958     return cint_make_u64(p, ty, (u64)v);
    959   }
    960   if (p->cur.kind == TOK_CHR) {
    961     i64 v = decode_char_literal(p, &p->cur);
    962     const Type* ty = char_literal_type(p, &p->cur);
    963     advance(p);
    964     return cint_make_u64(p, ty, (u64)v);
    965   }
    966   if (p->cur.kind == TOK_IDENT) {
    967     Sym name = p->cur.v.ident;
    968     if (name == p->sym_b_offsetof) {
    969       u32 off = 0;
    970       const Type* root;
    971       advance(p); /* IDENT */
    972       expect_punct(p, '(', "'(' after __builtin_offsetof");
    973       root = parse_type_name(p);
    974       expect_punct(p, ',', "',' in __builtin_offsetof");
    975       (void)offsetof_designator(p, root, &off);
    976       expect_punct(p, ')', "')' after __builtin_offsetof");
    977       return cint_make_u64(p, ty_size_t(p), off);
    978     }
    979     {
    980       SymEntry* e = scope_lookup(p, name);
    981       if (e && e->kind == SEK_ENUM_CST) {
    982         advance(p);
    983         return cint_make_u64(p, e->type ? e->type : ty_int(p),
    984                              (u64)e->v.enum_value);
    985       }
    986     }
    987     compiler_panic(p->c, loc, "non-constant identifier in constant expression");
    988   }
    989   compiler_panic(p->c, loc, "expected constant expression");
    990 }
    991 
    992 CConstInt eval_const_int_typed(Parser* p, SrcLoc loc) {
    993   CConstInt v = cexpr_cond(p, loc);
    994   if (!type_is_int(v.type)) perr(p, "integer constant expression required");
    995   return v;
    996 }
    997 
    998 i64 eval_const_int(Parser* p, SrcLoc loc) {
    999   return const_int_as_i64(p, eval_const_int_typed(p, loc));
   1000 }
   1001 
   1002 /* ============================================================
   1003  * to_rvalue
   1004  * ============================================================ */
   1005 
   1006 static void decay_array_to_pointer(Parser* p, const Type* arr_ty) {
   1007   pcg_decay_array(p, arr_ty);
   1008 }
   1009 
   1010 static FrameSlot vla_size_slot_for_type(VLABound* bounds, const Type* ty) {
   1011   for (VLABound* b = bounds; b; b = b->next) {
   1012     if (b->array_ty == ty) return b->byte_slot;
   1013   }
   1014   return FRAME_SLOT_NONE;
   1015 }
   1016 
   1017 void to_rvalue(Parser* p) {
   1018   const Type* t = pcg_top_type(p);
   1019   int is_lvalue = pcg_top_is_lvalue(p);
   1020   if (t) {
   1021     if (t->kind == TY_ARRAY) {
   1022       decay_array_to_pointer(p, t);
   1023       return;
   1024     }
   1025     if (t->kind == TY_FUNC) {
   1026       pcg_addr(p);
   1027       return;
   1028     }
   1029     if (t->kind == TY_STRUCT || t->kind == TY_UNION) {
   1030       const Type* uty = type_unqual(p->pool, t);
   1031       PcgLvAux* lv = pcg_top_lv_aux(p);
   1032       int materialize =
   1033           is_lvalue && lv &&
   1034           (lv->offset != 0 || lv->scale != 0 || lv->is_subobject ||
   1035            lv->base_kind == PCG_LV_BASE_POINTER_RV);
   1036       p->cg_type_stack[p->cg_type_sp - 1u] = uty;
   1037       if (materialize) {
   1038         pcg_addr(p);
   1039         pcg_deref(p, uty);
   1040       }
   1041       return;
   1042     }
   1043   }
   1044   if (is_lvalue) pcg_load(p);
   1045 }
   1046 
   1047 /* ============================================================
   1048  * coerce_top_to_lvalue (used by assignment / initializers)
   1049  * ============================================================ */
   1050 
   1051 void coerce_top_to_lvalue(Parser* p) {
   1052   const Type* src = pcg_top_type(p);
   1053   const Type* dst = pcg_top2_type(p);
   1054   if (!src || !dst || src == dst) return;
   1055   if (type_is_arith(src) && type_is_arith(dst)) {
   1056     pcg_convert(p, dst);
   1057   } else if (type_is_arith(src) && type_is_ptr(dst)) {
   1058     pcg_convert(p, dst);
   1059   } else if (type_is_ptr(src) && type_is_ptr(dst)) {
   1060     pcg_convert(p, dst);
   1061   }
   1062 }
   1063 
   1064 void coerce_top_to_type(Parser* p, const Type* dst) {
   1065   const Type* src = pcg_top_type(p);
   1066   if (!src || !dst || src == dst) return;
   1067   if (type_is_arith(src) && type_is_arith(dst)) {
   1068     pcg_convert(p, dst);
   1069   } else if (type_is_arith(src) && type_is_ptr(dst)) {
   1070     pcg_convert(p, dst);
   1071   } else if (type_is_ptr(src) && type_is_ptr(dst)) {
   1072     pcg_convert(p, dst);
   1073   }
   1074 }
   1075 
   1076 static const Type* atomic_pointee_type(Parser* p, const Type* ptr_ty,
   1077                                        const char* who) {
   1078   if (!ptr_ty || ptr_ty->kind != TY_PTR) {
   1079     perr(p, "%.*s: pointer argument must have pointer type",
   1080          KIT_SLICE_ARG(kit_slice_cstr(who)));
   1081   }
   1082   return ptr_ty->ptr.pointee;
   1083 }
   1084 
   1085 static const Type* atomic_lock_free_type_for_size(Parser* p, i64 size) {
   1086   const Type* ty = NULL;
   1087   switch (size) {
   1088     case 1:
   1089       ty = type_prim(p->pool, TY_UCHAR);
   1090       break;
   1091     case 2:
   1092       ty = type_prim(p->pool, TY_USHORT);
   1093       break;
   1094     case 4:
   1095       ty = type_prim(p->pool, TY_UINT);
   1096       break;
   1097     case 8:
   1098       ty = type_prim(p->pool, TY_ULLONG);
   1099       break;
   1100     case 16:
   1101       ty = type_prim(p->pool, TY_UINT128);
   1102       break;
   1103     default:
   1104       return NULL;
   1105   }
   1106   return c_abi_sizeof(p->abi, ty) == (u32)size ? ty : NULL;
   1107 }
   1108 
   1109 static int atomic_lock_free_for_const_size(Parser* p, i64 size) {
   1110   if (size <= 0 || size > 16) return 0;
   1111   const Type* ty = atomic_lock_free_type_for_size(p, size);
   1112   return ty ? kit_cg_atomic_is_lock_free(p->c, pcg_mem(p, ty)) : 0;
   1113 }
   1114 
   1115 static KitCgSym builtin_libcall_sym(Parser* p, const char* name,
   1116                                     const Type* fn_ty) {
   1117   KitCgDecl decl;
   1118   Sym source_name = kit_sym_intern(p->pool->c, kit_slice_cstr(name));
   1119   memset(&decl, 0, sizeof decl);
   1120   decl.kind = KIT_CG_DECL_FUNC;
   1121   decl.display_name = source_name;
   1122   decl.linkage_name = kit_cg_c_linkage_name(p->c, source_name);
   1123   decl.type = pcg_tid(p, fn_ty);
   1124   decl.sym.bind = KIT_SB_GLOBAL;
   1125   decl.sym.visibility = KIT_CG_VIS_DEFAULT;
   1126   return kit_cg_decl(p->cg, decl);
   1127 }
   1128 
   1129 static int parse_builtin_mem_call(Parser* p, Sym name, SrcLoc loc) {
   1130   const Type* void_ty = type_void(p->pool);
   1131   const Type* void_ptr_ty = type_ptr(p->pool, void_ty);
   1132   const Type* const_void_ptr_ty =
   1133       type_ptr(p->pool, type_qualified(p->pool, void_ty, Q_CONST));
   1134   const Type* size_ty = ty_size_t(p);
   1135   const Type* int_ty = ty_int(p);
   1136   const Type* params[3];
   1137   const Type* fn_ty;
   1138   const char* libname;
   1139   KitCgSym sym;
   1140 
   1141   advance(p); /* IDENT */
   1142   expect_punct(p, '(', "'(' after builtin");
   1143 
   1144   if (name == p->sym_b_memcpy || name == p->sym_b_memmove) {
   1145     libname = name == p->sym_b_memcpy ? "memcpy" : "memmove";
   1146     parse_assign_expr(p);
   1147     to_rvalue(p);
   1148     coerce_top_to_type(p, void_ptr_ty);
   1149     expect_punct(p, ',', "',' in memory builtin");
   1150     parse_assign_expr(p);
   1151     to_rvalue(p);
   1152     coerce_top_to_type(p, const_void_ptr_ty);
   1153     expect_punct(p, ',', "',' in memory builtin");
   1154     parse_assign_expr(p);
   1155     to_rvalue(p);
   1156     coerce_top_to_type(p, size_ty);
   1157     expect_punct(p, ')', "')' after memory builtin");
   1158     params[0] = void_ptr_ty;
   1159     params[1] = const_void_ptr_ty;
   1160     params[2] = size_ty;
   1161     fn_ty = type_func(p->pool, void_ptr_ty, params, 3, 0);
   1162   } else if (name == p->sym_b_memset) {
   1163     libname = "memset";
   1164     parse_assign_expr(p);
   1165     to_rvalue(p);
   1166     coerce_top_to_type(p, void_ptr_ty);
   1167     expect_punct(p, ',', "',' in __builtin_memset");
   1168     parse_assign_expr(p);
   1169     to_rvalue(p);
   1170     coerce_top_to_type(p, int_ty);
   1171     expect_punct(p, ',', "',' in __builtin_memset");
   1172     parse_assign_expr(p);
   1173     to_rvalue(p);
   1174     coerce_top_to_type(p, size_ty);
   1175     expect_punct(p, ')', "')' after __builtin_memset");
   1176     params[0] = void_ptr_ty;
   1177     params[1] = int_ty;
   1178     params[2] = size_ty;
   1179     fn_ty = type_func(p->pool, void_ptr_ty, params, 3, 0);
   1180   } else {
   1181     libname = "memcmp";
   1182     parse_assign_expr(p);
   1183     to_rvalue(p);
   1184     coerce_top_to_type(p, const_void_ptr_ty);
   1185     expect_punct(p, ',', "',' in __builtin_memcmp");
   1186     parse_assign_expr(p);
   1187     to_rvalue(p);
   1188     coerce_top_to_type(p, const_void_ptr_ty);
   1189     expect_punct(p, ',', "',' in __builtin_memcmp");
   1190     parse_assign_expr(p);
   1191     to_rvalue(p);
   1192     coerce_top_to_type(p, size_ty);
   1193     expect_punct(p, ')', "')' after __builtin_memcmp");
   1194     params[0] = const_void_ptr_ty;
   1195     params[1] = const_void_ptr_ty;
   1196     params[2] = size_ty;
   1197     fn_ty = type_func(p->pool, int_ty, params, 3, 0);
   1198   }
   1199 
   1200   sym = pcg_emit_enabled(p) ? builtin_libcall_sym(p, libname, fn_ty)
   1201                             : KIT_CG_SYM_NONE;
   1202   pcg_set_loc(p, loc);
   1203   pcg_call_symbol(p, sym, 3, fn_ty);
   1204   return 1;
   1205 }
   1206 
   1207 static int parse_builtin_clear_cache_call(Parser* p, Sym name, SrcLoc loc) {
   1208   const Type* void_ty = type_void(p->pool);
   1209   const Type* void_ptr_ty = type_ptr(p->pool, void_ty);
   1210   const Type* params[2];
   1211   const Type* fn_ty;
   1212   KitCgSym sym;
   1213 
   1214   if (name != p->sym_b_clear_cache) return 0;
   1215 
   1216   advance(p); /* IDENT */
   1217   expect_punct(p, '(', "'(' after __builtin___clear_cache");
   1218   parse_assign_expr(p);
   1219   to_rvalue(p);
   1220   coerce_top_to_type(p, void_ptr_ty);
   1221   expect_punct(p, ',', "',' in __builtin___clear_cache");
   1222   parse_assign_expr(p);
   1223   to_rvalue(p);
   1224   coerce_top_to_type(p, void_ptr_ty);
   1225   expect_punct(p, ')', "')' after __builtin___clear_cache");
   1226 
   1227   /* Instruction-cache coherency is automatic on x86, and wasm has no separate
   1228    * I-cache to flush (the engine handles code installation), so
   1229    * __builtin___clear_cache is a no-op on those targets — matching GCC/Clang.
   1230    * Emitting the __clear_cache libcall there would reference an undefined
   1231    * symbol. Targets that need explicit coherency (ARM, RISC-V) keep the call.
   1232    * The argument expressions are still evaluated for their side effects. The
   1233    * coherency fact is a backend capability, not an arch identity. */
   1234   if (kit_cg_target_backend_features(p->c) & KIT_CG_BACKEND_ICACHE_COHERENT) {
   1235     pcg_drop(p);
   1236     pcg_drop(p);
   1237     pcg_push_int(p, 0, ty_int(p));
   1238     return 1;
   1239   }
   1240 
   1241   params[0] = void_ptr_ty;
   1242   params[1] = void_ptr_ty;
   1243   fn_ty = type_func(p->pool, void_ty, params, 2, 0);
   1244   sym = pcg_emit_enabled(p) ? builtin_libcall_sym(p, "__clear_cache", fn_ty)
   1245                             : KIT_CG_SYM_NONE;
   1246   pcg_set_loc(p, loc);
   1247   pcg_call_symbol(p, sym, 2, fn_ty);
   1248   pcg_push_int(p, 0, ty_int(p));
   1249   return 1;
   1250 }
   1251 
   1252 static MemOrder parse_atomic_mem_order(Parser* p) {
   1253   if (p->cur.kind == TOK_NUM) {
   1254     return (MemOrder)eval_const_int(p, p->cur.loc);
   1255   }
   1256   parse_assign_expr(p);
   1257   to_rvalue(p);
   1258   pcg_drop(p);
   1259   return MO_SEQ_CST;
   1260 }
   1261 
   1262 /* ============================================================
   1263  * Builtin call handling
   1264  * ============================================================ */
   1265 
   1266 static int offsetof_find_member(Parser* p, const Type* rec_ty, Sym mname,
   1267                                 const Type** out_ty, u32* out_off) {
   1268   const ABIRecordLayout* L;
   1269   rec_ty = type_unqual(p->pool, rec_ty);
   1270   if (!rec_ty || (rec_ty->kind != TY_STRUCT && rec_ty->kind != TY_UNION))
   1271     return 0;
   1272   L = c_abi_record_layout(p->abi, p->pool, rec_ty);
   1273   if (!L) return 0;
   1274   for (u16 i = 0; i < rec_ty->rec.nfields; ++i) {
   1275     const Field* f = &rec_ty->rec.fields[i];
   1276     if (f->name == mname && mname != 0) {
   1277       *out_ty = f->type;
   1278       *out_off = L->fields[i].offset;
   1279       return 1;
   1280     }
   1281   }
   1282   for (u16 i = 0; i < rec_ty->rec.nfields; ++i) {
   1283     const Field* f = &rec_ty->rec.fields[i];
   1284     const Type* fty = type_unqual(p->pool, f->type);
   1285     const Type* nested_ty = NULL;
   1286     u32 nested_off = 0;
   1287     if (!((f->flags & FIELD_ANON) &&
   1288           (fty->kind == TY_STRUCT || fty->kind == TY_UNION))) {
   1289       continue;
   1290     }
   1291     if (offsetof_find_member(p, fty, mname, &nested_ty, &nested_off)) {
   1292       *out_ty = nested_ty;
   1293       *out_off = L->fields[i].offset + nested_off;
   1294       return 1;
   1295     }
   1296   }
   1297   return 0;
   1298 }
   1299 
   1300 static const Type* offsetof_designator(Parser* p, const Type* base, u32* off) {
   1301   const Type* cur = base;
   1302   if (p->cur.kind != TOK_IDENT || ident_kw(p, p->cur.v.ident) != KW_NONE) {
   1303     perr(p, "expected member name in __builtin_offsetof");
   1304   }
   1305   for (;;) {
   1306     if (cur->kind == TY_STRUCT || cur->kind == TY_UNION) {
   1307       Sym mname = p->cur.v.ident;
   1308       const Type* mty = NULL;
   1309       u32 moff = 0;
   1310       if (!offsetof_find_member(p, cur, mname, &mty, &moff))
   1311         perr(p, "no such member in __builtin_offsetof");
   1312       advance(p);
   1313       *off += moff;
   1314       cur = mty;
   1315     } else if (cur->kind == TY_ARRAY) {
   1316       /* fall through to bracket branch */
   1317     } else {
   1318       perr(p, "__builtin_offsetof step into non-aggregate");
   1319     }
   1320     if (is_punct(&p->cur, '.')) {
   1321       advance(p);
   1322       if (p->cur.kind != TOK_IDENT || ident_kw(p, p->cur.v.ident) != KW_NONE) {
   1323         perr(p, "expected member name after '.'");
   1324       }
   1325       continue;
   1326     }
   1327     if (is_punct(&p->cur, '[')) {
   1328       advance(p);
   1329       i64 idx = eval_const_int(p, p->cur.loc);
   1330       expect_punct(p, ']', "']' in __builtin_offsetof");
   1331       if (cur->kind != TY_ARRAY) {
   1332         perr(p, "__builtin_offsetof '[' on non-array");
   1333       }
   1334       *off += (u32)((i64)c_abi_sizeof(p->abi, cur->arr.elem) * idx);
   1335       cur = cur->arr.elem;
   1336       continue;
   1337     }
   1338     break;
   1339   }
   1340   return cur;
   1341 }
   1342 
   1343 typedef struct BuiltinOverflowInfo {
   1344   KitCgIntrinsic intrin;
   1345   TypeKind type_kind;
   1346   const char* name;
   1347 } BuiltinOverflowInfo;
   1348 
   1349 static int sym_eq_cstr(Parser* p, Sym sym, const char* want) {
   1350   KitSlice got = kit_sym_str(p->pool->c, sym);
   1351   return got.s && kit_slice_eq_cstr(got, want);
   1352 }
   1353 
   1354 static int builtin_overflow_info(Parser* p, Sym name,
   1355                                  BuiltinOverflowInfo* out) {
   1356   static const BuiltinOverflowInfo infos[] = {
   1357       {KIT_CG_INTRIN_SADD_OVERFLOW, TY_INT, "__builtin_sadd_overflow"},
   1358       {KIT_CG_INTRIN_SADD_OVERFLOW, TY_LONG, "__builtin_saddl_overflow"},
   1359       {KIT_CG_INTRIN_SADD_OVERFLOW, TY_LLONG, "__builtin_saddll_overflow"},
   1360       {KIT_CG_INTRIN_UADD_OVERFLOW, TY_UINT, "__builtin_uadd_overflow"},
   1361       {KIT_CG_INTRIN_UADD_OVERFLOW, TY_ULONG, "__builtin_uaddl_overflow"},
   1362       {KIT_CG_INTRIN_UADD_OVERFLOW, TY_ULLONG, "__builtin_uaddll_overflow"},
   1363       {KIT_CG_INTRIN_SSUB_OVERFLOW, TY_INT, "__builtin_ssub_overflow"},
   1364       {KIT_CG_INTRIN_SSUB_OVERFLOW, TY_LONG, "__builtin_ssubl_overflow"},
   1365       {KIT_CG_INTRIN_SSUB_OVERFLOW, TY_LLONG, "__builtin_ssubll_overflow"},
   1366       {KIT_CG_INTRIN_USUB_OVERFLOW, TY_UINT, "__builtin_usub_overflow"},
   1367       {KIT_CG_INTRIN_USUB_OVERFLOW, TY_ULONG, "__builtin_usubl_overflow"},
   1368       {KIT_CG_INTRIN_USUB_OVERFLOW, TY_ULLONG, "__builtin_usubll_overflow"},
   1369       {KIT_CG_INTRIN_SMUL_OVERFLOW, TY_INT, "__builtin_smul_overflow"},
   1370       {KIT_CG_INTRIN_SMUL_OVERFLOW, TY_LONG, "__builtin_smull_overflow"},
   1371       {KIT_CG_INTRIN_SMUL_OVERFLOW, TY_LLONG, "__builtin_smulll_overflow"},
   1372       {KIT_CG_INTRIN_UMUL_OVERFLOW, TY_UINT, "__builtin_umul_overflow"},
   1373       {KIT_CG_INTRIN_UMUL_OVERFLOW, TY_ULONG, "__builtin_umull_overflow"},
   1374       {KIT_CG_INTRIN_UMUL_OVERFLOW, TY_ULLONG, "__builtin_umulll_overflow"},
   1375   };
   1376   size_t i;
   1377   for (i = 0; i < sizeof(infos) / sizeof(infos[0]); ++i) {
   1378     if (sym_eq_cstr(p, name, infos[i].name)) {
   1379       if (out) *out = infos[i];
   1380       return 1;
   1381     }
   1382   }
   1383   return 0;
   1384 }
   1385 
   1386 static FrameSlot builtin_tmp_slot(Parser* p, const Type* ty) {
   1387   FrameSlotDesc fsd;
   1388   memset(&fsd, 0, sizeof fsd);
   1389   fsd.type = ty;
   1390   fsd.size = c_abi_sizeof(p->abi, ty);
   1391   fsd.align = c_abi_alignof(p->abi, ty);
   1392   fsd.kind = FS_LOCAL;
   1393   return pcg_local(p, &fsd);
   1394 }
   1395 
   1396 static int parse_builtin_overflow_call(Parser* p, Sym name, SrcLoc loc) {
   1397   BuiltinOverflowInfo info;
   1398   const Type* op_ty;
   1399   const Type* ptr_ty;
   1400   const Type* out_ty;
   1401   const Type* bool_ty;
   1402   FrameSlot ptr_slot;
   1403   FrameSlot ov_slot;
   1404   if (!builtin_overflow_info(p, name, &info)) return 0;
   1405 
   1406   op_ty = type_prim(p->pool, info.type_kind);
   1407   bool_ty = type_prim(p->pool, TY_BOOL);
   1408 
   1409   advance(p); /* IDENT */
   1410   expect_punct(p, '(', "'(' after overflow builtin");
   1411   parse_assign_expr(p);
   1412   to_rvalue(p);
   1413   coerce_top_to_type(p, op_ty);
   1414   expect_punct(p, ',', "',' in overflow builtin");
   1415   parse_assign_expr(p);
   1416   to_rvalue(p);
   1417   coerce_top_to_type(p, op_ty);
   1418   expect_punct(p, ',', "',' in overflow builtin");
   1419   parse_assign_expr(p);
   1420   to_rvalue(p);
   1421   ptr_ty = pcg_top_type(p);
   1422   if (!ptr_ty || ptr_ty->kind != TY_PTR) {
   1423     perr(p, "overflow builtin result argument must be a pointer");
   1424   }
   1425   out_ty = ptr_ty->ptr.pointee;
   1426   if (!type_compatible(type_unqual(p->pool, out_ty), op_ty)) {
   1427     perr(p, "overflow builtin result pointer type mismatch");
   1428   }
   1429   expect_punct(p, ')', "')' after overflow builtin");
   1430 
   1431   ptr_slot = builtin_tmp_slot(p, ptr_ty);
   1432   pcg_push_local_typed(p, ptr_slot, ptr_ty);
   1433   pcg_swap(p);
   1434   pcg_store(p);
   1435   pcg_drop(p);
   1436 
   1437   pcg_set_loc(p, loc);
   1438   if (pcg_emit_enabled(p)) {
   1439     kit_cg_intrinsic(p->cg, info.intrin, 2, pcg_tid(p, op_ty));
   1440   }
   1441   pcg_drop_type(p);
   1442   pcg_drop_type(p);
   1443   pcg_push_type(p, op_ty);
   1444   pcg_push_type(p, bool_ty);
   1445 
   1446   ov_slot = builtin_tmp_slot(p, bool_ty);
   1447   pcg_push_local_typed(p, ov_slot, bool_ty);
   1448   pcg_swap(p);
   1449   pcg_store(p);
   1450   pcg_drop(p);
   1451 
   1452   pcg_push_local_typed(p, ptr_slot, ptr_ty);
   1453   pcg_load(p);
   1454   pcg_deref(p, out_ty);
   1455   pcg_swap(p);
   1456   pcg_store(p);
   1457   pcg_drop(p);
   1458 
   1459   pcg_push_local_typed(p, ov_slot, bool_ty);
   1460   pcg_load(p);
   1461   return 1;
   1462 }
   1463 
   1464 static int parse_builtin_isnan_call(Parser* p, Sym name, SrcLoc loc) {
   1465   const Type* arg_ty;
   1466   if (name != p->sym_b_isnan) return 0;
   1467 
   1468   advance(p); /* IDENT */
   1469   expect_punct(p, '(', "'(' after __builtin_isnan");
   1470   parse_assign_expr(p);
   1471   to_rvalue(p);
   1472   arg_ty = pcg_top_type(p);
   1473   if (!type_is_fp(arg_ty)) {
   1474     perr(p, "__builtin_isnan argument must have floating type");
   1475   }
   1476   expect_punct(p, ')', "')' after __builtin_isnan");
   1477 
   1478   pcg_set_loc(p, loc);
   1479   pcg_dup(p);
   1480   pcg_cmp(p, CMP_NE);
   1481   return 1;
   1482 }
   1483 
   1484 /* C99 floating comparison builtins (Route A). The five relational forms map
   1485  * directly to ordered FP predicates (NaN -> false): isless/islessequal/
   1486  * isgreater/isgreaterequal -> OLT/OLE/OGT/OGE (the same predicates the bare
   1487  * `< <= > >=` operators produce, but as the explicit quiet macros), and
   1488  * islessgreater -> ONE (ordered-and-not-equal). isunordered has no standalone
   1489  * predicate in the CmpOp enum, so it is synthesized as (a != a) || (b != b)
   1490  * using the unordered self-compare that __builtin_isnan already relies on. */
   1491 static int parse_builtin_fp_cmp_call(Parser* p, Sym name, SrcLoc loc) {
   1492   CmpOp cop;
   1493   int is_unordered = 0;
   1494   const Type* common;
   1495 
   1496   if (name == p->sym_b_isless) {
   1497     cop = CMP_OLT_F;
   1498   } else if (name == p->sym_b_islessequal) {
   1499     cop = CMP_OLE_F;
   1500   } else if (name == p->sym_b_isgreater) {
   1501     cop = CMP_OGT_F;
   1502   } else if (name == p->sym_b_isgreaterequal) {
   1503     cop = CMP_OGE_F;
   1504   } else if (name == p->sym_b_islessgreater) {
   1505     cop = CMP_ONE_F;
   1506   } else if (name == p->sym_b_isunordered) {
   1507     cop = CMP_OEQ_F; /* unused; isunordered is synthesized below */
   1508     is_unordered = 1;
   1509   } else {
   1510     return 0;
   1511   }
   1512 
   1513   advance(p); /* IDENT */
   1514   expect_punct(p, '(', "'(' after floating comparison builtin");
   1515   parse_assign_expr(p);
   1516   to_rvalue(p);
   1517   if (!type_is_fp(pcg_top_type(p))) {
   1518     perr(p, "floating comparison builtin requires floating arguments");
   1519   }
   1520   expect_punct(p, ',', "',' between floating comparison builtin arguments");
   1521   parse_assign_expr(p);
   1522   to_rvalue(p);
   1523   if (!type_is_fp(pcg_top_type(p))) {
   1524     perr(p, "floating comparison builtin requires floating arguments");
   1525   }
   1526   expect_punct(p, ')', "')' after floating comparison builtin");
   1527 
   1528   /* Bring both operands to a common floating type so the compare (and the
   1529    * synthesized self-compares) see matching widths, mirroring the bare
   1530    * relational path (parse_rel). */
   1531   common = common_fp_type(p, pcg_top2_type(p), pcg_top_type(p));
   1532   coerce_fp_cmp_operands(p, common);
   1533 
   1534   pcg_set_loc(p, loc);
   1535   if (!is_unordered) {
   1536     pcg_cmp(p, cop);
   1537     return 1;
   1538   }
   1539 
   1540   /* isunordered(a, b) == isnan(a) || isnan(b). Stash both operands, then OR the
   1541    * two unordered self-compares (each yields the 0/1 int isnan result). */
   1542   {
   1543     FrameSlot slot_a = builtin_tmp_slot(p, common);
   1544     FrameSlot slot_b = builtin_tmp_slot(p, common);
   1545     /* stack: [a, b] */
   1546     pcg_push_local_typed(p, slot_b, common);
   1547     pcg_swap(p);
   1548     pcg_store(p);
   1549     pcg_drop(p);
   1550     /* stack: [a] */
   1551     pcg_push_local_typed(p, slot_a, common);
   1552     pcg_swap(p);
   1553     pcg_store(p);
   1554     pcg_drop(p);
   1555     /* stack: [] */
   1556     pcg_push_local_typed(p, slot_a, common);
   1557     pcg_load(p);
   1558     pcg_dup(p);
   1559     pcg_cmp(p, CMP_NE); /* isnan(a): unordered not-equal */
   1560     pcg_push_local_typed(p, slot_b, common);
   1561     pcg_load(p);
   1562     pcg_dup(p);
   1563     pcg_cmp(p, CMP_NE); /* isnan(b) */
   1564     pcg_binop(p, BO_OR);
   1565   }
   1566   return 1;
   1567 }
   1568 
   1569 static const Type* builtin_math_fp_type(Parser* p, Sym name) {
   1570   if (name == p->sym_b_fabsf || name == p->sym_b_inff ||
   1571       name == p->sym_b_huge_valf) {
   1572     return type_prim(p->pool, TY_FLOAT);
   1573   }
   1574   if (name == p->sym_b_fabsl || name == p->sym_b_infl ||
   1575       name == p->sym_b_huge_vall) {
   1576     return type_prim(p->pool, TY_LDOUBLE);
   1577   }
   1578   return type_prim(p->pool, TY_DOUBLE);
   1579 }
   1580 
   1581 static int parse_builtin_inf_call(Parser* p, Sym name, SrcLoc loc) {
   1582   const Type* ty;
   1583   if (name != p->sym_b_inf && name != p->sym_b_inff && name != p->sym_b_infl &&
   1584       name != p->sym_b_huge_val && name != p->sym_b_huge_valf &&
   1585       name != p->sym_b_huge_vall) {
   1586     return 0;
   1587   }
   1588 
   1589   ty = builtin_math_fp_type(p, name);
   1590   advance(p); /* IDENT */
   1591   expect_punct(p, '(', "'(' after floating builtin");
   1592   expect_punct(p, ')', "')' after floating builtin");
   1593   pcg_set_loc(p, loc);
   1594   pcg_push_float(p, __builtin_inf(), ty);
   1595   return 1;
   1596 }
   1597 
   1598 static int parse_builtin_fabs_call(Parser* p, Sym name, SrcLoc loc) {
   1599   const Type* ty;
   1600   FrameSlot slot;
   1601   CGLabel L_nonneg;
   1602   CGLabel L_nonzero;
   1603   if (name != p->sym_b_fabs && name != p->sym_b_fabsf &&
   1604       name != p->sym_b_fabsl) {
   1605     return 0;
   1606   }
   1607 
   1608   ty = builtin_math_fp_type(p, name);
   1609   advance(p); /* IDENT */
   1610   expect_punct(p, '(', "'(' after __builtin_fabs");
   1611   parse_assign_expr(p);
   1612   to_rvalue(p);
   1613   if (!type_is_fp(pcg_top_type(p))) {
   1614     perr(p, "__builtin_fabs argument must have floating type");
   1615   }
   1616   coerce_top_to_type(p, ty);
   1617   expect_punct(p, ')', "')' after __builtin_fabs");
   1618 
   1619   slot = builtin_tmp_slot(p, ty);
   1620   pcg_push_local_typed(p, slot, ty);
   1621   pcg_swap(p);
   1622   pcg_store(p);
   1623   pcg_drop(p);
   1624 
   1625   pcg_set_loc(p, loc);
   1626   pcg_push_local_typed(p, slot, ty);
   1627   pcg_load(p);
   1628   pcg_push_float(p, 0.0, ty);
   1629   pcg_cmp(p, CMP_LT_F);
   1630   L_nonneg = pcg_label_new(p);
   1631   pcg_branch_false(p, L_nonneg);
   1632   pcg_push_local_typed(p, slot, ty);
   1633   pcg_push_local_typed(p, slot, ty);
   1634   pcg_load(p);
   1635   pcg_unop(p, UO_NEG);
   1636   pcg_store(p);
   1637   pcg_drop(p);
   1638   pcg_label_place(p, L_nonneg);
   1639   pcg_push_local_typed(p, slot, ty);
   1640   pcg_load(p);
   1641   pcg_push_float(p, 0.0, ty);
   1642   pcg_cmp(p, CMP_EQ);
   1643   L_nonzero = pcg_label_new(p);
   1644   pcg_branch_false(p, L_nonzero);
   1645   pcg_push_local_typed(p, slot, ty);
   1646   pcg_push_float(p, 0.0, ty);
   1647   pcg_store(p);
   1648   pcg_drop(p);
   1649   pcg_label_place(p, L_nonzero);
   1650   pcg_push_local_typed(p, slot, ty);
   1651   pcg_load(p);
   1652   return 1;
   1653 }
   1654 
   1655 static int parse_builtin_abs_call(Parser* p, Sym name, SrcLoc loc) {
   1656   KitSlice name_sl = kit_sym_str(p->pool->c, name);
   1657   size_t nlen = name_sl.len;
   1658   const char* nm = name_sl.s;
   1659   const char* libname = NULL;
   1660   const Type* int_ty = NULL;
   1661   const Type* params[1];
   1662   const Type* fn_ty;
   1663   KitCgSym sym;
   1664 
   1665   if (nm && nlen == 13u && memcmp(nm, "__builtin_abs", 13u) == 0) {
   1666     libname = "abs";
   1667     int_ty = type_prim(p->pool, TY_INT);
   1668   } else if (nm && nlen == 14u && memcmp(nm, "__builtin_labs", 14u) == 0) {
   1669     libname = "labs";
   1670     int_ty = type_prim(p->pool, TY_LONG);
   1671   } else if (nm && nlen == 15u && memcmp(nm, "__builtin_llabs", 15u) == 0) {
   1672     libname = "llabs";
   1673     int_ty = type_prim(p->pool, TY_LLONG);
   1674   } else {
   1675     return 0;
   1676   }
   1677 
   1678   advance(p); /* IDENT */
   1679   expect_punct(p, '(', "'(' after abs builtin");
   1680   parse_assign_expr(p);
   1681   to_rvalue(p);
   1682   coerce_top_to_type(p, int_ty);
   1683   expect_punct(p, ')', "')' after abs builtin");
   1684 
   1685   params[0] = int_ty;
   1686   fn_ty = type_func(p->pool, int_ty, params, 1, 0);
   1687   sym = pcg_emit_enabled(p) ? builtin_libcall_sym(p, libname, fn_ty)
   1688                             : KIT_CG_SYM_NONE;
   1689   pcg_set_loc(p, loc);
   1690   pcg_call_symbol(p, sym, 1, fn_ty);
   1691   return 1;
   1692 }
   1693 
   1694 static int parse_kit_syscall_call(Parser* p, Sym name, SrcLoc loc) {
   1695   const Type* long_ty;
   1696   u32 arity = 0;
   1697   u32 nargs;
   1698   int found = 0;
   1699 
   1700   for (u32 i = 0; i < 7u; ++i) {
   1701     if (name == p->sym_kit_syscall[i]) {
   1702       arity = i;
   1703       found = 1;
   1704       break;
   1705     }
   1706   }
   1707   if (!found) return 0;
   1708 
   1709   long_ty = type_prim(p->pool, TY_LONG);
   1710   nargs = arity + 1u; /* syscall number plus payload args */
   1711   advance(p);         /* IDENT */
   1712   expect_punct(p, '(', "'(' after __kit_syscall");
   1713   for (u32 i = 0; i < nargs; ++i) {
   1714     if (i) expect_punct(p, ',', "',' in __kit_syscall");
   1715     parse_assign_expr(p);
   1716     to_rvalue(p);
   1717     coerce_top_to_type(p, long_ty);
   1718   }
   1719   expect_punct(p, ')', "')' after __kit_syscall");
   1720 
   1721   pcg_set_loc(p, loc);
   1722   pcg_syscall(p, nargs, long_ty);
   1723   return 1;
   1724 }
   1725 
   1726 static int try_parse_builtin_call(Parser* p) {
   1727   Sym name = p->cur.v.ident;
   1728   SrcLoc loc = p->cur.loc;
   1729 
   1730   if (parse_kit_syscall_call(p, name, loc)) return 1;
   1731 
   1732   if (name == p->sym_b_memcpy || name == p->sym_b_memmove ||
   1733       name == p->sym_b_memcmp || name == p->sym_b_memset) {
   1734     return parse_builtin_mem_call(p, name, loc);
   1735   }
   1736 
   1737   if (parse_builtin_overflow_call(p, name, loc)) return 1;
   1738   if (parse_builtin_isnan_call(p, name, loc)) return 1;
   1739   if (parse_builtin_fp_cmp_call(p, name, loc)) return 1;
   1740   if (parse_builtin_inf_call(p, name, loc)) return 1;
   1741   if (parse_builtin_fabs_call(p, name, loc)) return 1;
   1742   if (parse_builtin_abs_call(p, name, loc)) return 1;
   1743   if (parse_builtin_clear_cache_call(p, name, loc)) return 1;
   1744 
   1745   if (name != p->sym_b_alloca && name != p->sym_b_ctz &&
   1746       name != p->sym_b_ctzl && name != p->sym_b_ctzll && name != p->sym_b_clz &&
   1747       name != p->sym_b_clzl && name != p->sym_b_clzll &&
   1748       name != p->sym_b_trap && name != p->sym_b_unreachable &&
   1749       name != p->sym_b_return_address && name != p->sym_b_frame_address &&
   1750       name != p->sym_b_expect && name != p->sym_b_offsetof &&
   1751       name != p->sym_b_va_start && name != p->sym_b_va_arg &&
   1752       name != p->sym_b_va_end && name != p->sym_b_va_copy &&
   1753       name != p->sym_a_load_n && name != p->sym_a_store_n &&
   1754       name != p->sym_a_exchange_n && name != p->sym_a_fetch_add &&
   1755       name != p->sym_a_fetch_sub && name != p->sym_a_fetch_and &&
   1756       name != p->sym_a_fetch_or && name != p->sym_a_fetch_xor &&
   1757       name != p->sym_a_fetch_nand && name != p->sym_a_cas_n &&
   1758       name != p->sym_a_always_lock_free && name != p->sym_a_is_lock_free &&
   1759       name != p->sym_a_thread_fence && name != p->sym_a_signal_fence) {
   1760     return 0;
   1761   }
   1762   advance(p); /* IDENT */
   1763   expect_punct(p, '(', "'(' after builtin");
   1764 
   1765   if (name == p->sym_b_offsetof) {
   1766     const Type* root = parse_type_name(p);
   1767     expect_punct(p, ',', "',' in __builtin_offsetof");
   1768     u32 off = 0;
   1769     (void)offsetof_designator(p, root, &off);
   1770     expect_punct(p, ')', "')' after __builtin_offsetof");
   1771     pcg_push_int(p, (i64)off, ty_size_t(p));
   1772     return 1;
   1773   }
   1774 
   1775   if (name == p->sym_b_expect) {
   1776     parse_assign_expr(p);
   1777     to_rvalue(p);
   1778     expect_punct(p, ',', "',' in __builtin_expect");
   1779     parse_assign_expr(p);
   1780     pcg_drop(p);
   1781     expect_punct(p, ')', "')' after __builtin_expect");
   1782     return 1;
   1783   }
   1784 
   1785   if (name == p->sym_b_alloca) {
   1786     parse_assign_expr(p);
   1787     to_rvalue(p);
   1788     expect_punct(p, ')', "')' after __builtin_alloca");
   1789     pcg_set_loc(p, loc);
   1790     pcg_alloca(p);
   1791     return 1;
   1792   }
   1793 
   1794   if (name == p->sym_b_ctz || name == p->sym_b_ctzl || name == p->sym_b_ctzll) {
   1795     parse_assign_expr(p);
   1796     to_rvalue(p);
   1797     expect_punct(p, ')', "')' after __builtin_ctz");
   1798     pcg_set_loc(p, loc);
   1799     pcg_intrinsic_unary_to_int(p, INTRIN_CTZ);
   1800     return 1;
   1801   }
   1802 
   1803   if (name == p->sym_b_clz || name == p->sym_b_clzl || name == p->sym_b_clzll) {
   1804     parse_assign_expr(p);
   1805     to_rvalue(p);
   1806     expect_punct(p, ')', "')' after __builtin_clz");
   1807     pcg_set_loc(p, loc);
   1808     /* The operand carries its own type, which drives the sf bit on
   1809      * aarch64 / REX.W on x64 / sf on rv64. Whether the caller used the
   1810      * `l` / `ll` suffix only changes the C-level type the user wrote;
   1811      * kit picks the instruction width from the value type. */
   1812     pcg_intrinsic_unary_to_int(p, INTRIN_CLZ);
   1813     return 1;
   1814   }
   1815 
   1816   if (name == p->sym_b_trap || name == p->sym_b_unreachable) {
   1817     expect_punct(p, ')', "')' after __builtin_trap/unreachable");
   1818     pcg_set_loc(p, loc);
   1819     pcg_intrinsic_void(
   1820         p, name == p->sym_b_trap ? INTRIN_TRAP : INTRIN_UNREACHABLE);
   1821     /* Both are noreturn at the C level. Push a dummy `int 0` so callers
   1822      * that consume an expression value (e.g. ternary, comma) don't see
   1823      * an empty stack — the dead value will be folded out. */
   1824     pcg_push_int(p, 0, ty_int(p));
   1825     return 1;
   1826   }
   1827 
   1828   if (name == p->sym_b_return_address || name == p->sym_b_frame_address) {
   1829     /* GCC requires the level to be an integer constant expression. */
   1830     int is_return = (name == p->sym_b_return_address);
   1831     i64 level = eval_const_int(p, p->cur.loc);
   1832     expect_punct(p, ')',
   1833                  "')' after __builtin_return_address/__builtin_frame_address");
   1834     if (level < 0)
   1835       perr(p, "__builtin_%s: level must be non-negative",
   1836            is_return ? "return_address" : "frame_address");
   1837     pcg_set_loc(p, loc);
   1838     pcg_frame_or_return_address(p, is_return, (u32)level);
   1839     return 1;
   1840   }
   1841 
   1842   if (name == p->sym_b_va_start) {
   1843     parse_assign_expr(p);
   1844     pcg_addr(p);
   1845     expect_punct(p, ',', "',' in __builtin_va_start");
   1846     parse_assign_expr(p);
   1847     pcg_drop(p);
   1848     expect_punct(p, ')', "')' after __builtin_va_start");
   1849     pcg_set_loc(p, loc);
   1850     pcg_va_start(p);
   1851     pcg_push_int(p, 0, ty_int(p));
   1852     return 1;
   1853   }
   1854 
   1855   if (name == p->sym_b_va_end) {
   1856     parse_assign_expr(p);
   1857     pcg_addr(p);
   1858     expect_punct(p, ')', "')' after __builtin_va_end");
   1859     pcg_set_loc(p, loc);
   1860     pcg_va_end(p);
   1861     pcg_push_int(p, 0, ty_int(p));
   1862     return 1;
   1863   }
   1864 
   1865   if (name == p->sym_b_va_copy) {
   1866     parse_assign_expr(p);
   1867     pcg_addr(p);
   1868     expect_punct(p, ',', "',' in __builtin_va_copy");
   1869     parse_assign_expr(p);
   1870     pcg_addr(p);
   1871     expect_punct(p, ')', "')' after __builtin_va_copy");
   1872     pcg_set_loc(p, loc);
   1873     pcg_va_copy(p);
   1874     pcg_push_int(p, 0, ty_int(p));
   1875     return 1;
   1876   }
   1877 
   1878   if (name == p->sym_b_va_arg) {
   1879     parse_assign_expr(p);
   1880     pcg_addr(p);
   1881     expect_punct(p, ',', "',' in __builtin_va_arg");
   1882     const Type* ty = parse_type_name(p);
   1883     expect_punct(p, ')', "')' after __builtin_va_arg");
   1884     pcg_set_loc(p, loc);
   1885     pcg_va_arg(p, ty);
   1886     return 1;
   1887   }
   1888 
   1889   if (name == p->sym_a_load_n) {
   1890     parse_assign_expr(p);
   1891     to_rvalue(p);
   1892     expect_punct(p, ',', "',' in __atomic_load_n");
   1893     MemOrder ord = parse_atomic_mem_order(p);
   1894     expect_punct(p, ')', "')' after __atomic_load_n");
   1895     pcg_set_loc(p, loc);
   1896     pcg_atomic_load(p, ord);
   1897     return 1;
   1898   }
   1899 
   1900   if (name == p->sym_a_store_n) {
   1901     parse_assign_expr(p);
   1902     to_rvalue(p);
   1903     const Type* val_ty =
   1904         atomic_pointee_type(p, pcg_top_type(p), "__atomic_store_n");
   1905     expect_punct(p, ',', "',' in __atomic_store_n");
   1906     parse_assign_expr(p);
   1907     to_rvalue(p);
   1908     coerce_top_to_type(p, val_ty);
   1909     expect_punct(p, ',', "',' in __atomic_store_n");
   1910     MemOrder ord = parse_atomic_mem_order(p);
   1911     expect_punct(p, ')', "')' after __atomic_store_n");
   1912     pcg_set_loc(p, loc);
   1913     pcg_atomic_store(p, ord);
   1914     pcg_push_int(p, 0, ty_int(p));
   1915     return 1;
   1916   }
   1917 
   1918   if (name == p->sym_a_thread_fence || name == p->sym_a_signal_fence) {
   1919     MemOrder ord = parse_atomic_mem_order(p);
   1920     expect_punct(p, ')', "')' after atomic fence");
   1921     pcg_set_loc(p, loc);
   1922     pcg_fence(p, ord);
   1923     pcg_push_int(p, 0, ty_int(p));
   1924     return 1;
   1925   }
   1926 
   1927   if (name == p->sym_a_always_lock_free || name == p->sym_a_is_lock_free) {
   1928     i64 size = eval_const_int(p, p->cur.loc);
   1929     expect_punct(p, ',', "',' in atomic lock-free builtin");
   1930     parse_assign_expr(p);
   1931     to_rvalue(p);
   1932     pcg_drop(p);
   1933     expect_punct(p, ')', "')' after atomic lock-free builtin");
   1934     pcg_push_int(p, atomic_lock_free_for_const_size(p, size), ty_int(p));
   1935     return 1;
   1936   }
   1937 
   1938   if (name == p->sym_a_cas_n) {
   1939     parse_assign_expr(p);
   1940     to_rvalue(p); /* ptr */
   1941     const Type* obj_ty =
   1942         atomic_pointee_type(p, pcg_top_type(p), "__atomic_compare_exchange_n");
   1943     expect_punct(p, ',', "',' in __atomic_compare_exchange_n");
   1944 
   1945     parse_assign_expr(p);
   1946     to_rvalue(p); /* &expected */
   1947     const Type* eptr_ty = pcg_top_type(p);
   1948     if (!eptr_ty || eptr_ty->kind != TY_PTR) {
   1949       perr(p, "__atomic_compare_exchange_n: arg 2 must be a pointer");
   1950     }
   1951     const Type* val_ty = eptr_ty->ptr.pointee;
   1952     if (val_ty != obj_ty) {
   1953       val_ty = obj_ty;
   1954     }
   1955 
   1956     FrameSlotDesc fsd;
   1957     memset(&fsd, 0, sizeof fsd);
   1958     fsd.type = eptr_ty;
   1959     fsd.size = 8;
   1960     fsd.align = 8;
   1961     fsd.kind = FS_LOCAL;
   1962     FrameSlot eslot = pcg_local(p, &fsd);
   1963     pcg_push_local_typed(p, eslot, eptr_ty);
   1964     pcg_swap(p);
   1965     pcg_store(p);
   1966     pcg_drop(p);
   1967 
   1968     pcg_push_local_typed(p, eslot, eptr_ty);
   1969     pcg_load(p);
   1970     pcg_deref(p, val_ty);
   1971     pcg_load(p);
   1972 
   1973     expect_punct(p, ',', "',' in __atomic_compare_exchange_n");
   1974     parse_assign_expr(p);
   1975     to_rvalue(p); /* desired */
   1976     coerce_top_to_type(p, val_ty);
   1977     expect_punct(p, ',', "',' in __atomic_compare_exchange_n");
   1978 
   1979     (void)eval_const_int(p, p->cur.loc); /* weak */
   1980     expect_punct(p, ',', "',' in __atomic_compare_exchange_n");
   1981     MemOrder succ = parse_atomic_mem_order(p);
   1982     expect_punct(p, ',', "',' in __atomic_compare_exchange_n");
   1983     MemOrder fail = parse_atomic_mem_order(p);
   1984     expect_punct(p, ')', "')' after __atomic_compare_exchange_n");
   1985 
   1986     pcg_set_loc(p, loc);
   1987     pcg_atomic_cas(p, succ, fail);
   1988 
   1989     const Type* ok_ty = pcg_top_type(p);
   1990     FrameSlotDesc okd;
   1991     memset(&okd, 0, sizeof okd);
   1992     okd.type = ok_ty;
   1993     okd.size = 4;
   1994     okd.align = 4;
   1995     okd.kind = FS_LOCAL;
   1996     FrameSlot okslot = pcg_local(p, &okd);
   1997     pcg_push_local_typed(p, okslot, ok_ty);
   1998     pcg_swap(p);
   1999     pcg_store(p);
   2000     pcg_drop(p);
   2001 
   2002     FrameSlotDesc pd;
   2003     memset(&pd, 0, sizeof pd);
   2004     pd.type = val_ty;
   2005     pd.size = c_abi_sizeof(p->abi, val_ty);
   2006     pd.align = c_abi_alignof(p->abi, val_ty);
   2007     pd.kind = FS_LOCAL;
   2008     FrameSlot pslot = pcg_local(p, &pd);
   2009     pcg_push_local_typed(p, pslot, val_ty);
   2010     pcg_swap(p);
   2011     pcg_store(p);
   2012     pcg_drop(p);
   2013 
   2014     pcg_push_local_typed(p, okslot, ok_ty);
   2015     pcg_load(p);
   2016     CGLabel L_done = pcg_label_new(p);
   2017     pcg_branch_true(p, L_done);
   2018     pcg_push_local_typed(p, eslot, eptr_ty);
   2019     pcg_load(p);
   2020     pcg_deref(p, val_ty);
   2021     pcg_push_local_typed(p, pslot, val_ty);
   2022     pcg_load(p);
   2023     pcg_store(p);
   2024     pcg_drop(p);
   2025     pcg_label_place(p, L_done);
   2026 
   2027     pcg_push_local_typed(p, okslot, ok_ty);
   2028     pcg_load(p);
   2029     return 1;
   2030   }
   2031 
   2032   AtomicOp op;
   2033   if (name == p->sym_a_exchange_n)
   2034     op = AO_XCHG;
   2035   else if (name == p->sym_a_fetch_add)
   2036     op = AO_ADD;
   2037   else if (name == p->sym_a_fetch_sub)
   2038     op = AO_SUB;
   2039   else if (name == p->sym_a_fetch_and)
   2040     op = AO_AND;
   2041   else if (name == p->sym_a_fetch_or)
   2042     op = AO_OR;
   2043   else if (name == p->sym_a_fetch_xor)
   2044     op = AO_XOR;
   2045   else if (name == p->sym_a_fetch_nand)
   2046     op = AO_NAND;
   2047   else {
   2048     perr(p, "internal: unhandled builtin");
   2049   }
   2050 
   2051   parse_assign_expr(p);
   2052   to_rvalue(p);
   2053   const Type* val_ty =
   2054       atomic_pointee_type(p, pcg_top_type(p), "__atomic read-modify-write");
   2055   expect_punct(p, ',', "',' in atomic builtin");
   2056   parse_assign_expr(p);
   2057   to_rvalue(p);
   2058   coerce_top_to_type(p, val_ty);
   2059   expect_punct(p, ',', "',' in atomic builtin");
   2060   MemOrder ord = parse_atomic_mem_order(p);
   2061   expect_punct(p, ')', "')' after atomic builtin");
   2062   pcg_set_loc(p, loc);
   2063   pcg_atomic_rmw(p, op, ord);
   2064   return 1;
   2065 }
   2066 
   2067 /* ============================================================
   2068  * parse_primary, parse_postfix, parse_unary
   2069  * ============================================================ */
   2070 
   2071 static void parse_primary(Parser* p) {
   2072   Tok t = p->cur;
   2073   if (t.kind == TOK_NUM) {
   2074     i64 v = parse_int_literal(p, &t);
   2075     const Type* lty = int_literal_type(p, &t);
   2076     advance(p);
   2077     pcg_push_int(p, v, lty);
   2078     return;
   2079   }
   2080   if (t.kind == TOK_FLT) {
   2081     double v = parse_float_literal(p, &t);
   2082     const Type* lty = float_literal_type(p, &t);
   2083     advance(p);
   2084     pcg_push_float(p, v, lty);
   2085     return;
   2086   }
   2087   if (is_punct(&t, '(')) {
   2088     advance(p);
   2089     parse_expr(p);
   2090     expect_punct(p, ')', "')'");
   2091     return;
   2092   }
   2093   if (t.kind == TOK_IDENT) {
   2094     SymEntry* e;
   2095     if (ident_kw(p, t.v.ident) != KW_NONE) {
   2096       perr(p, "unexpected keyword in expression");
   2097     }
   2098     {
   2099       Tok n = peek1(p);
   2100       if (is_punct(&n, '(') && try_parse_builtin_call(p)) return;
   2101     }
   2102     /* try_parse_builtin_call may rewrite the current ident in-place
   2103      * (e.g. __builtin_memcpy → memcpy) and return 0, asking us to
   2104      * resume normal lookup with the rewritten name. */
   2105     t = p->cur;
   2106     /* C99 §6.4.2.2: `__func__` inside a function-body acts as
   2107      *   static const char __func__[] = "<function-name>";
   2108      * GCC also exposes `__FUNCTION__` and `__PRETTY_FUNCTION__` with
   2109      * the same value. We synthesize the string lazily — the symbol
   2110      * lives in .rodata and the resulting type is `char[N+1]` (with the
   2111      * trailing NUL). */
   2112     if (t.v.ident == p->sym_func || t.v.ident == p->sym_func_gcc ||
   2113         t.v.ident == p->sym_pretty_func_gcc) {
   2114       if (p->cur_func_name == 0) {
   2115         compiler_panic(
   2116             p->c, t.loc, "'%.*s' used outside a function",
   2117             KIT_SLICE_ARG(kit_slice_cstr(t.v.ident == p->sym_func ? "__func__"
   2118                                          : t.v.ident == p->sym_func_gcc
   2119                                              ? "__FUNCTION__"
   2120                                              : "__PRETTY_FUNCTION__")));
   2121       }
   2122       KitSlice fn_name_sl = kit_sym_str(p->pool->c, p->cur_func_name);
   2123       size_t nlen = fn_name_sl.len;
   2124       const char* fn_name = fn_name_sl.s;
   2125       Heap* h = kit_compiler_context(p->c)->heap;
   2126       u8* bytes = (u8*)h->alloc(h, nlen + 1u, 1u);
   2127       for (size_t i = 0; i < nlen; ++i) bytes[i] = (u8)fn_name[i];
   2128       bytes[nlen] = 0;
   2129       ObjSymId sym = emit_string_to_rodata(p, bytes, nlen + 1u);
   2130       h->free(h, bytes, 0);
   2131       advance(p);
   2132       const Type* char_ty = type_prim(p->pool, TY_CHAR);
   2133       const Type* arr_ty = type_array(p->pool, char_ty, (u32)(nlen + 1u), 0);
   2134       pcg_push_global(p, sym, arr_ty);
   2135       return;
   2136     }
   2137     e = scope_lookup(p, t.v.ident);
   2138     if (!e) {
   2139       KitSlice ident_sl = kit_sym_str(p->pool->c, t.v.ident);
   2140       size_t nlen = ident_sl.len;
   2141       const char* nm = ident_sl.s;
   2142       compiler_panic(p->c, t.loc, "undeclared identifier '%.*s'", (int)nlen,
   2143                      nm ? nm : "?");
   2144     }
   2145     advance(p);
   2146     switch (e->kind) {
   2147       case SEK_LOCAL:
   2148         pcg_push_local_typed(p, e->v.slot, e->type);
   2149         if (e->storage == DS_REGISTER) pcg_set_top_register(p);
   2150         if (e->vla_byte_slot != FRAME_SLOT_NONE) {
   2151           p->last_pushed_vla_slot = e->vla_byte_slot;
   2152         }
   2153         if (e->vla_bounds) {
   2154           p->last_pushed_vla_bounds = e->vla_bounds;
   2155         }
   2156         return;
   2157       case SEK_GLOBAL:
   2158       case SEK_FUNC:
   2159         pcg_push_global(p, e->v.sym, e->type);
   2160         return;
   2161       case SEK_ENUM_CST:
   2162         pcg_push_int(p, e->v.enum_value, e->type);
   2163         return;
   2164       case SEK_TYPEDEF:
   2165       default:
   2166         perr(p, "identifier is not a value");
   2167     }
   2168   }
   2169   if (t.kind == TOK_CHR) {
   2170     i64 v = decode_char_literal(p, &t);
   2171     const Type* lty = char_literal_type(p, &t);
   2172     advance(p);
   2173     pcg_push_int(p, v, lty);
   2174     return;
   2175   }
   2176   if (t.kind == TOK_STR) {
   2177     size_t n = 0;
   2178     u8* bytes = decode_string_literal(p, &t, &n);
   2179     const Type* elem_ty = string_literal_elem_type(p, &t);
   2180     u32 elem_size = c_abi_sizeof(p->abi, elem_ty);
   2181     ObjSymId sym = emit_string_literal_to_rodata(p, bytes, n, elem_ty);
   2182     kit_compiler_context(p->c)->heap->free(kit_compiler_context(p->c)->heap,
   2183                                            bytes, 0);
   2184     advance(p);
   2185     {
   2186       const Type* arr_ty =
   2187           type_array(p->pool, elem_ty, elem_size ? (u32)(n / elem_size) : 0, 0);
   2188       pcg_push_global(p, sym, arr_ty);
   2189     }
   2190     return;
   2191   }
   2192   perr(p, "expected expression");
   2193 }
   2194 
   2195 static int find_record_member_path(Parser* p, const Type* rec_ty, Sym mname,
   2196                                    const Type** out_ty, u32 path[2],
   2197                                    u32* out_depth, const Field** out_field) {
   2198   const ABIRecordLayout* L;
   2199   rec_ty = type_unqual(p->pool, rec_ty);
   2200   if (!rec_ty || (rec_ty->kind != TY_STRUCT && rec_ty->kind != TY_UNION))
   2201     return 0;
   2202   L = c_abi_record_layout(p->abi, p->pool, rec_ty);
   2203   if (!L) return 0;
   2204   for (u16 i = 0; i < rec_ty->rec.nfields; ++i) {
   2205     const Field* f = &rec_ty->rec.fields[i];
   2206     if (f->name == mname && mname != 0) {
   2207       *out_ty = f->type;
   2208       path[0] = i;
   2209       *out_depth = 1;
   2210       if (out_field) *out_field = f;
   2211       return 1;
   2212     }
   2213     {
   2214       const Type* fty = type_unqual(p->pool, f->type);
   2215       if (!((f->flags & FIELD_ANON) &&
   2216             (fty->kind == TY_STRUCT || fty->kind == TY_UNION))) {
   2217         continue;
   2218       }
   2219       const ABIRecordLayout* IL = c_abi_record_layout(p->abi, p->pool, fty);
   2220       if (!IL) continue;
   2221       for (u16 j = 0; j < fty->rec.nfields; ++j) {
   2222         const Field* ff = &fty->rec.fields[j];
   2223         if (ff->name == mname && mname != 0) {
   2224           *out_ty = ff->type;
   2225           path[0] = i;
   2226           path[1] = j;
   2227           *out_depth = 2;
   2228           if (out_field) *out_field = ff;
   2229           return 1;
   2230         }
   2231       }
   2232     }
   2233   }
   2234   return 0;
   2235 }
   2236 
   2237 static void cg_record_member_path(Parser* p, const Type* member_ty,
   2238                                   const u32* path, u32 depth,
   2239                                   const Field* field) {
   2240   /* Walk the path locally to compute the cumulative byte offset; pull
   2241    * bit-field metadata from the final ABIFieldLayout when applicable. The
   2242    * field/index/addr_offset CG ops are gone — pcg_lv_member folds the offset
   2243    * (and any bit-field meta) onto the TOS lvalue's aux for the next memop. */
   2244   const Type* cur_ty = pcg_top_type(p);
   2245   i64 total_offset = 0;
   2246   u16 bf_off = 0;
   2247   u16 bf_w = 0;
   2248   u32 bf_ss = 0;
   2249   cur_ty = type_unqual(p->pool, cur_ty);
   2250   for (u32 i = 0; i < depth; ++i) {
   2251     const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, cur_ty);
   2252     const ABIFieldLayout* fl;
   2253     const Field* f;
   2254     if (!L) break;
   2255     fl = &L->fields[path[i]];
   2256     f = &cur_ty->rec.fields[path[i]];
   2257     total_offset += (i64)fl->offset;
   2258     if (i + 1u == depth && (f->flags & FIELD_BITFIELD)) {
   2259       bf_off = fl->bit_offset;
   2260       bf_w = fl->bit_width;
   2261       bf_ss = fl->storage_size;
   2262     }
   2263     cur_ty = type_unqual(p->pool, f->type);
   2264   }
   2265   (void)field;
   2266   pcg_lv_member(p, total_offset, member_ty, bf_off, bf_w, bf_ss);
   2267 }
   2268 
   2269 static void parse_postfix(Parser* p) {
   2270   VLABound* vla_bounds;
   2271   p->last_pushed_vla_slot = FRAME_SLOT_NONE;
   2272   p->last_pushed_vla_bounds = NULL;
   2273   parse_primary(p);
   2274   vla_bounds = p->last_pushed_vla_bounds;
   2275   for (;;) {
   2276     Tok t = p->cur;
   2277     if (is_punct(&t, P_INC)) {
   2278       advance(p);
   2279       if (!pcg_top_is_modifiable_lvalue(p)) {
   2280         perr(p, "increment/decrement requires modifiable lvalue");
   2281       }
   2282       if (!c_type_is_scalar(pcg_top_type(p))) {
   2283         perr(p, "increment/decrement requires scalar operand");
   2284       }
   2285       pcg_inc_dec(p, BO_IADD, /*post=*/1);
   2286       continue;
   2287     }
   2288     if (is_punct(&t, P_DEC)) {
   2289       advance(p);
   2290       if (!pcg_top_is_modifiable_lvalue(p)) {
   2291         perr(p, "increment/decrement requires modifiable lvalue");
   2292       }
   2293       if (!c_type_is_scalar(pcg_top_type(p))) {
   2294         perr(p, "increment/decrement requires scalar operand");
   2295       }
   2296       pcg_inc_dec(p, BO_ISUB, /*post=*/1);
   2297       continue;
   2298     }
   2299     if (is_punct(&t, '(')) {
   2300       const Type* top = pcg_top_type(p);
   2301       const Type* fn_type;
   2302       if (top && top->kind == TY_FUNC) {
   2303         fn_type = top;
   2304       } else if (top && top->kind == TY_PTR && top->ptr.pointee &&
   2305                  top->ptr.pointee->kind == TY_FUNC) {
   2306         fn_type = top->ptr.pointee;
   2307         if (pcg_top_is_lvalue(p)) pcg_load(p);
   2308       } else {
   2309         perr(p, "called object is not a function");
   2310       }
   2311       advance(p); /* '(' */
   2312       u32 nargs = 0;
   2313       if (!is_punct(&p->cur, ')')) {
   2314         for (;;) {
   2315           const Type* param_ty =
   2316               (nargs < fn_type->fn.nparams) ? fn_type->fn.params[nargs] : NULL;
   2317           parse_assign_expr(p);
   2318           to_rvalue(p);
   2319           if (param_ty) {
   2320             CSemCheck chk = c_sem_check_assignment(
   2321                 p->pool, param_ty, pcg_top_type(p), C_SEM_ASSIGN_EXPR);
   2322             if (!chk.ok)
   2323               perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message)));
   2324             coerce_top_to_type(p, param_ty);
   2325           }
   2326           ++nargs;
   2327           if (!accept_punct(p, ',')) break;
   2328         }
   2329       }
   2330       expect_punct(p, ')', "')' after argument list");
   2331       if (fn_type->fn.nparams != nargs && !fn_type->fn.variadic) {
   2332         perr(p, "wrong number of arguments");
   2333       }
   2334       if (fn_type->fn.variadic && nargs < fn_type->fn.nparams) {
   2335         perr(p, "too few arguments to variadic function");
   2336       }
   2337       pcg_call(p, nargs, fn_type);
   2338       if (fn_type->fn.ret && fn_type->fn.ret->kind == TY_VOID) {
   2339         pcg_push_int(p, 0, ty_int(p));
   2340       }
   2341       continue;
   2342     }
   2343     if (is_punct(&t, '[')) {
   2344       const Type* lt0 = pcg_top_type(p);
   2345       advance(p); /* '[' */
   2346       if (lt0 && lt0->kind == TY_ARRAY) {
   2347         decay_array_to_pointer(p, lt0);
   2348       } else if (lt0 && lt0->kind == TY_PTR) {
   2349         if (pcg_top_is_lvalue(p)) pcg_load(p);
   2350       }
   2351       parse_expr(p);
   2352       {
   2353         const Type* it0 = pcg_top_type(p);
   2354         if (it0 && it0->kind == TY_ARRAY) {
   2355           decay_array_to_pointer(p, it0);
   2356         } else {
   2357           to_rvalue(p);
   2358         }
   2359       }
   2360       expect_punct(p, ']', "']' after subscript");
   2361       {
   2362         const Type* lt = pcg_top2_type(p);
   2363         const Type* it = pcg_top_type(p);
   2364         const Type* elem;
   2365         if (lt && lt->kind == TY_PTR && type_is_int(it)) {
   2366           elem = lt->ptr.pointee;
   2367         } else if (it && it->kind == TY_PTR && type_is_int(lt)) {
   2368           pcg_swap(p);
   2369           elem = it->ptr.pointee;
   2370         } else {
   2371           perr(p, "invalid subscript: needs one pointer and one integer");
   2372         }
   2373         if (!elem) perr(p, "subscript on incomplete pointee");
   2374         coerce_top_to_type(p, c_abi_ptrdiff_type(p->abi, p->pool));
   2375         {
   2376           FrameSlot elem_vla_slot = vla_size_slot_for_type(vla_bounds, elem);
   2377           if (elem_vla_slot != FRAME_SLOT_NONE) {
   2378             pcg_push_local_typed(p, elem_vla_slot, ty_size_t(p));
   2379             pcg_load(p);
   2380             pcg_binop(p, BO_IMUL);
   2381             pcg_binop(p, BO_IADD);
   2382             pcg_deref(p, elem);
   2383             p->last_pushed_vla_slot = elem_vla_slot;
   2384             p->last_pushed_vla_bounds = vla_bounds;
   2385           } else {
   2386             u32 elem_size = c_abi_sizeof(p->abi, elem);
   2387             pcg_lv_subscript(p, elem_size, elem);
   2388           }
   2389         }
   2390       }
   2391       continue;
   2392     }
   2393     if (is_punct(&t, '.')) {
   2394       const Type* lt = pcg_top_type(p);
   2395       Sym mname;
   2396       const Type* mty = NULL;
   2397       const Field* mf = NULL;
   2398       u32 path[2];
   2399       u32 depth = 0;
   2400       advance(p); /* '.' */
   2401       if (!lt || (lt->kind != TY_STRUCT && lt->kind != TY_UNION)) {
   2402         perr(p,
   2403              "request for member in something that is not a struct or union");
   2404       }
   2405       if (p->cur.kind != TOK_IDENT || ident_kw(p, p->cur.v.ident) != KW_NONE) {
   2406         perr(p, "expected member name after '.'");
   2407       }
   2408       mname = p->cur.v.ident;
   2409       advance(p);
   2410       lt = type_unqual(p->pool, lt);
   2411       if (!find_record_member_path(p, lt, mname, &mty, path, &depth, &mf))
   2412         perr(p, "no such member");
   2413       cg_record_member_path(p, mty, path, depth, mf);
   2414       continue;
   2415     }
   2416     if (is_punct(&t, P_ARROW)) {
   2417       const Type* lt0;
   2418       const Type* rec_ty;
   2419       Sym mname;
   2420       const Type* mty = NULL;
   2421       const Field* mf = NULL;
   2422       u32 path[2];
   2423       u32 depth = 0;
   2424       advance(p); /* `->` */
   2425       to_rvalue(p);
   2426       lt0 = pcg_top_type(p);
   2427       if (!lt0 || lt0->kind != TY_PTR) {
   2428         perr(p, "'->' requires a pointer operand");
   2429       }
   2430       rec_ty = type_unqual(p->pool, lt0->ptr.pointee);
   2431       if (!rec_ty || (rec_ty->kind != TY_STRUCT && rec_ty->kind != TY_UNION)) {
   2432         perr(p, "'->' on pointer to non-struct/union");
   2433       }
   2434       if (p->cur.kind != TOK_IDENT || ident_kw(p, p->cur.v.ident) != KW_NONE) {
   2435         perr(p, "expected member name after '->'");
   2436       }
   2437       mname = p->cur.v.ident;
   2438       advance(p);
   2439       if (!find_record_member_path(p, rec_ty, mname, &mty, path, &depth, &mf))
   2440         perr(p, "no such member");
   2441       pcg_deref(p, rec_ty);
   2442       cg_record_member_path(p, mty, path, depth, mf);
   2443       continue;
   2444     }
   2445     break;
   2446   }
   2447 }
   2448 
   2449 void parse_unary(Parser* p) {
   2450   Tok t = p->cur;
   2451   if (is_punct(&t, '(')) {
   2452     Tok n = peek1(p);
   2453     if (starts_type_name(p, &n)) {
   2454       const Type* dst;
   2455       const Type* src;
   2456       advance(p); /* '(' */
   2457       dst = parse_type_name(p);
   2458       expect_punct(p, ')', "')' after type-name");
   2459       if (is_punct(&p->cur, '{')) {
   2460         FrameSlotDesc fsd;
   2461         FrameSlot slot;
   2462         const Type* lit_ty = dst;
   2463         if (lit_ty && lit_ty->kind == TY_ARRAY && lit_ty->arr.incomplete) {
   2464           lit_ty = complete_incomplete_array(p, lit_ty);
   2465         }
   2466         memset(&fsd, 0, sizeof fsd);
   2467         fsd.type = lit_ty;
   2468         fsd.size = c_abi_sizeof(p->abi, lit_ty);
   2469         fsd.align = c_abi_alignof(p->abi, lit_ty);
   2470         fsd.kind = FS_LOCAL;
   2471         fsd.flags = FSF_NONE;
   2472         slot = pcg_local(p, &fsd);
   2473         if (lit_ty && (lit_ty->kind == TY_ARRAY || lit_ty->kind == TY_STRUCT ||
   2474                        lit_ty->kind == TY_UNION)) {
   2475           init_at(p, slot, lit_ty, 0, lit_ty);
   2476         } else {
   2477           init_at(p, slot, lit_ty, 0, lit_ty);
   2478         }
   2479         pcg_push_local_typed(p, slot, lit_ty);
   2480         return;
   2481       }
   2482       parse_unary(p);
   2483       to_rvalue(p);
   2484       src = pcg_top_type(p);
   2485       if (dst && dst->kind == TY_VOID) {
   2486         pcg_drop(p);
   2487         pcg_push_int(p, 0, ty_int(p));
   2488         return;
   2489       }
   2490       if (!c_type_is_scalar(dst) || !c_type_is_scalar(src)) {
   2491         perr(p, "cast requires scalar type");
   2492       }
   2493       if (src && src->kind == TY_PTR && dst->kind == TY_PTR) {
   2494         pcg_convert(p, dst);
   2495         return;
   2496       }
   2497       pcg_convert(p, dst);
   2498       return;
   2499     }
   2500   }
   2501   if (is_punct(&t, '+')) {
   2502     advance(p);
   2503     parse_unary(p);
   2504     to_rvalue(p);
   2505     require_arith(p, pcg_top_type(p), "unary '+'");
   2506     return;
   2507   }
   2508   if (is_punct(&t, '-')) {
   2509     advance(p);
   2510     parse_unary(p);
   2511     to_rvalue(p);
   2512     require_arith(p, pcg_top_type(p), "unary '-'");
   2513     pcg_unop(p, UO_NEG);
   2514     return;
   2515   }
   2516   if (is_punct(&t, '!')) {
   2517     advance(p);
   2518     parse_unary(p);
   2519     to_rvalue(p);
   2520     require_scalar(p, pcg_top_type(p), "unary '!'");
   2521     pcg_push_int(p, 0, ty_int(p));
   2522     pcg_cmp(p, CMP_EQ);
   2523     return;
   2524   }
   2525   if (is_punct(&t, '~')) {
   2526     advance(p);
   2527     parse_unary(p);
   2528     to_rvalue(p);
   2529     if (!type_is_int(pcg_top_type(p))) {
   2530       perr(p, "unary '~' requires integer operand");
   2531     }
   2532     pcg_unop(p, UO_BNOT);
   2533     return;
   2534   }
   2535   if (is_punct(&t, P_AND)) {
   2536     /* GNU labels-as-values: `&&label` yields the label's address as void*. */
   2537     Sym name;
   2538     SrcLoc loc;
   2539     advance(p); /* '&&' */
   2540     if (p->cur.kind != TOK_IDENT || ident_kw(p, p->cur.v.ident) != KW_NONE) {
   2541       perr(p, "expected label name after '&&'");
   2542     }
   2543     name = p->cur.v.ident;
   2544     loc = p->cur.loc;
   2545     advance(p);
   2546     pcg_push_label_addr(p, take_label_addr(p, name, loc));
   2547     return;
   2548   }
   2549   if (is_punct(&t, '&')) {
   2550     advance(p);
   2551     parse_unary(p);
   2552     if (!pcg_top_is_lvalue(p) &&
   2553         !(pcg_top_type(p) && pcg_top_type(p)->kind == TY_FUNC)) {
   2554       perr(p, "address-of requires lvalue operand");
   2555     }
   2556     if (pcg_top_is_bitfield(p)) perr(p, "cannot take address of bit-field");
   2557     if (pcg_top_is_register(p))
   2558       perr(p, "cannot take address of register object");
   2559     pcg_addr(p);
   2560     return;
   2561   }
   2562   if (is_punct(&t, '*')) {
   2563     const Type* pty;
   2564     const Type* pointee;
   2565     advance(p);
   2566     parse_unary(p);
   2567     to_rvalue(p);
   2568     pty = pcg_top_type(p);
   2569     if (!pty || pty->kind != TY_PTR) {
   2570       perr(p, "indirection requires pointer operand");
   2571     }
   2572     pointee = pty->ptr.pointee;
   2573     if (pointee && pointee->kind == TY_VOID) {
   2574       perr(p, "dereferencing pointer to incomplete type");
   2575     }
   2576     pcg_deref(p, pointee);
   2577     return;
   2578   }
   2579   if (is_punct(&t, P_INC) || is_punct(&t, P_DEC)) {
   2580     BinOp bop = is_punct(&t, P_INC) ? BO_IADD : BO_ISUB;
   2581     advance(p);
   2582     parse_unary(p);
   2583     if (!pcg_top_is_modifiable_lvalue(p)) {
   2584       perr(p, "increment/decrement requires modifiable lvalue");
   2585     }
   2586     if (!c_type_is_scalar(pcg_top_type(p))) {
   2587       perr(p, "increment/decrement requires scalar operand");
   2588     }
   2589     pcg_inc_dec(p, bop, /*post=*/0);
   2590     return;
   2591   }
   2592   if (is_kw(p, &t, KW_SIZEOF)) {
   2593     const Type* ty = NULL;
   2594     FrameSlot vla_slot = FRAME_SLOT_NONE;
   2595     advance(p);
   2596     if (is_punct(&p->cur, '(')) {
   2597       Tok n = peek1(p);
   2598       if (starts_type_name(p, &n)) {
   2599         advance(p);
   2600         ty = parse_type_name(p);
   2601         expect_punct(p, ')', "')'");
   2602       } else {
   2603         p->last_pushed_vla_slot = FRAME_SLOT_NONE;
   2604         pcg_codegen_suppress_push(p);
   2605         parse_unary(p);
   2606         ty = pcg_top_type(p);
   2607         vla_slot = p->last_pushed_vla_slot;
   2608         if (pcg_top_is_bitfield(p)) perr(p, "sizeof bit-field");
   2609         pcg_drop(p);
   2610         pcg_codegen_suppress_pop(p);
   2611       }
   2612     } else {
   2613       p->last_pushed_vla_slot = FRAME_SLOT_NONE;
   2614       pcg_codegen_suppress_push(p);
   2615       parse_unary(p);
   2616       ty = pcg_top_type(p);
   2617       vla_slot = p->last_pushed_vla_slot;
   2618       if (pcg_top_is_bitfield(p)) perr(p, "sizeof bit-field");
   2619       pcg_drop(p);
   2620       pcg_codegen_suppress_pop(p);
   2621     }
   2622     if (vla_slot != FRAME_SLOT_NONE) {
   2623       pcg_push_local_typed(p, vla_slot, ty_size_t(p));
   2624       pcg_load(p);
   2625     } else {
   2626       require_sizeof_type(p, ty);
   2627       pcg_push_int(p, (i64)c_abi_sizeof(p->abi, ty), ty_size_t(p));
   2628     }
   2629     return;
   2630   }
   2631   if (is_kw(p, &t, KW_GENERIC)) {
   2632     advance(p);
   2633     expect_punct(p, '(', "'('");
   2634     pcg_codegen_suppress_push(p);
   2635     parse_assign_expr(p);
   2636     to_rvalue(p);
   2637     const Type* ctl_ty = pcg_top_type(p);
   2638     pcg_drop(p);
   2639     pcg_codegen_suppress_pop(p);
   2640     expect_punct(p, ',', "','");
   2641     int emitted = 0;
   2642     Tok* default_buf = NULL;
   2643     u32 default_len = 0;
   2644     const Type** assoc_types = NULL;
   2645     u32 assoc_n = 0;
   2646     u32 assoc_cap = 0;
   2647     int saw_default = 0;
   2648     for (;;) {
   2649       const Type* assoc_ty = NULL;
   2650       int is_default = 0;
   2651       if (is_kw(p, &p->cur, KW_DEFAULT)) {
   2652         advance(p);
   2653         is_default = 1;
   2654         if (saw_default) perr(p, "_Generic has duplicate default association");
   2655         saw_default = 1;
   2656       } else {
   2657         assoc_ty = parse_type_name(p);
   2658         {
   2659           const Type* au = type_unqual(p->pool, assoc_ty);
   2660           for (u32 ai = 0; ai < assoc_n; ++ai) {
   2661             if (type_compatible(assoc_types[ai], au)) {
   2662               perr(p, "_Generic association type is duplicated");
   2663             }
   2664           }
   2665           if (assoc_n == assoc_cap) {
   2666             u32 nc = assoc_cap ? assoc_cap * 2u : 8u;
   2667             const Type** nb = arena_array(p->pool->arena, const Type*, nc);
   2668             if (!nb) perr(p, "out of memory recording _Generic associations");
   2669             if (assoc_n) memcpy(nb, assoc_types, assoc_n * sizeof(*nb));
   2670             assoc_types = nb;
   2671             assoc_cap = nc;
   2672           }
   2673           assoc_types[assoc_n++] = au;
   2674         }
   2675       }
   2676       expect_punct(p, ':', "':' in _Generic association");
   2677       int take = 0;
   2678       if (!emitted && !is_default && ctl_ty && assoc_ty &&
   2679           type_compatible(type_unqual(p->pool, ctl_ty),
   2680                           type_unqual(p->pool, assoc_ty))) {
   2681         take = 1;
   2682       }
   2683       if (take) {
   2684         parse_assign_expr(p);
   2685         emitted = 1;
   2686       } else if (is_default && !default_buf) {
   2687         u32 cap = 16;
   2688         Tok* buf = arena_array(p->pool->arena, Tok, cap);
   2689         u32 len = 0;
   2690         int paren_depth = 0, brack_depth = 0, brace_depth = 0;
   2691         while (p->cur.kind != TOK_EOF) {
   2692           if (paren_depth == 0 && brack_depth == 0 && brace_depth == 0) {
   2693             if (is_punct(&p->cur, ',') || is_punct(&p->cur, ')')) break;
   2694           }
   2695           if (len == cap) {
   2696             u32 new_cap = cap * 2;
   2697             Tok* nv = arena_array(p->pool->arena, Tok, new_cap);
   2698             if (!nv) perr(p, "out of memory recording _Generic default");
   2699             memcpy(nv, buf, len * sizeof(Tok));
   2700             buf = nv;
   2701             cap = new_cap;
   2702           }
   2703           buf[len++] = p->cur;
   2704           if (is_punct(&p->cur, '('))
   2705             ++paren_depth;
   2706           else if (is_punct(&p->cur, ')'))
   2707             --paren_depth;
   2708           else if (is_punct(&p->cur, '['))
   2709             ++brack_depth;
   2710           else if (is_punct(&p->cur, ']'))
   2711             --brack_depth;
   2712           else if (is_punct(&p->cur, '{'))
   2713             ++brace_depth;
   2714           else if (is_punct(&p->cur, '}'))
   2715             --brace_depth;
   2716           advance(p);
   2717         }
   2718         if (len == cap) {
   2719           u32 new_cap = cap + 1;
   2720           Tok* nv = arena_array(p->pool->arena, Tok, new_cap);
   2721           if (!nv) perr(p, "out of memory recording _Generic default");
   2722           memcpy(nv, buf, len * sizeof(Tok));
   2723           buf = nv;
   2724           cap = new_cap;
   2725         }
   2726         memset(&buf[len], 0, sizeof(Tok));
   2727         buf[len].kind = TOK_PUNCT;
   2728         buf[len].v.punct = ',';
   2729         ++len;
   2730         default_buf = buf;
   2731         default_len = len;
   2732       } else {
   2733         int paren_depth = 0;
   2734         int brack_depth = 0;
   2735         int brace_depth = 0;
   2736         while (p->cur.kind != TOK_EOF) {
   2737           if (paren_depth == 0 && brack_depth == 0 && brace_depth == 0) {
   2738             if (is_punct(&p->cur, ',') || is_punct(&p->cur, ')')) break;
   2739           }
   2740           if (is_punct(&p->cur, '('))
   2741             ++paren_depth;
   2742           else if (is_punct(&p->cur, ')'))
   2743             --paren_depth;
   2744           else if (is_punct(&p->cur, '['))
   2745             ++brack_depth;
   2746           else if (is_punct(&p->cur, ']'))
   2747             --brack_depth;
   2748           else if (is_punct(&p->cur, '{'))
   2749             ++brace_depth;
   2750           else if (is_punct(&p->cur, '}'))
   2751             --brace_depth;
   2752           advance(p);
   2753         }
   2754       }
   2755       if (!accept_punct(p, ',')) break;
   2756     }
   2757     if (!emitted && default_buf) {
   2758       Tok* save_replay = p->replay;
   2759       u32 save_cap = p->replay_cap;
   2760       u32 save_len = p->replay_len;
   2761       u32 save_pos = p->replay_pos;
   2762       u8 save_active = p->replay_active;
   2763       Tok save_cur = p->cur;
   2764       int save_has_next = p->has_next;
   2765       p->replay = default_buf;
   2766       p->replay_cap = default_len;
   2767       p->replay_len = default_len;
   2768       p->replay_pos = 1;
   2769       p->replay_active = 1;
   2770       p->cur = default_buf[0];
   2771       p->has_next = 0;
   2772       parse_assign_expr(p);
   2773       emitted = 1;
   2774       p->replay = save_replay;
   2775       p->replay_cap = save_cap;
   2776       p->replay_len = save_len;
   2777       p->replay_pos = save_pos;
   2778       p->replay_active = save_active;
   2779       p->cur = save_cur;
   2780       p->has_next = save_has_next;
   2781     }
   2782     expect_punct(p, ')', "')' after _Generic");
   2783     if (!emitted) {
   2784       perr(p, "_Generic: no association matched and no default present");
   2785     }
   2786     return;
   2787   }
   2788   if (is_kw(p, &t, KW_ALIGNOF)) {
   2789     const Type* ty;
   2790     advance(p);
   2791     expect_punct(p, '(', "'('");
   2792     if (starts_type_name(p, &p->cur)) {
   2793       ty = parse_type_name(p);
   2794     } else {
   2795       parse_unary(p);
   2796       ty = pcg_top_type(p);
   2797       pcg_drop(p);
   2798     }
   2799     expect_punct(p, ')', "')'");
   2800     pcg_push_int(p, (i64)c_abi_alignof(p->abi, ty), ty_size_t(p));
   2801     return;
   2802   }
   2803   parse_postfix(p);
   2804 }
   2805 
   2806 /* ============================================================
   2807  * Binary operator levels
   2808  * ============================================================ */
   2809 
   2810 static int type_is_fp(const Type* t) {
   2811   return t &&
   2812          (t->kind == TY_FLOAT || t->kind == TY_DOUBLE || t->kind == TY_LDOUBLE);
   2813 }
   2814 
   2815 static const Type* common_fp_type(Parser* p, const Type* a, const Type* b) {
   2816   if (!type_is_fp(a) && !type_is_fp(b)) return NULL;
   2817   if ((a && a->kind == TY_LDOUBLE) || (b && b->kind == TY_LDOUBLE)) {
   2818     return type_prim(p->pool, TY_LDOUBLE);
   2819   }
   2820   if ((a && a->kind == TY_DOUBLE) || (b && b->kind == TY_DOUBLE)) {
   2821     return type_prim(p->pool, TY_DOUBLE);
   2822   }
   2823   return type_prim(p->pool, TY_FLOAT);
   2824 }
   2825 
   2826 static void emit_fp_binop(Parser* p, BinOp bop, const Type* common) {
   2827   if (pcg_top_type(p) != common) pcg_convert(p, common);
   2828   pcg_swap(p);
   2829   if (pcg_top_type(p) != common) pcg_convert(p, common);
   2830   pcg_swap(p);
   2831   BinOp fop;
   2832   switch (bop) {
   2833     case BO_IADD:
   2834       fop = BO_FADD;
   2835       break;
   2836     case BO_ISUB:
   2837       fop = BO_FSUB;
   2838       break;
   2839     case BO_IMUL:
   2840       fop = BO_FMUL;
   2841       break;
   2842     case BO_SDIV:
   2843       fop = BO_FDIV;
   2844       break;
   2845     default:
   2846       perr(p, "operator does not apply to floating types");
   2847       return;
   2848   }
   2849   pcg_binop(p, fop);
   2850 }
   2851 
   2852 static void coerce_fp_cmp_operands(Parser* p, const Type* common) {
   2853   if (pcg_top_type(p) != common) pcg_convert(p, common);
   2854   pcg_swap(p);
   2855   if (pcg_top_type(p) != common) pcg_convert(p, common);
   2856   pcg_swap(p);
   2857 }
   2858 
   2859 static void coerce_arith_operands(Parser* p, const Type* common) {
   2860   if (!common) return;
   2861   if (pcg_top_type(p) != common) pcg_convert(p, common);
   2862   pcg_swap(p);
   2863   if (pcg_top_type(p) != common) pcg_convert(p, common);
   2864   pcg_swap(p);
   2865 }
   2866 
   2867 static CmpOp unsigned_rel_cmp(CmpOp cop) {
   2868   switch (cop) {
   2869     case CMP_LT_S:
   2870       return CMP_LT_U;
   2871     case CMP_LE_S:
   2872       return CMP_LE_U;
   2873     case CMP_GT_S:
   2874       return CMP_GT_U;
   2875     case CMP_GE_S:
   2876       return CMP_GE_U;
   2877     default:
   2878       return cop;
   2879   }
   2880 }
   2881 
   2882 static BinOp int_div_rem_binop(BinOp op, const Type* common) {
   2883   if (pcg_type_is_signed(common)) return op;
   2884   switch (op) {
   2885     case BO_SDIV:
   2886       return BO_UDIV;
   2887     case BO_SREM:
   2888       return BO_UREM;
   2889     default:
   2890       return op;
   2891   }
   2892 }
   2893 
   2894 static void parse_mul(Parser* p) {
   2895   parse_unary(p);
   2896   for (;;) {
   2897     Tok t = p->cur;
   2898     BinOp bop;
   2899     if (is_punct(&t, '*')) {
   2900       bop = BO_IMUL;
   2901     } else if (is_punct(&t, '/')) {
   2902       bop = BO_SDIV;
   2903     } else if (is_punct(&t, '%')) {
   2904       bop = BO_SREM;
   2905     } else {
   2906       break;
   2907     }
   2908     advance(p);
   2909     to_rvalue(p);
   2910     parse_unary(p);
   2911     to_rvalue(p);
   2912     const Type* lt = pcg_top2_type(p);
   2913     const Type* rt = pcg_top_type(p);
   2914     const Type* common = common_fp_type(p, lt, rt);
   2915     if (bop == BO_SREM) {
   2916       if (!type_is_int(lt) || !type_is_int(rt))
   2917         perr(p, "operator '%' requires integer operands");
   2918     } else if (!type_is_arith(lt) || !type_is_arith(rt)) {
   2919       perr(p, "multiplicative operator requires arithmetic operands");
   2920     }
   2921     if (common) {
   2922       emit_fp_binop(p, bop, common);
   2923     } else {
   2924       const Type* icommon = cint_common_type(p, lt, rt);
   2925       coerce_arith_operands(p, icommon);
   2926       pcg_binop(p, int_div_rem_binop(bop, icommon));
   2927     }
   2928   }
   2929 }
   2930 
   2931 static void scale_pointer_index(Parser* p, u32 elem_size) {
   2932   const Type* idx_ty = c_abi_ptrdiff_type(p->abi, p->pool);
   2933   coerce_top_to_type(p, idx_ty);
   2934   if (elem_size != 1) {
   2935     pcg_push_int(p, (i64)elem_size, idx_ty);
   2936     pcg_binop(p, BO_IMUL);
   2937   }
   2938 }
   2939 
   2940 static void emit_add_or_sub(Parser* p, BinOp bop) {
   2941   const Type* lt = pcg_top2_type(p);
   2942   const Type* rt = pcg_top_type(p);
   2943   int l_is_ptr = lt && lt->kind == TY_PTR;
   2944   int r_is_ptr = rt && rt->kind == TY_PTR;
   2945   if (bop == BO_IADD) {
   2946     if (l_is_ptr && r_is_ptr) {
   2947       perr(p, "invalid operands to binary +");
   2948     }
   2949     if (l_is_ptr && type_is_int(rt)) {
   2950       if (lt->ptr.pointee && lt->ptr.pointee->kind == TY_VOID)
   2951         perr(p, "pointer arithmetic on void pointer");
   2952       u32 esz = c_abi_sizeof(p->abi, lt->ptr.pointee);
   2953       scale_pointer_index(p, esz);
   2954       pcg_binop(p, BO_IADD);
   2955       return;
   2956     }
   2957     if (r_is_ptr && type_is_int(lt)) {
   2958       if (rt->ptr.pointee && rt->ptr.pointee->kind == TY_VOID)
   2959         perr(p, "pointer arithmetic on void pointer");
   2960       pcg_swap(p);
   2961       u32 esz = c_abi_sizeof(p->abi, rt->ptr.pointee);
   2962       scale_pointer_index(p, esz);
   2963       pcg_binop(p, BO_IADD);
   2964       return;
   2965     }
   2966   } else { /* BO_ISUB */
   2967     if (l_is_ptr && type_is_int(rt)) {
   2968       if (lt->ptr.pointee && lt->ptr.pointee->kind == TY_VOID)
   2969         perr(p, "pointer arithmetic on void pointer");
   2970       u32 esz = c_abi_sizeof(p->abi, lt->ptr.pointee);
   2971       scale_pointer_index(p, esz);
   2972       pcg_binop(p, BO_ISUB);
   2973       return;
   2974     }
   2975     if (l_is_ptr && r_is_ptr) {
   2976       if (!pointer_pointees_compatible(p, lt, rt)) {
   2977         perr(p, "subtraction of incompatible pointer types");
   2978       }
   2979       u32 esz = c_abi_sizeof(p->abi, lt->ptr.pointee);
   2980       pcg_binop(p, BO_ISUB);
   2981       if (esz != 1) {
   2982         pcg_push_int(p, (i64)esz, ty_size_t(p));
   2983         pcg_binop(p, BO_SDIV);
   2984       }
   2985       pcg_convert(p, c_abi_ptrdiff_type(p->abi, p->pool));
   2986       return;
   2987     }
   2988   }
   2989   if (l_is_ptr || r_is_ptr) {
   2990     perr(p, "invalid operands to additive operator");
   2991   }
   2992   const Type* common = common_fp_type(p, lt, rt);
   2993   if (!common && (!type_is_arith(lt) || !type_is_arith(rt))) {
   2994     perr(p, "additive operator requires arithmetic operands");
   2995   }
   2996   if (common) {
   2997     emit_fp_binop(p, bop, common);
   2998     return;
   2999   }
   3000   common = cint_common_type(p, lt, rt);
   3001   coerce_arith_operands(p, common);
   3002   pcg_binop(p, bop);
   3003 }
   3004 
   3005 static void parse_add(Parser* p) {
   3006   parse_mul(p);
   3007   for (;;) {
   3008     Tok t = p->cur;
   3009     BinOp bop;
   3010     if (is_punct(&t, '+')) {
   3011       bop = BO_IADD;
   3012     } else if (is_punct(&t, '-')) {
   3013       bop = BO_ISUB;
   3014     } else {
   3015       break;
   3016     }
   3017     advance(p);
   3018     to_rvalue(p);
   3019     parse_mul(p);
   3020     to_rvalue(p);
   3021     emit_add_or_sub(p, bop);
   3022   }
   3023 }
   3024 
   3025 static void parse_shift(Parser* p) {
   3026   parse_add(p);
   3027   for (;;) {
   3028     Tok t = p->cur;
   3029     BinOp bop;
   3030     if (is_punct(&t, P_SHL)) {
   3031       bop = BO_SHL;
   3032     } else if (is_punct(&t, P_SHR)) {
   3033       bop = BO_SHR_S;
   3034     } else {
   3035       break;
   3036     }
   3037     advance(p);
   3038     to_rvalue(p);
   3039     {
   3040       const Type* lt = pcg_top_type(p);
   3041       const Type* lp = cint_promote_type(p, lt);
   3042       if (!type_is_int(lt)) perr(p, "shift operator requires integer operands");
   3043       if (pcg_top_type(p) != lp) pcg_convert(p, lp);
   3044       if (bop == BO_SHR_S && !c_abi_type_info(p->abi, lp).signed_)
   3045         bop = BO_SHR_U;
   3046     }
   3047     parse_add(p);
   3048     to_rvalue(p);
   3049     {
   3050       const Type* rt = pcg_top_type(p);
   3051       const Type* rp = cint_promote_type(p, rt);
   3052       if (!type_is_int(rt)) perr(p, "shift operator requires integer operands");
   3053       if (pcg_top_type(p) != rp) pcg_convert(p, rp);
   3054     }
   3055     if (!type_is_int(pcg_top2_type(p)) || !type_is_int(pcg_top_type(p))) {
   3056       perr(p, "shift operator requires integer operands");
   3057     }
   3058     pcg_binop(p, bop);
   3059   }
   3060 }
   3061 
   3062 static void parse_rel(Parser* p) {
   3063   parse_shift(p);
   3064   for (;;) {
   3065     Tok t = p->cur;
   3066     CmpOp cop;
   3067     if (is_punct(&t, '<')) {
   3068       cop = CMP_LT_S;
   3069     } else if (is_punct(&t, '>')) {
   3070       cop = CMP_GT_S;
   3071     } else if (is_punct(&t, P_LE)) {
   3072       cop = CMP_LE_S;
   3073     } else if (is_punct(&t, P_GE)) {
   3074       cop = CMP_GE_S;
   3075     } else {
   3076       break;
   3077     }
   3078     advance(p);
   3079     to_rvalue(p);
   3080     parse_shift(p);
   3081     to_rvalue(p);
   3082     {
   3083       const Type* lt = pcg_top2_type(p);
   3084       const Type* rt = pcg_top_type(p);
   3085       const Type* common = common_fp_type(p, lt, rt);
   3086       if (lt && lt->kind == TY_PTR && rt && rt->kind == TY_PTR) {
   3087         if (!pointer_pointees_compatible(p, lt, rt)) {
   3088           perr(p, "comparison of incompatible pointer types");
   3089         }
   3090       } else if (!type_is_arith(lt) || !type_is_arith(rt)) {
   3091         perr(p,
   3092              "relational operator requires arithmetic or compatible pointer "
   3093              "operands");
   3094       }
   3095       if (common) {
   3096         coerce_fp_cmp_operands(p, common);
   3097         switch (cop) {
   3098           case CMP_LT_S:
   3099             cop = CMP_LT_F;
   3100             break;
   3101           case CMP_LE_S:
   3102             cop = CMP_LE_F;
   3103             break;
   3104           case CMP_GT_S:
   3105             cop = CMP_GT_F;
   3106             break;
   3107           case CMP_GE_S:
   3108             cop = CMP_GE_F;
   3109             break;
   3110           default:
   3111             break;
   3112         }
   3113       } else if (type_is_arith(lt) && type_is_arith(rt)) {
   3114         common = cint_common_type(p, lt, rt);
   3115         coerce_arith_operands(p, common);
   3116         if (!cint_signed(p, common)) cop = unsigned_rel_cmp(cop);
   3117       }
   3118     }
   3119     pcg_cmp(p, cop);
   3120   }
   3121 }
   3122 
   3123 static void parse_eq(Parser* p) {
   3124   parse_rel(p);
   3125   for (;;) {
   3126     Tok t = p->cur;
   3127     CmpOp cop;
   3128     if (is_punct(&t, P_EQ)) {
   3129       cop = CMP_EQ;
   3130     } else if (is_punct(&t, P_NE)) {
   3131       cop = CMP_NE;
   3132     } else {
   3133       break;
   3134     }
   3135     int lhs_null = null_pointer_constant(p, pcg_top_type(p));
   3136     advance(p);
   3137     to_rvalue(p);
   3138     parse_rel(p);
   3139     to_rvalue(p);
   3140     {
   3141       const Type* lt = pcg_top2_type(p);
   3142       const Type* rt = pcg_top_type(p);
   3143       const Type* common = common_fp_type(p, lt, rt);
   3144       int lnull = lhs_null;
   3145       int rnull = null_pointer_constant(p, rt);
   3146       if (lt && lt->kind == TY_PTR && rt && rt->kind == TY_PTR) {
   3147         if (!type_is_void_ptr(lt) && !type_is_void_ptr(rt) &&
   3148             !pointer_pointees_compatible(p, lt, rt)) {
   3149           perr(p, "comparison of incompatible pointer types");
   3150         }
   3151       } else if ((lt && lt->kind == TY_PTR) || (rt && rt->kind == TY_PTR)) {
   3152         if (!lnull && !rnull) perr(p, "comparison between pointer and integer");
   3153       } else if (!type_is_arith(lt) || !type_is_arith(rt)) {
   3154         perr(p, "equality operator requires scalar operands");
   3155       }
   3156       if (common)
   3157         coerce_fp_cmp_operands(p, common);
   3158       else if (type_is_arith(lt) && type_is_arith(rt)) {
   3159         common = cint_common_type(p, lt, rt);
   3160         coerce_arith_operands(p, common);
   3161       }
   3162     }
   3163     pcg_cmp(p, cop);
   3164   }
   3165 }
   3166 
   3167 static void parse_band(Parser* p) {
   3168   parse_eq(p);
   3169   while (is_punct(&p->cur, '&')) {
   3170     advance(p);
   3171     to_rvalue(p);
   3172     parse_eq(p);
   3173     to_rvalue(p);
   3174     if (!type_is_int(pcg_top2_type(p)) || !type_is_int(pcg_top_type(p))) {
   3175       perr(p, "bitwise operator requires integer operands");
   3176     }
   3177     coerce_arith_operands(
   3178         p, cint_common_type(p, pcg_top2_type(p), pcg_top_type(p)));
   3179     pcg_binop(p, BO_AND);
   3180   }
   3181 }
   3182 
   3183 static void parse_bxor(Parser* p) {
   3184   parse_band(p);
   3185   while (is_punct(&p->cur, '^')) {
   3186     advance(p);
   3187     to_rvalue(p);
   3188     parse_band(p);
   3189     to_rvalue(p);
   3190     if (!type_is_int(pcg_top2_type(p)) || !type_is_int(pcg_top_type(p))) {
   3191       perr(p, "bitwise operator requires integer operands");
   3192     }
   3193     coerce_arith_operands(
   3194         p, cint_common_type(p, pcg_top2_type(p), pcg_top_type(p)));
   3195     pcg_binop(p, BO_XOR);
   3196   }
   3197 }
   3198 
   3199 static void parse_bor(Parser* p) {
   3200   parse_bxor(p);
   3201   while (is_punct(&p->cur, '|')) {
   3202     advance(p);
   3203     to_rvalue(p);
   3204     parse_bxor(p);
   3205     to_rvalue(p);
   3206     if (!type_is_int(pcg_top2_type(p)) || !type_is_int(pcg_top_type(p))) {
   3207       perr(p, "bitwise operator requires integer operands");
   3208     }
   3209     coerce_arith_operands(
   3210         p, cint_common_type(p, pcg_top2_type(p), pcg_top_type(p)));
   3211     pcg_binop(p, BO_OR);
   3212   }
   3213 }
   3214 
   3215 static int cg_top_const_truth(Parser* p, int* truth_out) {
   3216   i64 v = 0;
   3217   if (!pcg_emit_enabled(p)) return 0;
   3218   if (!kit_cg_top_const_int(p->cg, &v)) return 0;
   3219   *truth_out = v != 0;
   3220   return 1;
   3221 }
   3222 
   3223 static FrameSlot ll_tmp_slot(Parser* p, const Type* ty) {
   3224   FrameSlotDesc fsd;
   3225   memset(&fsd, 0, sizeof fsd);
   3226   fsd.type = ty;
   3227   fsd.size = c_abi_sizeof(p->abi, ty);
   3228   fsd.align = c_abi_alignof(p->abi, ty);
   3229   fsd.kind = FS_LOCAL;
   3230   fsd.flags = FSF_NONE;
   3231   return pcg_local(p, &fsd);
   3232 }
   3233 
   3234 static void ll_store_const(Parser* p, FrameSlot tmp, const Type* ty, i64 v) {
   3235   pcg_push_local_typed(p, tmp, ty);
   3236   pcg_push_int(p, v, ty);
   3237   pcg_store(p);
   3238   pcg_drop(p);
   3239 }
   3240 
   3241 static void parse_land(Parser* p) {
   3242   parse_bor(p);
   3243   while (is_punct(&p->cur, P_AND)) {
   3244     CGLabel L_false = pcg_label_new(p);
   3245     CGLabel L_end = pcg_label_new(p);
   3246     const Type* result_ty = ty_int(p);
   3247     FrameSlot tmp = ll_tmp_slot(p, result_ty);
   3248     int lhs_known;
   3249     int lhs_truth = 0;
   3250     int rhs_truth = 0;
   3251     advance(p);
   3252     to_rvalue(p);
   3253     require_scalar(p, pcg_top_type(p), "logical '&&'");
   3254     lhs_known = cg_top_const_truth(p, &lhs_truth);
   3255     if (lhs_known && !lhs_truth) {
   3256       pcg_drop(p);
   3257       pcg_codegen_suppress_push(p);
   3258       parse_bor(p);
   3259       to_rvalue(p);
   3260       require_scalar(p, pcg_top_type(p), "logical '&&'");
   3261       pcg_drop(p);
   3262       pcg_codegen_suppress_pop(p);
   3263       pcg_push_int(p, 0, result_ty);
   3264       continue;
   3265     }
   3266     pcg_branch_false(p, L_false);
   3267     parse_bor(p);
   3268     to_rvalue(p);
   3269     require_scalar(p, pcg_top_type(p), "logical '&&'");
   3270     if (lhs_known && lhs_truth && cg_top_const_truth(p, &rhs_truth)) {
   3271       pcg_drop(p);
   3272       pcg_push_int(p, rhs_truth ? 1 : 0, result_ty);
   3273       continue;
   3274     }
   3275     pcg_branch_false(p, L_false);
   3276     ll_store_const(p, tmp, result_ty, 1);
   3277     pcg_jump(p, L_end);
   3278     pcg_label_place(p, L_false);
   3279     ll_store_const(p, tmp, result_ty, 0);
   3280     pcg_label_place(p, L_end);
   3281     pcg_push_local_typed(p, tmp, result_ty);
   3282   }
   3283 }
   3284 
   3285 static void parse_lor(Parser* p) {
   3286   parse_land(p);
   3287   while (is_punct(&p->cur, P_OR)) {
   3288     CGLabel L_true = pcg_label_new(p);
   3289     CGLabel L_end = pcg_label_new(p);
   3290     const Type* result_ty = ty_int(p);
   3291     FrameSlot tmp = ll_tmp_slot(p, result_ty);
   3292     int lhs_known;
   3293     int lhs_truth = 0;
   3294     int rhs_truth = 0;
   3295     advance(p);
   3296     to_rvalue(p);
   3297     require_scalar(p, pcg_top_type(p), "logical '||'");
   3298     lhs_known = cg_top_const_truth(p, &lhs_truth);
   3299     if (lhs_known && lhs_truth) {
   3300       pcg_drop(p);
   3301       pcg_codegen_suppress_push(p);
   3302       parse_land(p);
   3303       to_rvalue(p);
   3304       require_scalar(p, pcg_top_type(p), "logical '||'");
   3305       pcg_drop(p);
   3306       pcg_codegen_suppress_pop(p);
   3307       pcg_push_int(p, 1, result_ty);
   3308       continue;
   3309     }
   3310     pcg_branch_true(p, L_true);
   3311     parse_land(p);
   3312     to_rvalue(p);
   3313     require_scalar(p, pcg_top_type(p), "logical '||'");
   3314     if (lhs_known && !lhs_truth && cg_top_const_truth(p, &rhs_truth)) {
   3315       pcg_drop(p);
   3316       pcg_push_int(p, rhs_truth ? 1 : 0, result_ty);
   3317       continue;
   3318     }
   3319     pcg_branch_true(p, L_true);
   3320     ll_store_const(p, tmp, result_ty, 0);
   3321     pcg_jump(p, L_end);
   3322     pcg_label_place(p, L_true);
   3323     ll_store_const(p, tmp, result_ty, 1);
   3324     pcg_label_place(p, L_end);
   3325     pcg_push_local_typed(p, tmp, result_ty);
   3326   }
   3327 }
   3328 
   3329 static const Type* common_fp_type(Parser* p, const Type* a, const Type* b);
   3330 
   3331 static void parse_ternary(Parser* p) {
   3332   parse_lor(p);
   3333   if (!is_punct(&p->cur, '?')) return;
   3334   CGLabel L_else = pcg_label_new(p);
   3335   CGLabel L_end = pcg_label_new(p);
   3336   const Type* result_ty = ty_int(p);
   3337   int then_null = 0;
   3338   FrameSlot tmp;
   3339   FrameSlotDesc fsd;
   3340   const Type* then_store_ty;
   3341   advance(p); /* '?' */
   3342   to_rvalue(p);
   3343   require_scalar(p, pcg_top_type(p), "conditional operator");
   3344   pcg_branch_false(p, L_else);
   3345   parse_expr(p);
   3346   to_rvalue(p);
   3347   result_ty = pcg_top_type(p);
   3348   then_null = null_pointer_constant(p, result_ty);
   3349   if (!result_ty) result_ty = ty_int(p);
   3350   if (type_is_int(result_ty)) {
   3351     result_ty = type_promoted(p->pool, result_ty);
   3352     if (pcg_top_type(p) != result_ty) pcg_convert(p, result_ty);
   3353   }
   3354   then_store_ty =
   3355       then_null ? type_ptr(p->pool, type_prim(p->pool, TY_VOID)) : result_ty;
   3356   memset(&fsd, 0, sizeof fsd);
   3357   fsd.type = then_store_ty;
   3358   fsd.size = c_abi_sizeof(p->abi, then_store_ty);
   3359   fsd.align = c_abi_alignof(p->abi, then_store_ty);
   3360   fsd.kind = FS_LOCAL;
   3361   fsd.flags = FSF_NONE;
   3362   tmp = pcg_local(p, &fsd);
   3363   if (pcg_top_type(p) != then_store_ty) pcg_convert(p, then_store_ty);
   3364   pcg_push_local_typed(p, tmp, then_store_ty);
   3365   pcg_swap(p);
   3366   pcg_store(p);
   3367   pcg_drop(p);
   3368   pcg_jump(p, L_end);
   3369   pcg_label_place(p, L_else);
   3370   expect_punct(p, ':', "':' in ternary");
   3371   parse_assign_expr(p);
   3372   to_rvalue(p);
   3373   const Type* else_ty = pcg_top_type(p);
   3374   const Type* common = common_fp_type(p, result_ty, else_ty);
   3375   const Type* ptr_result = conditional_pointer_type(
   3376       p, result_ty, then_null, else_ty, null_pointer_constant(p, else_ty));
   3377   if ((result_ty && result_ty->kind == TY_PTR) ||
   3378       (else_ty && else_ty->kind == TY_PTR)) {
   3379     if (!ptr_result) perr(p, "conditional operator pointer type mismatch");
   3380     result_ty = ptr_result;
   3381   } else if (type_is_arith(result_ty) && type_is_arith(else_ty)) {
   3382     /* Usual arithmetic conversions are handled by the existing `common`
   3383      * materialization below; keep the first temporary's type stable here. */
   3384   } else if (!type_compatible(result_ty, else_ty)) {
   3385     perr(p, "conditional operator type mismatch");
   3386   }
   3387   if (pcg_top_type(p) != result_ty) {
   3388     pcg_convert(p, result_ty);
   3389   }
   3390   pcg_push_local_typed(p, tmp, result_ty);
   3391   pcg_swap(p);
   3392   pcg_store(p);
   3393   pcg_drop(p);
   3394   pcg_label_place(p, L_end);
   3395   if (common && common != result_ty) {
   3396     FrameSlotDesc cfsd;
   3397     FrameSlot ctmp;
   3398     memset(&cfsd, 0, sizeof cfsd);
   3399     cfsd.type = common;
   3400     cfsd.size = c_abi_sizeof(p->abi, common);
   3401     cfsd.align = c_abi_alignof(p->abi, common);
   3402     cfsd.kind = FS_LOCAL;
   3403     cfsd.flags = FSF_NONE;
   3404     ctmp = pcg_local(p, &cfsd);
   3405     pcg_push_local_typed(p, tmp, result_ty);
   3406     pcg_load(p);
   3407     pcg_convert(p, common);
   3408     pcg_push_local_typed(p, ctmp, common);
   3409     pcg_swap(p);
   3410     pcg_store(p);
   3411     pcg_drop(p);
   3412     pcg_push_local_typed(p, ctmp, common);
   3413     return;
   3414   }
   3415   pcg_push_local_typed(p, tmp, result_ty);
   3416 }
   3417 
   3418 void parse_assign_expr(Parser* p) {
   3419   parse_ternary(p);
   3420   Tok t = p->cur;
   3421   BinOp compound;
   3422   int is_simple_assign;
   3423   if (is_punct(&t, '=')) {
   3424     is_simple_assign = 1;
   3425     compound = (BinOp)0;
   3426   } else if (is_punct(&t, P_ADD_ASSIGN)) {
   3427     is_simple_assign = 0;
   3428     compound = BO_IADD;
   3429   } else if (is_punct(&t, P_SUB_ASSIGN)) {
   3430     is_simple_assign = 0;
   3431     compound = BO_ISUB;
   3432   } else if (is_punct(&t, P_MUL_ASSIGN)) {
   3433     is_simple_assign = 0;
   3434     compound = BO_IMUL;
   3435   } else if (is_punct(&t, P_DIV_ASSIGN)) {
   3436     is_simple_assign = 0;
   3437     compound = BO_SDIV;
   3438   } else if (is_punct(&t, P_MOD_ASSIGN)) {
   3439     is_simple_assign = 0;
   3440     compound = BO_SREM;
   3441   } else if (is_punct(&t, P_AND_ASSIGN)) {
   3442     is_simple_assign = 0;
   3443     compound = BO_AND;
   3444   } else if (is_punct(&t, P_OR_ASSIGN)) {
   3445     is_simple_assign = 0;
   3446     compound = BO_OR;
   3447   } else if (is_punct(&t, P_XOR_ASSIGN)) {
   3448     is_simple_assign = 0;
   3449     compound = BO_XOR;
   3450   } else if (is_punct(&t, P_SHL_ASSIGN)) {
   3451     is_simple_assign = 0;
   3452     compound = BO_SHL;
   3453   } else if (is_punct(&t, P_SHR_ASSIGN)) {
   3454     is_simple_assign = 0;
   3455     compound = BO_SHR_S;
   3456   } else {
   3457     return;
   3458   }
   3459   if (!pcg_top_is_modifiable_lvalue(p)) {
   3460     perr(p, "assignment requires modifiable lvalue");
   3461   }
   3462   advance(p);
   3463   const Type* lhs = pcg_top_type(p);
   3464   if (compound == BO_SHR_S && !c_abi_type_info(p->abi, lhs).signed_)
   3465     compound = BO_SHR_U;
   3466   {
   3467     if (lhs && (lhs->qual & Q_CONST)) {
   3468       perr(p, "assignment to const-qualified object");
   3469     }
   3470   }
   3471   if (is_simple_assign) {
   3472     /* Aggregate destinations keep any member/index displacement in the lvalue
   3473      * aux rather than a scalar EA the store can fold. Collapse a non-trivial
   3474      * EA into a plain pointer-deref lvalue (mirrors the source-side handling in
   3475      * to_rvalue) so the aggregate copy lands at the right address. */
   3476     if (lhs && (lhs->kind == TY_STRUCT || lhs->kind == TY_UNION)) {
   3477       PcgLvAux* dlv = pcg_top_lv_aux(p);
   3478       if (pcg_top_is_lvalue(p) && dlv &&
   3479           (dlv->offset != 0 || dlv->scale != 0)) {
   3480         const Type* uty = type_unqual(p->pool, lhs);
   3481         pcg_addr(p);
   3482         pcg_deref(p, uty);
   3483       }
   3484     }
   3485     parse_assign_expr(p);
   3486     to_rvalue(p);
   3487     {
   3488       const Type* rhs = pcg_top_type(p);
   3489       CSemCheck chk =
   3490           c_sem_check_assignment(p->pool, lhs, rhs, C_SEM_ASSIGN_EXPR);
   3491       if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message)));
   3492     }
   3493     coerce_top_to_lvalue(p);
   3494     pcg_store(p);
   3495     return;
   3496   }
   3497   {
   3498     PcgLvAux* lv = pcg_top_lv_aux(p);
   3499     if (pcg_emit_enabled(p)) {
   3500       if (lv && lv->scale != 0)
   3501         kit_cg_dup2(p->cg);
   3502       else
   3503         kit_cg_dup(p->cg);
   3504     }
   3505     pcg_dup_type(p);
   3506   }
   3507   pcg_load(p);
   3508   parse_assign_expr(p);
   3509   to_rvalue(p);
   3510   {
   3511     const Type* rhs = pcg_top_type(p);
   3512     int op = '+';
   3513     switch (compound) {
   3514       case BO_IADD:
   3515         op = '+';
   3516         break;
   3517       case BO_ISUB:
   3518         op = '-';
   3519         break;
   3520       case BO_IMUL:
   3521         op = '*';
   3522         break;
   3523       case BO_SDIV:
   3524         op = '/';
   3525         break;
   3526       case BO_SREM:
   3527         op = '%';
   3528         break;
   3529       case BO_AND:
   3530         op = '&';
   3531         break;
   3532       case BO_OR:
   3533         op = '|';
   3534         break;
   3535       case BO_XOR:
   3536         op = '^';
   3537         break;
   3538       case BO_SHL:
   3539         op = '<';
   3540         break;
   3541       case BO_SHR_S:
   3542         op = '>';
   3543         break;
   3544       case BO_SHR_U:
   3545         op = '>';
   3546         break;
   3547       default:
   3548         op = 0;
   3549         break;
   3550     }
   3551     CSemCheck chk = c_sem_check_compound_assignment(p->pool, lhs, rhs, op);
   3552     if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message)));
   3553   }
   3554   if (compound == BO_IADD || compound == BO_ISUB) {
   3555     emit_add_or_sub(p, compound);
   3556   } else {
   3557     const Type* lt = pcg_top2_type(p);
   3558     const Type* rt = pcg_top_type(p);
   3559     const Type* common = common_fp_type(p, lt, rt);
   3560     if (common) {
   3561       if (compound == BO_SREM)
   3562         perr(p, "operator '%%=' requires integer operands");
   3563       emit_fp_binop(p, compound, common);
   3564     } else {
   3565       const Type* icommon = cint_common_type(p, lt, rt);
   3566       coerce_arith_operands(p, icommon);
   3567       pcg_binop(p, int_div_rem_binop(compound, icommon));
   3568     }
   3569   }
   3570   coerce_top_to_type(p, lhs);
   3571   if (p->cg_type_sp >= 2) p->cg_type_stack[p->cg_type_sp - 2u] = lhs;
   3572   pcg_store(p);
   3573 }
   3574 
   3575 void parse_expr(Parser* p) {
   3576   parse_assign_expr(p);
   3577   while (is_punct(&p->cur, ',')) {
   3578     advance(p);
   3579     pcg_drop(p);
   3580     parse_assign_expr(p);
   3581   }
   3582 }
   3583 
   3584 /* parse_cond_expr is the ternary level, provided for completeness */
   3585 void parse_cond_expr(Parser* p) { parse_ternary(p); }