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