parse_init.c (57423B)
1 /* parse_init.c — runtime and static-storage initializers. 2 * 3 * Covers §6.7.9 (initializers): 4 * - Runtime aggregate/scalar initializers (init_at, init_elided, 5 * init_struct_fields, init_string_at, parse_designator_chain, 6 * push_subobject_lv, emit_copy_leaf, emit_walk_copy, 7 * emit_struct_copy_into_slot, zero_init_at) 8 * - Static-storage object definition (parse_static_init_at, 9 * parse_static_string_at, parse_static_const, encode_int_le, 10 * pick_object_section, define_static_object, srl_push) 11 */ 12 13 #include "parse/parse_priv.h" 14 15 /* ============================================================ 16 * File-local helpers 17 * ============================================================ */ 18 19 static SrcLoc tok_loc_init(const Tok* t) { return t->loc; } 20 21 static CKw ident_kw_init(const Parser* p, Sym name) { 22 return ident_kw_inline(p, name); 23 } 24 25 static const Type* init_field_type_at(const Type* ty, u16 i) { 26 const Field* f = &ty->rec.fields[i]; 27 return f->type; 28 } 29 30 static u32 init_field_offset_at(const ABIRecordLayout* L, u16 i) { 31 return L->fields[i].offset; 32 } 33 34 /* True if `ty` is char/signed char/unsigned char. */ 35 int is_char_kind(const Type* ty) { 36 if (!ty) return 0; 37 return ty->kind == TY_CHAR || ty->kind == TY_SCHAR || ty->kind == TY_UCHAR; 38 } 39 40 /* Decode the string token at p->cur without advancing. Returns a heap- 41 * allocated byte buffer (caller frees) and writes length (including NUL) 42 * to *nlen_out. */ 43 static u8* peek_string_bytes(Parser* p, size_t* nlen_out) { 44 Tok t = p->cur; 45 if (t.kind != TOK_STR) perr(p, "internal: peek_string_bytes on non-string"); 46 return decode_string_literal(p, &t, nlen_out); 47 } 48 49 static u64 decode_lit_unit_le(const u8* src, u32 size) { 50 u64 v = 0; 51 u32 i; 52 if (size > 8u) size = 8u; 53 for (i = 0; i < size; ++i) v |= (u64)src[i] << (8u * i); 54 return v; 55 } 56 57 /* ============================================================ 58 * Runtime initializers 59 * ============================================================ */ 60 61 /* Forward declaration for mutual recursion. */ 62 void init_at(Parser* p, FrameSlot slot, const Type* arr_ty, u32 offset, 63 const Type* ty); 64 65 typedef struct InitDesignatorCont { 66 const Type* parent_ty; 67 u32 parent_offset; 68 u32 next_index; 69 } InitDesignatorCont; 70 71 static void init_aggregate_remainder(Parser* p, FrameSlot slot, 72 const Type* arr_ty, u32 offset, 73 const Type* ty, u32 start_index); 74 75 static void replay_recorded_initializer_expr(Parser* p) { 76 if (p->replay_len == 0) 77 perr(p, "internal: empty initializer expression replay"); 78 p->cur = p->replay[0]; 79 p->replay_pos = 1; 80 p->replay_active = 1; 81 p->has_next = 0; 82 } 83 84 static void record_initializer_expr_for_replay(Parser* p) { 85 u32 len = 0; 86 u32 cap = 0; 87 Tok* buf = NULL; 88 int paren_depth = 0; 89 int brack_depth = 0; 90 int brace_depth = 0; 91 92 for (;;) { 93 if (len == cap) { 94 u32 new_cap = cap ? cap * 2u : 16u; 95 Tok* nb = arena_array(p->pool->arena, Tok, new_cap); 96 if (!nb) perr(p, "out of memory recording initializer expression"); 97 if (buf && len) memcpy(nb, buf, len * sizeof(*buf)); 98 buf = nb; 99 cap = new_cap; 100 } 101 buf[len++] = p->cur; 102 103 if (p->cur.kind == TOK_EOF) break; 104 if (paren_depth == 0 && brack_depth == 0 && brace_depth == 0 && 105 (is_punct(&p->cur, ',') || is_punct(&p->cur, '}'))) { 106 break; 107 } 108 109 if (is_punct(&p->cur, '(')) 110 ++paren_depth; 111 else if (is_punct(&p->cur, ')')) 112 --paren_depth; 113 else if (is_punct(&p->cur, '[')) 114 ++brack_depth; 115 else if (is_punct(&p->cur, ']')) 116 --brack_depth; 117 else if (is_punct(&p->cur, '{')) 118 ++brace_depth; 119 else if (is_punct(&p->cur, '}')) 120 --brace_depth; 121 122 advance(p); 123 } 124 125 p->replay = buf; 126 p->replay_cap = cap; 127 p->replay_len = len; 128 replay_recorded_initializer_expr(p); 129 } 130 131 static int try_init_aggregate_from_expr(Parser* p, FrameSlot slot, 132 const Type* arr_ty, u32 offset, 133 const Type* ty) { 134 const Type* expr_ty; 135 u32 save_sp; 136 int compatible; 137 138 if (!ty || (ty->kind != TY_STRUCT && ty->kind != TY_UNION)) return 0; 139 if (is_punct(&p->cur, '{') || is_punct(&p->cur, '.') || 140 is_punct(&p->cur, '[')) { 141 return 0; 142 } 143 144 record_initializer_expr_for_replay(p); 145 146 save_sp = p->cg_type_sp; 147 pcg_codegen_suppress_push(p); 148 parse_assign_expr(p); 149 expr_ty = pcg_top_type(p); 150 compatible = 151 type_compatible(type_unqual(p->pool, ty), type_unqual(p->pool, expr_ty)); 152 p->cg_type_sp = save_sp; 153 pcg_codegen_suppress_pop(p); 154 155 replay_recorded_initializer_expr(p); 156 if (!compatible) return 0; 157 158 parse_assign_expr(p); 159 if (!type_compatible(type_unqual(p->pool, ty), 160 type_unqual(p->pool, pcg_top_type(p)))) { 161 perr(p, "incompatible aggregate initializer"); 162 } 163 emit_struct_copy_into_slot(p, slot, arr_ty, offset, ty); 164 return 1; 165 } 166 167 /* Push the lvalue of a sub-object at byte offset `offset` within the array 168 * local `slot` (whose type is `arr_ty`), with element type `elem_ty`. */ 169 void push_subobject_lv(Parser* p, FrameSlot slot, const Type* arr_ty, 170 u32 offset, const Type* elem_ty) { 171 pcg_push_local_typed(p, slot, arr_ty); 172 /* Fold the byte offset onto the local lvalue's aux; the next 173 * load/store/addr will bake it into the memop's ea.offset. The result is an 174 * lvalue of elem_ty backed by the frame slot. */ 175 pcg_lv_member(p, (i64)offset, elem_ty, /*bf_off=*/0, /*bf_w=*/0, /*ss=*/0); 176 } 177 178 static void zero_object_bytes_at(Parser* p, FrameSlot slot, const Type* arr_ty, 179 u32 offset, const Type* ty) { 180 KitCgMemAccess access = pcg_mem(p, ty); 181 push_subobject_lv(p, slot, arr_ty, offset, ty); 182 pcg_addr(p); 183 if (pcg_emit_enabled(p)) { 184 kit_cg_memset(p->cg, 0, c_abi_sizeof(p->abi, ty), access); 185 } 186 pcg_drop_type(p); 187 } 188 189 static void push_record_field_lv(Parser* p, FrameSlot slot, const Type* arr_ty, 190 u32 rec_offset, const Type* rec_ty, 191 u32 field_index) { 192 const Field* f = &rec_ty->rec.fields[field_index]; 193 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, rec_ty); 194 u32 foff = L->fields[field_index].offset; 195 u16 bf_off = 0; 196 u16 bf_w = 0; 197 u32 bf_ss = 0; 198 push_subobject_lv(p, slot, arr_ty, rec_offset, rec_ty); 199 if (f->flags & FIELD_BITFIELD) { 200 bf_off = L->fields[field_index].bit_offset; 201 bf_w = L->fields[field_index].bit_width; 202 bf_ss = L->fields[field_index].storage_size; 203 } 204 pcg_lv_member(p, (i64)foff, f->type, bf_off, bf_w, bf_ss); 205 } 206 207 /* Emit a load+store for one scalar leaf. */ 208 static void emit_copy_leaf(Parser* p, FrameSlot dst_slot, 209 const Type* dst_arr_ty, u32 dst_off, 210 FrameSlot src_ptr_slot, const Type* src_ptr_ty, 211 u32 src_off, const Type* leaf_ty) { 212 push_subobject_lv(p, dst_slot, dst_arr_ty, dst_off, leaf_ty); 213 pcg_push_local_typed(p, src_ptr_slot, src_ptr_ty); 214 pcg_load(p); 215 /* TOS is now a pointer rvalue (the loaded source pointer). Retag as a 216 * C-language lvalue with POINTER_RV base, then fold the source byte offset 217 * onto its aux. The next pcg_load consumes the EA into the memop. */ 218 pcg_deref(p, leaf_ty); 219 pcg_lv_member(p, (i64)src_off, leaf_ty, 0, 0, 0); 220 pcg_load(p); 221 pcg_store(p); 222 pcg_drop(p); 223 } 224 225 /* Walk a (possibly nested) aggregate, emitting a leaf load+store for each 226 * scalar member. */ 227 static void emit_walk_copy(Parser* p, FrameSlot dst_slot, 228 const Type* dst_arr_ty, u32 dst_off, 229 FrameSlot src_ptr_slot, const Type* src_ptr_ty, 230 u32 src_off, const Type* ty) { 231 if (ty->kind == TY_STRUCT) { 232 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, ty); 233 for (u16 i = 0; i < ty->rec.nfields; ++i) { 234 const Field* f = &ty->rec.fields[i]; 235 if (f->flags & FIELD_BITFIELD) continue; 236 const Type* fty = init_field_type_at(ty, i); 237 u32 foff = init_field_offset_at(L, i); 238 emit_walk_copy(p, dst_slot, dst_arr_ty, dst_off + foff, src_ptr_slot, 239 src_ptr_ty, src_off + foff, fty); 240 } 241 return; 242 } 243 if (ty->kind == TY_ARRAY) { 244 u32 esz = c_abi_sizeof(p->abi, ty->arr.elem); 245 for (u32 i = 0; i < ty->arr.count; ++i) { 246 emit_walk_copy(p, dst_slot, dst_arr_ty, dst_off + i * esz, src_ptr_slot, 247 src_ptr_ty, src_off + i * esz, ty->arr.elem); 248 } 249 return; 250 } 251 if (ty->kind == TY_UNION) { 252 u32 sz = c_abi_sizeof(p->abi, ty); 253 const Type* uchar_ty = type_prim(p->pool, TY_UCHAR); 254 for (u32 i = 0; i < sz; ++i) { 255 emit_copy_leaf(p, dst_slot, dst_arr_ty, dst_off + i, src_ptr_slot, 256 src_ptr_ty, src_off + i, uchar_ty); 257 } 258 return; 259 } 260 emit_copy_leaf(p, dst_slot, dst_arr_ty, dst_off, src_ptr_slot, src_ptr_ty, 261 src_off, ty); 262 } 263 264 /* Source struct/union value is on top of the cg stack as an lvalue. 265 * Spill its address into a fresh pointer slot, then walk the type and 266 * copy each scalar leaf into the destination sub-object. */ 267 void emit_struct_copy_into_slot(Parser* p, FrameSlot dst_slot, 268 const Type* dst_arr_ty, u32 dst_off, 269 const Type* ty) { 270 const Type* ptr_ty = type_ptr(p->pool, ty); 271 FrameSlotDesc fsd; 272 FrameSlot src_ptr_slot; 273 pcg_addr(p); 274 memset(&fsd, 0, sizeof fsd); 275 fsd.type = ptr_ty; 276 fsd.size = c_abi_sizeof(p->abi, ptr_ty); 277 fsd.align = c_abi_alignof(p->abi, ptr_ty); 278 fsd.kind = FS_LOCAL; 279 fsd.flags = FSF_NONE; 280 src_ptr_slot = pcg_local(p, &fsd); 281 pcg_push_local_typed(p, src_ptr_slot, ptr_ty); 282 pcg_swap(p); 283 pcg_store(p); 284 pcg_drop(p); 285 emit_walk_copy(p, dst_slot, dst_arr_ty, dst_off, src_ptr_slot, ptr_ty, 0, ty); 286 } 287 288 /* Recursively zero-initialize the sub-object at `offset` of type `ty`. */ 289 static void zero_init_at(Parser* p, FrameSlot slot, const Type* arr_ty, 290 u32 offset, const Type* ty) { 291 if (ty->kind == TY_ARRAY) { 292 u32 esz = c_abi_sizeof(p->abi, ty->arr.elem); 293 for (u32 i = 0; i < ty->arr.count; ++i) { 294 zero_init_at(p, slot, arr_ty, offset + i * esz, ty->arr.elem); 295 } 296 return; 297 } 298 if (ty->kind == TY_STRUCT) { 299 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, ty); 300 for (u16 i = 0; i < ty->rec.nfields; ++i) { 301 const Field* f = &ty->rec.fields[i]; 302 if (f->flags & FIELD_ZERO_WIDTH) continue; 303 if (f->flags & FIELD_BITFIELD) { 304 push_record_field_lv(p, slot, arr_ty, offset, ty, i); 305 pcg_push_int(p, 0, f->type); 306 pcg_store(p); 307 pcg_drop(p); 308 continue; 309 } 310 { 311 const Type* fty = init_field_type_at(ty, i); 312 u32 foff = init_field_offset_at(L, i); 313 zero_init_at(p, slot, arr_ty, offset + foff, fty); 314 } 315 } 316 return; 317 } 318 if (ty->kind == TY_UNION) { 319 if (ty->rec.nfields > 0) { 320 const Field* f = &ty->rec.fields[0]; 321 if (!(f->flags & FIELD_BITFIELD)) { 322 zero_init_at(p, slot, arr_ty, offset, f->type); 323 } 324 } 325 return; 326 } 327 push_subobject_lv(p, slot, arr_ty, offset, ty); 328 pcg_push_int(p, 0, ty); 329 pcg_store(p); 330 pcg_drop(p); 331 } 332 333 static void init_field_at(Parser* p, FrameSlot slot, const Type* arr_ty, 334 u32 rec_offset, const Type* rec_ty, u32 field_index) { 335 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, rec_ty); 336 const Field* f = &rec_ty->rec.fields[field_index]; 337 if (f->flags & FIELD_ZERO_WIDTH) return; 338 if (f->flags & FIELD_BITFIELD) { 339 push_record_field_lv(p, slot, arr_ty, rec_offset, rec_ty, field_index); 340 parse_assign_expr(p); 341 to_rvalue(p); 342 { 343 const Type* rhs = pcg_top_type(p); 344 CSemCheck chk = 345 c_sem_check_assignment(p->pool, f->type, rhs, C_SEM_ASSIGN_INIT); 346 if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message))); 347 } 348 coerce_top_to_lvalue(p); 349 pcg_store(p); 350 pcg_drop(p); 351 return; 352 } 353 init_at(p, slot, arr_ty, rec_offset + L->fields[field_index].offset, f->type); 354 } 355 356 /* Emit byte stores for a string literal initializing a char-array sub-object. 357 */ 358 static void init_string_at(Parser* p, FrameSlot slot, const Type* arr_ty, 359 u32 offset, const Type* elem_ty, u32 count) { 360 size_t n = 0; 361 u8* bytes = peek_string_bytes(p, &n); 362 u32 elem_size = c_abi_sizeof(p->abi, elem_ty); 363 size_t elems = elem_size ? n / elem_size : 0; 364 size_t copy = elems; 365 size_t i; 366 if (copy > count) copy = count; 367 for (i = 0; i < copy; ++i) { 368 push_subobject_lv(p, slot, arr_ty, offset + (u32)i * elem_size, elem_ty); 369 pcg_push_int(p, (i64)decode_lit_unit_le(bytes + i * elem_size, elem_size), 370 elem_ty); 371 pcg_store(p); 372 pcg_drop(p); 373 } 374 for (; i < count; ++i) { 375 push_subobject_lv(p, slot, arr_ty, offset + (u32)i * elem_size, elem_ty); 376 pcg_push_int(p, 0, elem_ty); 377 pcg_store(p); 378 pcg_drop(p); 379 } 380 kit_compiler_context(p->c)->heap->free(kit_compiler_context(p->c)->heap, 381 bytes, 0); 382 advance(p); /* consume TOK_STR */ 383 } 384 385 /* Parse a designator chain (`[const]` and `.ident` repeats) ending at `=`. */ 386 static void parse_designator_chain(Parser* p, const Type* outer_ty, 387 u32 outer_offset, const Type** sub_ty_out, 388 u32* sub_offset_out, u32* top_index_out, 389 InitDesignatorCont* cont_out) { 390 const Type* cur_ty = outer_ty; 391 u32 cur_off = outer_offset; 392 int first = 1; 393 InitDesignatorCont cont; 394 memset(&cont, 0, sizeof cont); 395 for (;;) { 396 if (is_punct(&p->cur, '[')) { 397 i64 idx; 398 u32 esz; 399 SrcLoc cloc = tok_loc_init(&p->cur); 400 const Type* parent_ty = cur_ty; 401 u32 parent_off = cur_off; 402 advance(p); 403 idx = eval_const_int(p, cloc); 404 expect_punct(p, ']', "']' after designator index"); 405 if (!cur_ty || cur_ty->kind != TY_ARRAY) { 406 perr(p, "array designator on non-array"); 407 } 408 if (idx < 0 || (u32)idx >= cur_ty->arr.count) { 409 perr(p, "array designator index out of range"); 410 } 411 esz = c_abi_sizeof(p->abi, cur_ty->arr.elem); 412 cur_off += (u32)idx * esz; 413 cur_ty = cur_ty->arr.elem; 414 cont.parent_ty = parent_ty; 415 cont.parent_offset = parent_off; 416 cont.next_index = (u32)idx + 1u; 417 if (first) *top_index_out = (u32)idx; 418 first = 0; 419 } else if (is_punct(&p->cur, '.')) { 420 Sym fname; 421 const Type* fty; 422 u32 foff; 423 const Field* ff; 424 u16 fi; 425 u32 selected_index = 0; 426 int have_selected_index = 0; 427 const Type* parent_ty = cur_ty; 428 u32 parent_off = cur_off; 429 advance(p); 430 if (p->cur.kind != TOK_IDENT || 431 ident_kw_init(p, p->cur.v.ident) != KW_NONE) { 432 perr(p, "expected field name after '.'"); 433 } 434 fname = p->cur.v.ident; 435 advance(p); 436 if (!cur_ty || (cur_ty->kind != TY_STRUCT && cur_ty->kind != TY_UNION)) { 437 perr(p, "field designator on non-record type"); 438 } 439 if (!find_field(p->abi, p->pool, cur_ty, fname, &fty, &foff, &ff)) { 440 perr(p, "no such field in designator"); 441 } 442 cur_off += foff; 443 for (fi = 0; fi < cur_ty->rec.nfields; ++fi) { 444 const Field* g = &cur_ty->rec.fields[fi]; 445 if (g->name == fname && fname != 0) { 446 selected_index = fi; 447 have_selected_index = 1; 448 if (first) { 449 *top_index_out = fi; 450 } 451 break; 452 } 453 if ((g->flags & FIELD_ANON) && 454 (g->type->kind == TY_STRUCT || g->type->kind == TY_UNION)) { 455 const Type* tmp_ty; 456 u32 tmp_off; 457 const Field* tmp_f; 458 if (find_field(p->abi, p->pool, g->type, fname, &tmp_ty, &tmp_off, 459 &tmp_f)) { 460 selected_index = fi; 461 have_selected_index = 1; 462 if (first) { 463 *top_index_out = fi; 464 } 465 break; 466 } 467 } 468 } 469 if (have_selected_index) { 470 cont.parent_ty = parent_ty; 471 cont.parent_offset = parent_off; 472 cont.next_index = selected_index + 1u; 473 } 474 cur_ty = fty; 475 first = 0; 476 } else { 477 break; 478 } 479 } 480 if (first) perr(p, "internal: empty designator chain"); 481 expect_punct(p, '=', "'=' after designator"); 482 *sub_ty_out = cur_ty; 483 *sub_offset_out = cur_off; 484 if (cont_out) *cont_out = cont; 485 } 486 487 static int aggregate_has_index(const Type* ty, u32 index) { 488 if (!ty) return 0; 489 if (ty->kind == TY_ARRAY) return index < ty->arr.count; 490 if (ty->kind == TY_STRUCT) return index < ty->rec.nfields; 491 return 0; 492 } 493 494 static int designator_continues_inside(Parser* p, const Type* outer_ty, 495 u32 outer_offset, const Type* top_ty, 496 u32 top_offset, 497 const InitDesignatorCont* cont) { 498 u32 top_size; 499 if (!cont || !cont->parent_ty) return 0; 500 if (cont->parent_ty == outer_ty && cont->parent_offset == outer_offset) 501 return 0; 502 if (!aggregate_has_index(cont->parent_ty, cont->next_index)) return 0; 503 top_size = c_abi_sizeof(p->abi, top_ty); 504 return cont->parent_offset >= top_offset && 505 cont->parent_offset - top_offset <= top_size; 506 } 507 508 static u32 init_struct_fields(Parser* p, FrameSlot slot, const Type* arr_ty, 509 u32 offset, const Type* ty, u32 start_field, 510 int braced) { 511 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, ty); 512 u32 i = start_field; 513 u32 zero_lo = start_field; 514 /* A braced list may carry designators that re-target any field, including a 515 * field earlier than one already seen, so the running position `i` does not 516 * bound the loop — only '}'/EOF (or, for an unbraced nested list, the field 517 * count) terminates it. */ 518 for (;;) { 519 if (braced) { 520 if (is_punct(&p->cur, '}') || p->cur.kind == TOK_EOF) break; 521 } else if (i >= ty->rec.nfields) { 522 break; 523 } 524 if (braced && is_punct(&p->cur, '.')) { 525 const Type* sub_ty; 526 u32 sub_off; 527 u32 top_idx = 0; 528 InitDesignatorCont cont; 529 parse_designator_chain(p, ty, offset, &sub_ty, &sub_off, &top_idx, &cont); 530 while (zero_lo < top_idx) { 531 const Field* zf = &ty->rec.fields[zero_lo]; 532 if (zf->flags & FIELD_BITFIELD) { 533 if (!(zf->flags & FIELD_ZERO_WIDTH)) { 534 push_record_field_lv(p, slot, arr_ty, offset, ty, zero_lo); 535 pcg_push_int(p, 0, zf->type); 536 pcg_store(p); 537 pcg_drop(p); 538 } 539 } else { 540 u32 zoff = offset + L->fields[zero_lo].offset; 541 zero_init_at(p, slot, arr_ty, zoff, zf->type); 542 } 543 ++zero_lo; 544 } 545 init_at(p, slot, arr_ty, sub_off, sub_ty); 546 { 547 const Field* top_f = &ty->rec.fields[top_idx]; 548 u32 top_off = offset + L->fields[top_idx].offset; 549 if (designator_continues_inside(p, ty, offset, top_f->type, top_off, 550 &cont) && 551 accept_punct(p, ',') && !is_punct(&p->cur, '}')) { 552 init_aggregate_remainder(p, slot, arr_ty, cont.parent_offset, 553 cont.parent_ty, cont.next_index); 554 } 555 } 556 i = top_idx; 557 if (zero_lo <= top_idx) zero_lo = top_idx + 1; 558 goto next_item_struct; 559 } 560 if (i >= ty->rec.nfields) { 561 /* Excess positional initializer with no designator to place it; stop and 562 * let the caller diagnose the missing '}'. */ 563 break; 564 } 565 init_field_at(p, slot, arr_ty, offset, ty, i); 566 if (zero_lo <= i) zero_lo = i + 1; 567 if (!braced) { 568 ++i; 569 break; 570 } 571 next_item_struct: 572 if (!accept_punct(p, ',')) { 573 ++i; 574 break; 575 } 576 if (is_punct(&p->cur, '}')) { 577 ++i; 578 break; 579 } 580 ++i; 581 } 582 if (braced) { 583 u32 j; 584 for (j = zero_lo; j < ty->rec.nfields; ++j) { 585 const Field* f = &ty->rec.fields[j]; 586 if (f->flags & FIELD_BITFIELD) { 587 if (!(f->flags & FIELD_ZERO_WIDTH)) { 588 push_record_field_lv(p, slot, arr_ty, offset, ty, j); 589 pcg_push_int(p, 0, f->type); 590 pcg_store(p); 591 pcg_drop(p); 592 } 593 } else { 594 u32 foff = offset + L->fields[j].offset; 595 zero_init_at(p, slot, arr_ty, foff, f->type); 596 } 597 } 598 } 599 return i; 600 } 601 602 static void init_aggregate_remainder(Parser* p, FrameSlot slot, 603 const Type* arr_ty, u32 offset, 604 const Type* ty, u32 start_index) { 605 if (ty->kind == TY_ARRAY) { 606 u32 esz = c_abi_sizeof(p->abi, ty->arr.elem); 607 u32 i; 608 for (i = start_index; i < ty->arr.count; ++i) { 609 init_at(p, slot, arr_ty, offset + i * esz, ty->arr.elem); 610 if (i + 1u >= ty->arr.count) return; 611 if (!accept_punct(p, ',')) break; 612 if (is_punct(&p->cur, '}')) break; 613 } 614 for (++i; i < ty->arr.count; ++i) { 615 zero_init_at(p, slot, arr_ty, offset + i * esz, ty->arr.elem); 616 } 617 return; 618 } 619 if (ty->kind == TY_STRUCT) { 620 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, ty); 621 u32 i; 622 for (i = start_index; i < ty->rec.nfields; ++i) { 623 init_field_at(p, slot, arr_ty, offset, ty, i); 624 if (i + 1u >= ty->rec.nfields) return; 625 if (!accept_punct(p, ',')) break; 626 if (is_punct(&p->cur, '}')) break; 627 } 628 for (++i; i < ty->rec.nfields; ++i) { 629 const Field* f = &ty->rec.fields[i]; 630 if (f->flags & FIELD_BITFIELD) { 631 if (!(f->flags & FIELD_ZERO_WIDTH)) { 632 push_record_field_lv(p, slot, arr_ty, offset, ty, i); 633 pcg_push_int(p, 0, f->type); 634 pcg_store(p); 635 pcg_drop(p); 636 } 637 } else { 638 const Type* fty = init_field_type_at(ty, i); 639 u32 foff = init_field_offset_at(L, i); 640 zero_init_at(p, slot, arr_ty, offset + foff, fty); 641 } 642 } 643 return; 644 } 645 init_at(p, slot, arr_ty, offset, ty); 646 } 647 648 void init_at(Parser* p, FrameSlot slot, const Type* arr_ty, u32 offset, 649 const Type* ty) { 650 if (ty->kind == TY_ARRAY) { 651 const Type* elem_ty = ty->arr.elem; 652 u32 esz = c_abi_sizeof(p->abi, elem_ty); 653 if (p->cur.kind == TOK_STR && 654 string_literal_initializes_array(p, elem_ty, &p->cur)) { 655 init_string_at(p, slot, arr_ty, offset, elem_ty, ty->arr.count); 656 return; 657 } 658 if (is_punct(&p->cur, '{') && peek1(p).kind == TOK_STR) { 659 Tok str = peek1(p); 660 if (string_literal_initializes_array(p, elem_ty, &str)) { 661 advance(p); 662 init_string_at(p, slot, arr_ty, offset, elem_ty, ty->arr.count); 663 accept_punct(p, ','); 664 expect_punct(p, '}', "'}' after string initializer"); 665 return; 666 } 667 } 668 if (!is_punct(&p->cur, '{')) { 669 init_aggregate_remainder(p, slot, arr_ty, offset, ty, 0); 670 return; 671 } 672 advance(p); /* '{' */ 673 { 674 u32 i = 0; 675 u32 zero_lo = 0; 676 if (!is_punct(&p->cur, '}')) { 677 for (;;) { 678 if (is_punct(&p->cur, '[')) { 679 const Type* sub_ty; 680 u32 sub_off; 681 u32 top_idx = 0; 682 InitDesignatorCont cont; 683 parse_designator_chain(p, ty, offset, &sub_ty, &sub_off, &top_idx, 684 &cont); 685 while (zero_lo < top_idx) { 686 zero_init_at(p, slot, arr_ty, offset + zero_lo * esz, elem_ty); 687 ++zero_lo; 688 } 689 init_at(p, slot, arr_ty, sub_off, sub_ty); 690 if (designator_continues_inside(p, ty, offset, elem_ty, 691 offset + top_idx * esz, &cont) && 692 accept_punct(p, ',') && !is_punct(&p->cur, '}')) { 693 init_aggregate_remainder(p, slot, arr_ty, cont.parent_offset, 694 cont.parent_ty, cont.next_index); 695 } 696 i = top_idx + 1; 697 if (zero_lo < i) zero_lo = i; 698 } else { 699 if (i >= ty->arr.count) { 700 perr(p, "too many initializers for array"); 701 } 702 init_at(p, slot, arr_ty, offset + i * esz, elem_ty); 703 ++i; 704 if (zero_lo < i) zero_lo = i; 705 } 706 if (!accept_punct(p, ',')) break; 707 if (is_punct(&p->cur, '}')) break; 708 } 709 } 710 expect_punct(p, '}', "'}' after array initializer"); 711 { 712 u32 j; 713 for (j = zero_lo; j < ty->arr.count; ++j) { 714 zero_init_at(p, slot, arr_ty, offset + j * esz, elem_ty); 715 } 716 } 717 } 718 return; 719 } 720 if (ty->kind == TY_STRUCT) { 721 if (!is_punct(&p->cur, '{')) { 722 if (try_init_aggregate_from_expr(p, slot, arr_ty, offset, ty)) return; 723 init_aggregate_remainder(p, slot, arr_ty, offset, ty, 0); 724 return; 725 } 726 advance(p); /* '{' */ 727 zero_object_bytes_at(p, slot, arr_ty, offset, ty); 728 init_struct_fields(p, slot, arr_ty, offset, ty, 0, /*braced=*/1); 729 expect_punct(p, '}', "'}' after struct initializer"); 730 return; 731 } 732 if (ty->kind == TY_UNION) { 733 int had_brace = accept_punct(p, '{'); 734 if (!had_brace && 735 try_init_aggregate_from_expr(p, slot, arr_ty, offset, ty)) { 736 return; 737 } 738 if (ty->rec.nfields == 0) { 739 if (had_brace) expect_punct(p, '}', "'}'"); 740 return; 741 } 742 if (had_brace && is_punct(&p->cur, '.')) { 743 const Type* sub_ty; 744 u32 sub_off; 745 u32 top_idx = 0; 746 parse_designator_chain(p, ty, offset, &sub_ty, &sub_off, &top_idx, NULL); 747 init_at(p, slot, arr_ty, sub_off, sub_ty); 748 } else { 749 const Field* f = &ty->rec.fields[0]; 750 if (!(f->flags & FIELD_BITFIELD)) { 751 init_at(p, slot, arr_ty, offset, f->type); 752 } 753 } 754 if (had_brace) { 755 accept_punct(p, ','); 756 expect_punct(p, '}', "'}' after union initializer"); 757 } 758 return; 759 } 760 /* Scalar (incl. pointer). */ 761 int had_brace = accept_punct(p, '{'); 762 push_subobject_lv(p, slot, arr_ty, offset, ty); 763 parse_assign_expr(p); 764 to_rvalue(p); 765 { 766 const Type* rhs = pcg_top_type(p); 767 CSemCheck chk = c_sem_check_assignment(p->pool, ty, rhs, C_SEM_ASSIGN_INIT); 768 if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message))); 769 } 770 coerce_top_to_lvalue(p); 771 pcg_store(p); 772 pcg_drop(p); 773 if (had_brace) { 774 accept_punct(p, ','); 775 expect_punct(p, '}', "'}' after scalar initializer"); 776 } 777 } 778 779 /* ============================================================ 780 * Static-storage initializers 781 * ============================================================ */ 782 783 void encode_int_le(u8* dst, u32 size, i64 v) { 784 for (u32 i = 0; i < size; ++i) { 785 dst[i] = (u8)((v >> (8u * i)) & 0xffu); 786 } 787 } 788 789 static u64 decode_uint_le(const u8* src, u32 size) { 790 u64 v = 0; 791 if (size > 8) size = 8; 792 for (u32 i = 0; i < size; ++i) { 793 v |= (u64)src[i] << (8u * i); 794 } 795 return v; 796 } 797 798 static void encode_uint_le(u8* dst, u32 size, u64 v) { 799 if (size > 8) size = 8; 800 for (u32 i = 0; i < size; ++i) { 801 dst[i] = (u8)((v >> (8u * i)) & 0xffu); 802 } 803 } 804 805 static void encode_uint128_le(u8* dst, u32 size, u64 lo, u64 hi) { 806 if (size > 16) size = 16; 807 for (u32 i = 0; i < size; ++i) { 808 u64 lane = i < 8u ? lo : hi; 809 dst[i] = (u8)((lane >> (8u * (i & 7u))) & 0xffu); 810 } 811 } 812 813 static void encode_binary128_from_double_le(u8 out[16], double value) { 814 union { 815 double d; 816 u64 u; 817 } in; 818 u64 lo = 0; 819 u64 hi = 0; 820 u64 frac; 821 u32 sign; 822 u32 exp; 823 in.d = value; 824 sign = (u32)(in.u >> 63); 825 exp = (u32)((in.u >> 52) & 0x7ffu); 826 frac = in.u & 0x000fffffffffffffull; 827 if (sign) hi |= 1ull << 63; 828 if (exp == 0x7ffu) { 829 hi |= (u64)0x7fffu << 48; 830 if (frac) { 831 lo |= (frac & 0xfu) << 60; 832 hi |= frac >> 4; 833 hi |= 1ull << 47; 834 } 835 } else if (exp != 0 || frac != 0) { 836 i32 e; 837 u64 sig; 838 if (exp == 0) { 839 e = -1022; 840 sig = frac; 841 while ((sig & (1ull << 52)) == 0) { 842 sig <<= 1; 843 --e; 844 } 845 frac = sig & 0x000fffffffffffffull; 846 } else { 847 e = (i32)exp - 1023; 848 } 849 hi |= (u64)(u32)(e + 16383) << 48; 850 lo |= (frac & 0xfu) << 60; 851 hi |= frac >> 4; 852 } 853 encode_uint128_le(out, 16, lo, hi); 854 } 855 856 static double parse_static_float_add(Parser* p); 857 858 static double parse_static_float_primary(Parser* p) { 859 double v; 860 if (accept_punct(p, '+')) return parse_static_float_primary(p); 861 if (accept_punct(p, '-')) return -parse_static_float_primary(p); 862 if (accept_punct(p, '(')) { 863 v = parse_static_float_add(p); 864 expect_punct(p, ')', "')' in floating constant expression"); 865 return v; 866 } 867 if (p->cur.kind == TOK_FLT) { 868 v = parse_float_literal(p, &p->cur); 869 advance(p); 870 return v; 871 } 872 if (p->cur.kind == TOK_NUM) { 873 v = (double)parse_int_literal(p, &p->cur); 874 advance(p); 875 return v; 876 } 877 perr(p, "expected floating constant expression"); 878 return 0.0; 879 } 880 881 static double parse_static_float_mul(Parser* p) { 882 double v = parse_static_float_primary(p); 883 for (;;) { 884 if (accept_punct(p, '*')) { 885 v *= parse_static_float_primary(p); 886 } else if (accept_punct(p, '/')) { 887 v /= parse_static_float_primary(p); 888 } else { 889 return v; 890 } 891 } 892 } 893 894 static double parse_static_float_add(Parser* p) { 895 double v = parse_static_float_mul(p); 896 for (;;) { 897 if (accept_punct(p, '+')) { 898 v += parse_static_float_mul(p); 899 } else if (accept_punct(p, '-')) { 900 v -= parse_static_float_mul(p); 901 } else { 902 return v; 903 } 904 } 905 } 906 907 static int try_parse_static_float(Parser* p, u8* dst, u32 size, 908 const Type* ty) { 909 const Type* uty = type_unqual(p->pool, ty); 910 double value; 911 if (!uty || (uty->kind != TY_FLOAT && uty->kind != TY_DOUBLE && 912 uty->kind != TY_LDOUBLE)) { 913 return 0; 914 } 915 value = parse_static_float_add(p); 916 if (uty->kind == TY_FLOAT && size == 4u) { 917 union { 918 float f; 919 u8 b[4]; 920 } u; 921 u.f = (float)value; 922 memcpy(dst, u.b, 4); 923 return 1; 924 } 925 if ((uty->kind == TY_DOUBLE || uty->kind == TY_LDOUBLE) && size == 8u) { 926 union { 927 double d; 928 u8 b[8]; 929 } u; 930 u.d = value; 931 memcpy(dst, u.b, 8); 932 return 1; 933 } 934 if (uty->kind == TY_LDOUBLE && size == 16u) { 935 encode_binary128_from_double_le(dst, value); 936 return 1; 937 } 938 perr(p, "unsupported static floating initializer type"); 939 return 0; 940 } 941 942 /* Encode a string literal at *buf+offset for a char-array sub-object. */ 943 static void parse_static_string_at(Parser* p, u8* buf, u32 buflen, u32 offset, 944 const Type* elem_ty, u32 count) { 945 size_t n = 0; 946 u8* bytes = peek_string_bytes(p, &n); 947 u32 elem_size = c_abi_sizeof(p->abi, elem_ty); 948 size_t elems = elem_size ? n / elem_size : 0; 949 size_t copy = elems; 950 size_t copy_bytes; 951 if (copy > count) copy = count; 952 copy_bytes = copy * elem_size; 953 if (offset + (u32)copy_bytes > buflen) 954 perr(p, "string initializer overflows object"); 955 memcpy(buf + offset, bytes, copy_bytes); 956 kit_compiler_context(p->c)->heap->free(kit_compiler_context(p->c)->heap, 957 bytes, 0); 958 advance(p); 959 } 960 961 /* Append one pending relocation to the parser-side list. */ 962 void srl_push(Parser* p, u32 offset, u32 size, ObjSymId target, i64 addend) { 963 if (p->static_relocs_len == p->static_relocs_cap) { 964 u32 nc = p->static_relocs_cap ? p->static_relocs_cap * 2u : 4u; 965 void* nb = arena_array(p->pool->arena, StaticReloc, nc); 966 if (!nb) perr(p, "out of memory recording static relocs"); 967 if (p->static_relocs && p->static_relocs_len) { 968 memcpy(nb, p->static_relocs, 969 p->static_relocs_len * sizeof(*p->static_relocs)); 970 } 971 p->static_relocs = nb; 972 p->static_relocs_cap = nc; 973 } 974 p->static_relocs[p->static_relocs_len].offset = offset; 975 p->static_relocs[p->static_relocs_len].size = size; 976 p->static_relocs[p->static_relocs_len].target = target; 977 p->static_relocs[p->static_relocs_len].addend = addend; 978 p->static_relocs[p->static_relocs_len].label = 0; 979 p->static_relocs[p->static_relocs_len].is_label = 0; 980 ++p->static_relocs_len; 981 } 982 983 /* Append one pending label-address relocation (&&label) to the list. */ 984 void srl_push_label(Parser* p, u32 offset, u32 size, CGLabel label, 985 i64 addend) { 986 srl_push(p, offset, size, 0, addend); 987 p->static_relocs[p->static_relocs_len - 1u].label = label; 988 p->static_relocs[p->static_relocs_len - 1u].is_label = 1; 989 } 990 991 typedef enum CStaticConstKind { 992 C_STATIC_CONST_INT, 993 C_STATIC_CONST_NULL_PTR, 994 C_STATIC_CONST_ADDR, 995 C_STATIC_CONST_LABEL_ADDR, /* &&label in a static pointer initializer */ 996 } CStaticConstKind; 997 998 typedef struct CStaticConst { 999 CStaticConstKind kind; 1000 CConstInt int_value; 1001 ObjSymId target; 1002 i64 addend; 1003 CGLabel label; /* valid when kind == C_STATIC_CONST_LABEL_ADDR */ 1004 } CStaticConst; 1005 1006 typedef struct StaticRelocSave { 1007 void* relocs; 1008 u32 len; 1009 u32 cap; 1010 } StaticRelocSave; 1011 1012 static Sym mint_compound_literal_sym(Parser* p) { 1013 static const char prefix[] = "__kit_compound_literal."; 1014 char buf[sizeof(prefix) + 12u]; 1015 u32 wlen = 0; 1016 u32 id = ++p->compound_literal_counter; 1017 for (u32 i = 0; prefix[i] != 0; ++i) { 1018 buf[wlen++] = prefix[i]; 1019 } 1020 { 1021 char digits[12]; 1022 int dn = 0; 1023 if (id == 0) digits[dn++] = '0'; 1024 while (id) { 1025 digits[dn++] = (char)('0' + (id % 10u)); 1026 id /= 10u; 1027 } 1028 while (dn) buf[wlen++] = digits[--dn]; 1029 } 1030 return kit_sym_intern(p->pool->c, (KitSlice){.s = buf, .len = wlen}); 1031 } 1032 1033 static void static_relocs_swap_empty(Parser* p, StaticRelocSave* save) { 1034 save->relocs = p->static_relocs; 1035 save->len = p->static_relocs_len; 1036 save->cap = p->static_relocs_cap; 1037 p->static_relocs = NULL; 1038 p->static_relocs_len = 0; 1039 p->static_relocs_cap = 0; 1040 } 1041 1042 static void static_relocs_restore(Parser* p, const StaticRelocSave* save) { 1043 p->static_relocs = save->relocs; 1044 p->static_relocs_len = save->len; 1045 p->static_relocs_cap = save->cap; 1046 } 1047 1048 static ObjSymId define_static_compound_literal(Parser* p, const Type* lit_ty, 1049 SrcLoc loc) { 1050 Decl decl_in; 1051 DeclId did; 1052 ObjSymId sym; 1053 StaticRelocSave relocs; 1054 1055 if (p->cur_func_name != 0) { 1056 perr(p, "block-scope compound literal is not a static address constant"); 1057 } 1058 if (lit_ty && lit_ty->kind == TY_ARRAY && lit_ty->arr.incomplete) { 1059 lit_ty = complete_incomplete_array(p, lit_ty); 1060 } 1061 1062 memset(&decl_in, 0, sizeof decl_in); 1063 decl_in.name = mint_compound_literal_sym(p); 1064 decl_in.type = lit_ty; 1065 decl_in.loc = loc; 1066 decl_in.storage = DS_STATIC; 1067 decl_in.linkage = DL_INTERNAL; 1068 decl_in.visibility = SV_DEFAULT; 1069 did = decl_declare(p->decls, &decl_in); 1070 sym = decl_obj_sym(p->decls, did); 1071 1072 static_relocs_swap_empty(p, &relocs); 1073 define_static_object(p, sym, decl_in.section_id, lit_ty, 1074 lit_ty ? lit_ty->qual : 0, /*has_init=*/1, loc, 1075 decl_in.align); 1076 static_relocs_restore(p, &relocs); 1077 return sym; 1078 } 1079 1080 static CStaticConst parse_static_compound_literal_after_type(Parser* p, 1081 const Type* lit_ty, 1082 SrcLoc loc) { 1083 CStaticConst r; 1084 memset(&r, 0, sizeof r); 1085 if (!is_punct(&p->cur, '{')) { 1086 perr(p, "expected compound literal initializer in static initializer"); 1087 } 1088 r.kind = C_STATIC_CONST_ADDR; 1089 r.target = define_static_compound_literal(p, lit_ty, loc); 1090 r.addend = 0; 1091 return r; 1092 } 1093 1094 static CConstInt int_bits_for_type(Parser* p, CConstInt v, const Type* ty) { 1095 u32 sz = c_abi_sizeof(p->abi, ty); 1096 v.type = ty; 1097 if (sz < 8u) { 1098 u32 bits = sz * 8u; 1099 v.lo &= bits ? ((1ull << bits) - 1ull) : 0; 1100 v.hi = 0; 1101 } else if (sz == 8u) { 1102 v.hi = 0; 1103 } else if (sz < 16u) { 1104 u32 hi_bits = sz * 8u - 64u; 1105 v.hi &= hi_bits ? ((1ull << hi_bits) - 1ull) : 0; 1106 } 1107 if (ty && ty->kind == TY_BOOL) { 1108 v.lo = (v.lo || v.hi) ? 1u : 0u; 1109 v.hi = 0; 1110 } 1111 return v; 1112 } 1113 1114 static void check_static_integer_initializer_range(Parser* p, const Type* ty, 1115 CConstInt v) { 1116 const Type* dst = type_unqual(p->pool, ty); 1117 u32 bits; 1118 if (!dst || !type_is_int(dst) || dst->kind == TY_BOOL) return; 1119 if (dst->kind == TY_CHAR) return; 1120 if (!c_abi_type_info(p->abi, dst).signed_) return; 1121 bits = c_abi_sizeof(p->abi, dst) * 8u; 1122 if (bits < 64u) { 1123 i64 minv = -(1ll << (bits - 1u)); 1124 i64 maxv = (1ll << (bits - 1u)) - 1ll; 1125 if (c_abi_type_info(p->abi, v.type).signed_) { 1126 i64 sv = const_int_as_i64(p, v); 1127 if (sv < minv || sv > maxv) { 1128 perr(p, "initializer value overflows destination type"); 1129 } 1130 } else { 1131 u64 maxu = (u64)maxv; 1132 if (v.hi != 0 || v.lo > maxu) { 1133 perr(p, "initializer value overflows destination type"); 1134 } 1135 } 1136 } 1137 } 1138 1139 static CConstInt parse_null_pointer_constant(Parser* p, SrcLoc loc) { 1140 if (is_punct(&p->cur, '(')) { 1141 Tok n = peek1(p); 1142 if (starts_type_name(p, &n)) { 1143 const Type* cast_ty; 1144 const Type* cast_unqual; 1145 advance(p); 1146 cast_ty = parse_type_name(p); 1147 cast_unqual = type_unqual(p->pool, cast_ty); 1148 expect_punct(p, ')', "')' after cast in null pointer constant"); 1149 if (!cast_unqual || 1150 (cast_unqual->kind != TY_PTR && cast_unqual->kind != TY_VOID && 1151 !type_is_int(cast_unqual))) { 1152 perr(p, "invalid cast in null pointer constant"); 1153 } 1154 return parse_null_pointer_constant(p, loc); 1155 } 1156 if (is_punct(&n, '(')) { 1157 advance(p); 1158 { 1159 CConstInt v = parse_null_pointer_constant(p, loc); 1160 expect_punct(p, ')', "')' in null pointer constant"); 1161 return v; 1162 } 1163 } 1164 } 1165 return eval_const_int_typed(p, loc); 1166 } 1167 1168 /* Try to parse the current expression as a static initializer address 1169 * constant. Leaves non-address expressions untouched. */ 1170 static int try_parse_static_address_const(Parser* p, CStaticConst* out) { 1171 Tok t = p->cur; 1172 Sym name = 0; 1173 int saw_amp = 0; 1174 i64 element_addend = 0; 1175 i64 byte_addend = 0; 1176 SymEntry* e; 1177 const Type* tgt_ty; 1178 ObjSymId tgt; 1179 if (t.kind == TOK_STR) { 1180 size_t n = 0; 1181 u8* bytes = decode_string_literal(p, &t, &n); 1182 const Type* elem_ty = string_literal_elem_type(p, &t); 1183 ObjSymId str_sym = emit_string_literal_to_rodata(p, bytes, n, elem_ty); 1184 kit_compiler_context(p->c)->heap->free(kit_compiler_context(p->c)->heap, 1185 bytes, 0); 1186 advance(p); 1187 out->kind = C_STATIC_CONST_ADDR; 1188 out->target = str_sym; 1189 out->addend = 0; 1190 return 1; 1191 } 1192 if (is_punct(&t, '&')) { 1193 saw_amp = 1; 1194 advance(p); 1195 if (is_punct(&p->cur, '(')) { 1196 Tok n = peek1(p); 1197 if (starts_type_name(p, &n)) { 1198 const Type* lit_ty; 1199 advance(p); 1200 lit_ty = parse_type_name(p); 1201 expect_punct(p, ')', "')' after compound literal type-name"); 1202 *out = parse_static_compound_literal_after_type(p, lit_ty, t.loc); 1203 return 1; 1204 } 1205 } 1206 if (p->cur.kind != TOK_IDENT || 1207 ident_kw_init(p, p->cur.v.ident) != KW_NONE) { 1208 perr(p, "expected identifier after '&' in static initializer"); 1209 } 1210 name = p->cur.v.ident; 1211 advance(p); 1212 } else if (t.kind == TOK_IDENT && ident_kw_init(p, t.v.ident) == KW_NONE) { 1213 name = t.v.ident; 1214 advance(p); 1215 } else { 1216 return 0; 1217 } 1218 e = scope_lookup(p, name); 1219 if (!e || (e->kind != SEK_GLOBAL && e->kind != SEK_FUNC)) { 1220 perr(p, "static initializer is not a constant address expression"); 1221 } 1222 tgt = e->v.sym; 1223 tgt_ty = e->type; 1224 if (saw_amp && is_punct(&p->cur, '[')) { 1225 SrcLoc cloc; 1226 advance(p); 1227 cloc = tok_loc_init(&p->cur); 1228 element_addend = eval_const_int(p, cloc); 1229 expect_punct(p, ']', "']' after array-subscript constant"); 1230 if (tgt_ty && tgt_ty->kind == TY_ARRAY) { 1231 byte_addend += 1232 element_addend * (i64)c_abi_sizeof(p->abi, tgt_ty->arr.elem); 1233 } else { 1234 byte_addend += element_addend; 1235 } 1236 } 1237 while (is_punct(&p->cur, '+') || is_punct(&p->cur, '-')) { 1238 int neg = is_punct(&p->cur, '-'); 1239 SrcLoc cloc; 1240 i64 v; 1241 advance(p); 1242 cloc = tok_loc_init(&p->cur); 1243 v = eval_const_int(p, cloc); 1244 if (neg) v = -v; 1245 if (tgt_ty && tgt_ty->kind == TY_ARRAY) { 1246 byte_addend += v * (i64)c_abi_sizeof(p->abi, tgt_ty->arr.elem); 1247 } else if (tgt_ty && tgt_ty->kind == TY_PTR) { 1248 byte_addend += v * (i64)c_abi_sizeof(p->abi, tgt_ty->ptr.pointee); 1249 } else if (saw_amp) { 1250 byte_addend += v * (i64)c_abi_sizeof(p->abi, tgt_ty); 1251 } else { 1252 byte_addend += v; 1253 } 1254 } 1255 out->kind = C_STATIC_CONST_ADDR; 1256 out->target = tgt; 1257 out->addend = byte_addend; 1258 return 1; 1259 } 1260 1261 static CStaticConst parse_static_const(Parser* p, const Type* ty, SrcLoc loc) { 1262 CStaticConst r; 1263 memset(&r, 0, sizeof r); 1264 r.kind = C_STATIC_CONST_INT; 1265 if (ty && ty->kind == TY_PTR) { 1266 if (is_punct(&p->cur, P_AND)) { 1267 /* GNU labels-as-values: `&&label` in a static pointer initializer, 1268 * e.g. a direct-threaded dispatch table `static void *tab[] = {...}`. */ 1269 Sym lname; 1270 SrcLoc lloc; 1271 advance(p); /* '&&' */ 1272 if (p->cur.kind != TOK_IDENT || 1273 ident_kw_init(p, p->cur.v.ident) != KW_NONE) { 1274 perr(p, "expected label name after '&&' in static initializer"); 1275 } 1276 lname = p->cur.v.ident; 1277 lloc = tok_loc_init(&p->cur); 1278 advance(p); 1279 r.kind = C_STATIC_CONST_LABEL_ADDR; 1280 r.label = take_label_addr(p, lname, lloc); 1281 r.addend = 0; 1282 return r; 1283 } 1284 if (is_punct(&p->cur, '(')) { 1285 Tok n = peek1(p); 1286 /* Grouping parens around the pointer initializer, e.g. `("str")`, 1287 * `(&x)`, or `((expr))`. A `(type-name)` is a cast or compound literal 1288 * and is handled below, so peel only when the inner token does not start 1289 * a type-name. */ 1290 if (!starts_type_name(p, &n)) { 1291 advance(p); 1292 r = parse_static_const(p, ty, loc); 1293 expect_punct(p, ')', "')' in static pointer initializer"); 1294 return r; 1295 } 1296 } 1297 if (is_punct(&p->cur, '(')) { 1298 Tok n = peek1(p); 1299 if (starts_type_name(p, &n)) { 1300 const Type* cast_ty; 1301 const Type* cast_unqual; 1302 advance(p); 1303 cast_ty = parse_type_name(p); 1304 cast_unqual = type_unqual(p->pool, cast_ty); 1305 expect_punct(p, ')', "')' after cast or compound literal type-name"); 1306 if (is_punct(&p->cur, '{')) { 1307 const Type* lit_unqual = type_unqual(p->pool, cast_ty); 1308 if (!lit_unqual || lit_unqual->kind != TY_ARRAY) { 1309 perr(p, 1310 "non-array compound literal needs '&' in pointer initializer"); 1311 } 1312 return parse_static_compound_literal_after_type(p, cast_ty, loc); 1313 } 1314 if (!cast_unqual || 1315 (cast_unqual->kind != TY_PTR && cast_unqual->kind != TY_VOID && 1316 !type_is_int(cast_unqual))) { 1317 perr(p, "invalid cast in null pointer constant"); 1318 } 1319 if (cast_unqual->kind == TY_PTR && 1320 (p->cur.kind == TOK_STR || is_punct(&p->cur, '&') || 1321 (p->cur.kind == TOK_IDENT && 1322 ident_kw_init(p, p->cur.v.ident) == KW_NONE)) && 1323 try_parse_static_address_const(p, &r)) { 1324 return r; 1325 } 1326 r.int_value = parse_null_pointer_constant(p, loc); 1327 if (const_int_as_i64(p, r.int_value) != 0 && 1328 cast_unqual->kind == TY_PTR) { 1329 r.kind = C_STATIC_CONST_INT; 1330 return r; 1331 } 1332 if (const_int_as_i64(p, r.int_value) != 0) { 1333 perr(p, "static pointer initializer is not a null pointer constant"); 1334 } 1335 r.kind = C_STATIC_CONST_NULL_PTR; 1336 return r; 1337 } 1338 } 1339 if (try_parse_static_address_const(p, &r)) return r; 1340 r.int_value = parse_null_pointer_constant(p, loc); 1341 if (const_int_as_i64(p, r.int_value) != 0) { 1342 perr(p, "static pointer initializer is not a null pointer constant"); 1343 } 1344 r.kind = C_STATIC_CONST_NULL_PTR; 1345 return r; 1346 } 1347 r.int_value = eval_const_int_typed(p, loc); 1348 check_static_integer_initializer_range(p, ty, r.int_value); 1349 return r; 1350 } 1351 1352 static void parse_static_bitfield_at(Parser* p, u8* buf, u32 buflen, 1353 u32 rec_offset, const ABIFieldLayout* fl, 1354 const Type* field_ty) { 1355 SrcLoc cloc = tok_loc_init(&p->cur); 1356 CStaticConst parsed = parse_static_const(p, field_ty, cloc); 1357 u32 storage_off = rec_offset + fl->offset; 1358 u32 storage_size = fl->storage_size; 1359 u32 width = fl->bit_width; 1360 u32 lsb = fl->bit_offset; 1361 u64 ones; 1362 u64 mask; 1363 u64 cur; 1364 u64 val; 1365 if (parsed.kind != C_STATIC_CONST_INT) { 1366 perr(p, "bit-field initializer requires integer constant expression"); 1367 } 1368 if (width == 0) return; 1369 if (storage_size > 8) perr(p, "bit-field storage unit too wide"); 1370 if (storage_off > buflen || storage_size > buflen - storage_off) 1371 perr(p, "initializer overflows object"); 1372 ones = width >= 64u ? ~(u64)0 : (((u64)1 << width) - 1u); 1373 mask = ones << lsb; 1374 cur = decode_uint_le(buf + storage_off, storage_size); 1375 val = (int_bits_for_type(p, parsed.int_value, field_ty).lo & ones) << lsb; 1376 cur = (cur & ~mask) | val; 1377 encode_uint_le(buf + storage_off, storage_size, cur); 1378 } 1379 1380 static void parse_static_aggregate_remainder(Parser* p, u8* buf, u32 buflen, 1381 u32 offset, const Type* ty, 1382 u32 start_index) { 1383 if (ty->kind == TY_ARRAY) { 1384 const Type* elem = ty->arr.elem; 1385 u32 esz = c_abi_sizeof(p->abi, elem); 1386 u32 i; 1387 for (i = start_index; i < ty->arr.count; ++i) { 1388 parse_static_init_at(p, buf, buflen, offset + i * esz, elem); 1389 if (i + 1u >= ty->arr.count) return; 1390 if (!accept_punct(p, ',')) break; 1391 if (is_punct(&p->cur, '}')) break; 1392 } 1393 return; 1394 } 1395 if (ty->kind == TY_STRUCT) { 1396 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, ty); 1397 u32 i; 1398 for (i = start_index; i < ty->rec.nfields; ++i) { 1399 const Field* f = &ty->rec.fields[i]; 1400 if (f->flags & FIELD_BITFIELD) { 1401 if (!(f->flags & FIELD_ZERO_WIDTH)) { 1402 parse_static_bitfield_at(p, buf, buflen, offset, &L->fields[i], 1403 f->type); 1404 } 1405 } else { 1406 const Type* fty = init_field_type_at(ty, i); 1407 u32 foff = init_field_offset_at(L, i); 1408 parse_static_init_at(p, buf, buflen, offset + foff, fty); 1409 } 1410 if (i + 1u >= ty->rec.nfields) return; 1411 if (!accept_punct(p, ',')) break; 1412 if (is_punct(&p->cur, '}')) break; 1413 } 1414 return; 1415 } 1416 parse_static_init_at(p, buf, buflen, offset, ty); 1417 } 1418 1419 void parse_static_init_at(Parser* p, u8* buf, u32 buflen, u32 offset, 1420 const Type* ty) { 1421 /* An aggregate object may be initialized by a (possibly parenthesized) 1422 * compound literal of its own type: `static T x = (T){...};` or, after macro 1423 * expansion, `static T x = ((T){...});`. Strip the `(type-name)` cast so the 1424 * brace body below initializes the object in place; peel grouping parens by 1425 * recursing and matching the closing ')'. Pointer/scalar targets keep their 1426 * own handling (parse_static_const / eval_const), where a compound literal 1427 * can instead yield an address or value. */ 1428 if ((ty->kind == TY_STRUCT || ty->kind == TY_UNION || ty->kind == TY_ARRAY) && 1429 is_punct(&p->cur, '(')) { 1430 Tok n = peek1(p); 1431 if (starts_type_name(p, &n)) { 1432 advance(p); 1433 parse_type_name(p); 1434 expect_punct(p, ')', "')' after compound literal type-name"); 1435 } else if (is_punct(&n, '(')) { 1436 advance(p); 1437 parse_static_init_at(p, buf, buflen, offset, ty); 1438 expect_punct(p, ')', "')' after parenthesized initializer"); 1439 return; 1440 } 1441 } 1442 if (ty->kind == TY_ARRAY) { 1443 const Type* elem = ty->arr.elem; 1444 u32 esz = c_abi_sizeof(p->abi, elem); 1445 u32 i = 0; 1446 int had_brace; 1447 if (p->cur.kind == TOK_STR && 1448 string_literal_initializes_array(p, elem, &p->cur)) { 1449 parse_static_string_at(p, buf, buflen, offset, elem, ty->arr.count); 1450 return; 1451 } 1452 if (is_punct(&p->cur, '{') && peek1(p).kind == TOK_STR) { 1453 Tok str = peek1(p); 1454 if (string_literal_initializes_array(p, elem, &str)) { 1455 advance(p); 1456 parse_static_string_at(p, buf, buflen, offset, elem, ty->arr.count); 1457 accept_punct(p, ','); 1458 expect_punct(p, '}', "'}' after string initializer"); 1459 return; 1460 } 1461 } 1462 had_brace = accept_punct(p, '{'); 1463 if (!had_brace) { 1464 parse_static_aggregate_remainder(p, buf, buflen, offset, ty, 0); 1465 return; 1466 } 1467 if (!is_punct(&p->cur, '}')) { 1468 for (;;) { 1469 if (is_punct(&p->cur, '[')) { 1470 const Type* sub_ty; 1471 u32 sub_off; 1472 u32 top_idx = 0; 1473 InitDesignatorCont cont; 1474 parse_designator_chain(p, ty, offset, &sub_ty, &sub_off, &top_idx, 1475 &cont); 1476 parse_static_init_at(p, buf, buflen, sub_off, sub_ty); 1477 if (designator_continues_inside(p, ty, offset, elem, 1478 offset + top_idx * esz, &cont) && 1479 accept_punct(p, ',') && !is_punct(&p->cur, '}')) { 1480 parse_static_aggregate_remainder(p, buf, buflen, cont.parent_offset, 1481 cont.parent_ty, cont.next_index); 1482 } 1483 i = top_idx + 1; 1484 } else { 1485 if (i >= ty->arr.count) { 1486 perr(p, "too many initializers for array"); 1487 } 1488 parse_static_init_at(p, buf, buflen, offset + i * esz, elem); 1489 ++i; 1490 } 1491 if (!accept_punct(p, ',')) break; 1492 if (is_punct(&p->cur, '}')) break; 1493 } 1494 } 1495 expect_punct(p, '}', "'}' after array initializer"); 1496 return; 1497 } 1498 if (ty->kind == TY_STRUCT) { 1499 int had_brace = accept_punct(p, '{'); 1500 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, ty); 1501 u32 i = 0; 1502 if (!had_brace) { 1503 parse_static_aggregate_remainder(p, buf, buflen, offset, ty, 0); 1504 return; 1505 } 1506 /* Designators may re-target any field regardless of the running position 1507 * `i`, so the loop is bounded by '}'/EOF; `i` only drives positional 1508 * placement (and is range-checked before use). */ 1509 while (!is_punct(&p->cur, '}') && p->cur.kind != TOK_EOF) { 1510 const Field* f; 1511 if (is_punct(&p->cur, '.')) { 1512 const Type* sub_ty; 1513 u32 sub_off; 1514 u32 top_idx = 0; 1515 InitDesignatorCont cont; 1516 parse_designator_chain(p, ty, offset, &sub_ty, &sub_off, &top_idx, 1517 &cont); 1518 parse_static_init_at(p, buf, buflen, sub_off, sub_ty); 1519 { 1520 const Field* top_f = &ty->rec.fields[top_idx]; 1521 u32 top_off = offset + L->fields[top_idx].offset; 1522 if (designator_continues_inside(p, ty, offset, top_f->type, top_off, 1523 &cont) && 1524 accept_punct(p, ',') && !is_punct(&p->cur, '}')) { 1525 parse_static_aggregate_remainder(p, buf, buflen, cont.parent_offset, 1526 cont.parent_ty, cont.next_index); 1527 } 1528 } 1529 i = top_idx + 1; 1530 if (!accept_punct(p, ',')) break; 1531 continue; 1532 } 1533 if (i >= ty->rec.nfields) break; /* excess positional initializer */ 1534 f = &ty->rec.fields[i]; 1535 if (f->flags & FIELD_BITFIELD) { 1536 if (!(f->flags & FIELD_ZERO_WIDTH)) { 1537 parse_static_bitfield_at(p, buf, buflen, offset, &L->fields[i], 1538 f->type); 1539 } 1540 } else { 1541 const Type* fty = init_field_type_at(ty, i); 1542 u32 foff = init_field_offset_at(L, i); 1543 parse_static_init_at(p, buf, buflen, offset + foff, fty); 1544 } 1545 ++i; 1546 if (!accept_punct(p, ',')) break; 1547 } 1548 expect_punct(p, '}', "'}' after struct initializer"); 1549 return; 1550 } 1551 if (ty->kind == TY_UNION) { 1552 int had_brace = accept_punct(p, '{'); 1553 if (ty->rec.nfields == 0) { 1554 if (had_brace) expect_punct(p, '}', "'}' after union initializer"); 1555 return; 1556 } 1557 if (had_brace && is_punct(&p->cur, '.')) { 1558 const Type* sub_ty; 1559 u32 sub_off; 1560 u32 top_idx = 0; 1561 parse_designator_chain(p, ty, offset, &sub_ty, &sub_off, &top_idx, NULL); 1562 (void)top_idx; 1563 parse_static_init_at(p, buf, buflen, sub_off, sub_ty); 1564 } else { 1565 const Field* f = &ty->rec.fields[0]; 1566 if (!(f->flags & FIELD_BITFIELD)) { 1567 parse_static_init_at(p, buf, buflen, offset, f->type); 1568 } else if (!(f->flags & FIELD_ZERO_WIDTH)) { 1569 const ABIRecordLayout* L = c_abi_record_layout(p->abi, p->pool, ty); 1570 parse_static_bitfield_at(p, buf, buflen, offset, &L->fields[0], 1571 f->type); 1572 } 1573 } 1574 if (had_brace) { 1575 accept_punct(p, ','); 1576 expect_punct(p, '}', "'}' after union initializer"); 1577 } 1578 return; 1579 } 1580 /* Scalar / pointer. */ 1581 { 1582 int had_brace = accept_punct(p, '{'); 1583 SrcLoc cloc = tok_loc_init(&p->cur); 1584 u32 sz = c_abi_sizeof(p->abi, ty); 1585 CStaticConst cv; 1586 if (offset + sz > buflen) perr(p, "initializer overflows object"); 1587 if (try_parse_static_float(p, buf + offset, sz, ty)) { 1588 if (had_brace) { 1589 accept_punct(p, ','); 1590 expect_punct(p, '}', "'}' after scalar initializer"); 1591 } 1592 return; 1593 } 1594 cv = parse_static_const(p, ty, cloc); 1595 if (cv.kind == C_STATIC_CONST_ADDR) { 1596 srl_push(p, offset, sz, cv.target, cv.addend); 1597 } else if (cv.kind == C_STATIC_CONST_LABEL_ADDR) { 1598 srl_push_label(p, offset, sz, cv.label, cv.addend); 1599 } else if (cv.kind == C_STATIC_CONST_NULL_PTR) { 1600 encode_int_le(buf + offset, sz, 0); 1601 } else { 1602 { 1603 CConstInt bits = int_bits_for_type(p, cv.int_value, ty); 1604 encode_uint128_le(buf + offset, sz, bits.lo, bits.hi); 1605 } 1606 } 1607 if (had_brace) { 1608 accept_punct(p, ','); 1609 expect_punct(p, '}', "'}' after scalar initializer"); 1610 } 1611 } 1612 } 1613 1614 static void emit_static_data(Parser* p, const u8* buf, u32 size) { 1615 u32 pos = 0; 1616 u32 emitted_relocs = 0; 1617 1618 while (emitted_relocs < p->static_relocs_len) { 1619 u32 best = p->static_relocs_len; 1620 u32 best_off = 0xffffffffu; 1621 for (u32 i = 0; i < p->static_relocs_len; ++i) { 1622 if (p->static_relocs[i].offset < pos) continue; 1623 if (p->static_relocs[i].offset < best_off) { 1624 best = i; 1625 best_off = p->static_relocs[i].offset; 1626 } 1627 } 1628 if (best == p->static_relocs_len) break; 1629 if (best_off > size || p->static_relocs[best].size > size - best_off) { 1630 perr(p, "static initializer relocation overflows object"); 1631 } 1632 if (best_off > pos) { 1633 if (buf) { 1634 kit_cg_data_bytes(p->cg, buf + pos, best_off - pos); 1635 } else { 1636 kit_cg_data_zero(p->cg, best_off - pos); 1637 } 1638 } 1639 if (p->static_relocs[best].is_label) { 1640 kit_cg_data_label_addr(p->cg, p->static_relocs[best].label, 1641 p->static_relocs[best].addend, 1642 p->static_relocs[best].size, 0); 1643 } else { 1644 kit_cg_data_addr(p->cg, p->static_relocs[best].target, 1645 p->static_relocs[best].addend, 1646 p->static_relocs[best].size, 0); 1647 } 1648 pos = best_off + p->static_relocs[best].size; 1649 ++emitted_relocs; 1650 } 1651 1652 if (pos < size) { 1653 if (buf) { 1654 kit_cg_data_bytes(p->cg, buf + pos, size - pos); 1655 } else { 1656 kit_cg_data_zero(p->cg, size - pos); 1657 } 1658 } 1659 } 1660 1661 /* Define a static-storage object. */ 1662 void define_static_object(Parser* p, ObjSymId sym, ObjSecId section_id, 1663 const Type* var_ty, u16 quals, int has_init, 1664 SrcLoc loc, u32 align_override) { 1665 u32 size = c_abi_sizeof(p->abi, var_ty); 1666 u32 align = c_abi_alignof(p->abi, var_ty); 1667 KitCgDataDefAttrs attrs; 1668 if (align_override > align) align = align_override; 1669 u8* buf = NULL; 1670 int has_nonzero = 0; 1671 int has_label_reloc = 0; 1672 1673 if (has_init) { 1674 buf = (u8*)arena_array(p->pool->arena, u8, size ? size : 1u); 1675 memset(buf, 0, size); 1676 p->static_relocs_len = 0; 1677 parse_static_init_at(p, buf, size, 0, var_ty); 1678 for (u32 i = 0; i < size; ++i) { 1679 if (buf[i]) { 1680 has_nonzero = 1; 1681 break; 1682 } 1683 } 1684 if (p->static_relocs_len) has_nonzero = 1; 1685 for (u32 i = 0; i < p->static_relocs_len; ++i) { 1686 if (p->static_relocs[i].is_label) { 1687 has_label_reloc = 1; 1688 break; 1689 } 1690 } 1691 } 1692 1693 memset(&attrs, 0, sizeof attrs); 1694 attrs.section = section_id; 1695 attrs.align = align ? align : 1u; 1696 /* Label-address relocations (&&label) are tied to the enclosing function's 1697 * label namespace, so the table must be emitted as function-local static 1698 * data while that function is still open. */ 1699 if (has_label_reloc) { 1700 attrs.flags |= KIT_CG_DATADEF_FUNCTION_LOCAL; 1701 } 1702 if ((quals & Q_CONST) != 0 && has_nonzero) { 1703 attrs.flags |= KIT_CG_DATADEF_READONLY; 1704 } 1705 if (!has_init || !has_nonzero) { 1706 attrs.flags |= KIT_CG_DATADEF_ZERO_FILL; 1707 } 1708 1709 kit_cg_data_begin(p->cg, sym, attrs); 1710 emit_static_data(p, (attrs.flags & KIT_CG_DATADEF_ZERO_FILL) ? NULL : buf, 1711 size); 1712 kit_cg_data_end(p->cg); 1713 p->static_relocs_len = 0; 1714 (void)loc; 1715 }