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); }