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