parse.c (71321B)
1 /* parse.c — residual C11 parser core. 2 * 3 * Contains: 4 * - kw_names[] table (used by parse_c to intern keywords) 5 * - Diagnostics/token helpers (perr, advance, peek1, fetch_tok, ...) 6 * - Scope/tag operations 7 * - Type helpers (ty_int, ty_size_t) 8 * - Local-variable slot allocation (make_local, make_local_aligned) 9 * - Static-local symbol naming (mint_static_local_sym) 10 * - Declaration driver (parse_init_declarator, parse_local_decl) 11 * - TU-level driver (parse_param_list, declare_function, 12 * parse_function_body, parse_external_decl, parse_translation_unit, 13 * parse_c) 14 * 15 * All expression, type, initializer, and statement code lives in 16 * parse_expr.c, parse_type.c, parse_init.c, and parse_stmt.c. */ 17 18 #include <stdarg.h> 19 #include <string.h> 20 21 #include "parse/parse_priv.h" 22 23 /* ============================================================ 24 * Keywords 25 * ============================================================ */ 26 27 static const char* const kw_names[KW_COUNT] = { 28 NULL, 29 "auto", 30 "break", 31 "case", 32 "char", 33 "const", 34 "continue", 35 "default", 36 "do", 37 "double", 38 "else", 39 "enum", 40 "extern", 41 "float", 42 "_Float16", 43 "for", 44 "goto", 45 "if", 46 "inline", 47 "int", 48 "long", 49 "register", 50 "restrict", 51 "return", 52 "short", 53 "signed", 54 "sizeof", 55 "static", 56 "struct", 57 "switch", 58 "typedef", 59 "union", 60 "unsigned", 61 "void", 62 "volatile", 63 "while", 64 "_Bool", 65 "_Complex", 66 "_Imaginary", 67 "_Alignas", 68 "_Alignof", 69 "_Atomic", 70 "_Generic", 71 "_Noreturn", 72 "_Static_assert", 73 "_Thread_local", 74 "asm", 75 "__asm__", 76 }; 77 78 /* ============================================================ 79 * Diagnostics 80 * ============================================================ */ 81 82 static SrcLoc tok_loc(Parser* p, const Tok* t) { 83 return pp_materialize_loc(p->pp, t->loc); 84 } 85 86 _Noreturn void perr(Parser* p, const char* fmt, ...) { 87 va_list ap; 88 SrcLoc loc = tok_loc(p, &p->cur); 89 va_start(ap, fmt); 90 compiler_panicv(p->c, loc, fmt, ap); 91 } 92 93 void reject_general_regs_only_fp(Parser* p, const char* what) { 94 if (!p->general_regs_only) return; 95 perr(p, "-mgeneral-regs-only rejects %.*s", 96 KIT_SLICE_ARG(kit_slice_cstr(what))); 97 } 98 99 /* ============================================================ 100 * Token helpers 101 * ============================================================ */ 102 103 /* Width of an encoding prefix on a string-literal spelling: 0 for ordinary, 104 * 1 for L/u/U, 2 for u8. */ 105 static size_t str_prefix_len(u16 flags) { 106 if (flags & TF_STR_U8) return 2; 107 if (flags & (TF_STR_WIDE | TF_STR_U16 | TF_STR_U32)) return 1; 108 return 0; 109 } 110 111 #define STR_ENC_MASK (TF_STR_WIDE | TF_STR_U8 | TF_STR_U16 | TF_STR_U32) 112 113 /* Fuse two adjacent TOK_STR tokens into one per C11 §6.4.5 ¶5. */ 114 static Tok fuse_string_lits(Parser* p, Tok a, Tok b) { 115 u16 ae = (u16)(a.flags & STR_ENC_MASK); 116 u16 be = (u16)(b.flags & STR_ENC_MASK); 117 u16 fused_enc; 118 KitSlice a_sl = pp_text_slice(p->pp, &a); 119 KitSlice b_sl = pp_text_slice(p->pp, &b); 120 size_t alen = a_sl.len, blen = b_sl.len; 121 const char* as = a_sl.s; 122 const char* bs = b_sl.s; 123 size_t apfx, bpfx; 124 size_t a_content_len, b_content_len; 125 size_t out_pfx_len; 126 size_t out_len; 127 Heap* h = kit_compiler_context(p->c)->heap; 128 char* buf; 129 size_t k = 0; 130 Tok out; 131 if (!as || !bs) perr(p, "bad string literal in concatenation"); 132 if (ae != 0 && be != 0 && ae != be) { 133 perr(p, 134 "concatenating string literals with incompatible " 135 "encoding prefixes"); 136 } 137 fused_enc = ae ? ae : be; 138 apfx = str_prefix_len(a.flags); 139 bpfx = str_prefix_len(b.flags); 140 if (alen < apfx + 2 || as[apfx] != '"' || as[alen - 1] != '"' || 141 blen < bpfx + 2 || bs[bpfx] != '"' || bs[blen - 1] != '"') { 142 perr(p, "malformed string literal in concatenation"); 143 } 144 a_content_len = alen - apfx - 2; 145 b_content_len = blen - bpfx - 2; 146 out_pfx_len = ae ? apfx : bpfx; 147 out_len = out_pfx_len + 1 + a_content_len + b_content_len + 1; 148 buf = (char*)h->alloc(h, out_len, 1); 149 if (!buf) perr(p, "out of memory fusing string literals"); 150 if (out_pfx_len) { 151 const char* src = ae ? as : bs; 152 memcpy(buf + k, src, out_pfx_len); 153 k += out_pfx_len; 154 } 155 buf[k++] = '"'; 156 if (a_content_len) { 157 memcpy(buf + k, as + apfx + 1, a_content_len); 158 k += a_content_len; 159 } 160 if (b_content_len) { 161 memcpy(buf + k, bs + bpfx + 1, b_content_len); 162 k += b_content_len; 163 } 164 buf[k++] = '"'; 165 out = a; 166 out.text = 167 text_sym_ref(kit_sym_intern(p->pool->c, (KitSlice){.s = buf, .len = k})); 168 out.flags = (u16)((a.flags & ~STR_ENC_MASK) | fused_enc); 169 h->free(h, buf, 0); 170 return out; 171 } 172 173 /* Pull one logical token from pp, collapsing adjacent TOK_STR runs. */ 174 static Tok fetch_tok(Parser* p) { 175 Tok t; 176 if (p->has_pending) { 177 t = p->pending; 178 p->has_pending = 0; 179 } else { 180 pp_next_parse(p->pp, &t); 181 } 182 if (t.kind != TOK_STR) return t; 183 for (;;) { 184 Tok n; 185 pp_next_parse(p->pp, &n); 186 if (n.kind != TOK_STR) { 187 p->pending = n; 188 p->has_pending = 1; 189 return t; 190 } 191 t = fuse_string_lits(p, t, n); 192 } 193 } 194 195 void advance(Parser* p) { 196 if (p->replay_active) { 197 if (p->replay_pos < p->replay_len) { 198 p->cur = p->replay[p->replay_pos++]; 199 return; 200 } 201 p->replay_active = 0; 202 } 203 if (p->function_replay_active) { 204 if (p->function_replay_pos < p->function_replay_len) { 205 p->cur = p->function_replay[p->function_replay_pos++]; 206 return; 207 } 208 p->function_replay_active = 0; 209 if (p->function_replay_hold) { 210 memset(&p->cur, 0, sizeof p->cur); 211 p->cur.kind = TOK_EOF; 212 return; 213 } 214 } 215 if (p->has_next) { 216 p->cur = p->next; 217 p->has_next = 0; 218 } else { 219 p->cur = fetch_tok(p); 220 } 221 } 222 223 Tok peek1(Parser* p) { 224 if (p->replay_active && p->replay_pos < p->replay_len) { 225 return p->replay[p->replay_pos]; 226 } 227 if (p->function_replay_active && 228 p->function_replay_pos < p->function_replay_len) { 229 return p->function_replay[p->function_replay_pos]; 230 } 231 if (!p->has_next) { 232 p->next = fetch_tok(p); 233 p->has_next = 1; 234 } 235 return p->next; 236 } 237 238 void expect_punct(Parser* p, u32 punct, const char* what) { 239 if (!accept_punct(p, punct)) { 240 perr(p, "expected %.*s", KIT_SLICE_ARG(kit_slice_cstr(what))); 241 } 242 } 243 244 int accept_punct(Parser* p, u32 punct) { 245 if (is_punct(&p->cur, punct)) { 246 advance(p); 247 return 1; 248 } 249 return 0; 250 } 251 252 /* Record tokens from the current `{` through the matching `}` into the 253 * parser's replay buffer. */ 254 void record_braced_block(Parser* p) { 255 int depth = 0; 256 if (!is_punct(&p->cur, '{')) perr(p, "internal: record on non-'{'"); 257 p->replay_len = 0; 258 for (;;) { 259 if (p->replay_len == p->replay_cap) { 260 u32 new_cap = p->replay_cap ? p->replay_cap * 2 : 32; 261 Tok* nv = arena_array(p->pool->arena, Tok, new_cap); 262 if (!nv) perr(p, "out of memory in record_braced_block"); 263 if (p->replay && p->replay_len) { 264 memcpy(nv, p->replay, p->replay_len * sizeof(Tok)); 265 } 266 p->replay = nv; 267 p->replay_cap = new_cap; 268 } 269 p->replay[p->replay_len++] = p->cur; 270 if (is_punct(&p->cur, '{')) { 271 ++depth; 272 } else if (is_punct(&p->cur, '}')) { 273 --depth; 274 if (depth == 0) break; 275 } else if (p->cur.kind == TOK_EOF) { 276 perr(p, "unexpected end of file in initializer"); 277 } 278 advance(p); 279 } 280 } 281 282 /* After record_braced_block, rewind to replay from the start. */ 283 void replay_rewind(Parser* p) { 284 if (p->replay_len == 0) perr(p, "internal: replay_rewind with empty buffer"); 285 p->cur = p->replay[0]; 286 p->replay_pos = 1; 287 p->replay_active = 1; 288 p->has_next = 0; 289 } 290 291 /* Buffer a whole function body without feeding its already-preprocessed tokens 292 * back through pp. The dedicated replay stream lets initializer replay nest 293 * normally during each semantic pass. */ 294 static void record_function_body(Parser* p) { 295 Tok* body = NULL; 296 u32 len = 0; 297 u32 cap = 0; 298 int depth = 0; 299 if (!is_punct(&p->cur, '{')) perr(p, "internal: function body is not '{'"); 300 for (;;) { 301 if (len == cap) { 302 u32 next_cap = cap ? cap * 2u : 128u; 303 Tok* next = arena_array(p->pool->arena, Tok, next_cap); 304 if (!next) perr(p, "out of memory recording function body"); 305 if (body && len) memcpy(next, body, sizeof(Tok) * len); 306 body = next; 307 cap = next_cap; 308 } 309 body[len++] = p->cur; 310 if (is_punct(&p->cur, '{')) { 311 ++depth; 312 } else if (is_punct(&p->cur, '}')) { 313 --depth; 314 if (depth == 0) break; 315 } else if (p->cur.kind == TOK_EOF) { 316 perr(p, "unexpected end of file in function body"); 317 } 318 advance(p); 319 } 320 p->function_replay = body; 321 p->function_replay_len = len; 322 p->function_replay_pos = 1; 323 p->function_replay_active = 1; 324 p->function_replay_hold = 1; 325 p->cur = body[0]; 326 p->has_next = 0; 327 } 328 329 static void rewind_function_body(Parser* p, int hold_at_end) { 330 if (!p->function_replay || !p->function_replay_len) 331 perr(p, "internal: empty function body replay"); 332 p->cur = p->function_replay[0]; 333 p->function_replay_pos = 1; 334 p->function_replay_active = 1; 335 p->function_replay_hold = hold_at_end ? 1u : 0u; 336 p->has_next = 0; 337 } 338 339 /* Count top-level items in a recorded brace list. */ 340 u32 count_recorded_top_level_items(const Tok* vec, u32 len) { 341 u32 count; 342 u32 i; 343 int depth = 0; 344 if (len < 2) return 0; 345 if (len == 2) return 0; /* `{}` */ 346 count = 1; 347 for (i = 1; i < len - 1; ++i) { 348 const Tok* t = &vec[i]; 349 if (is_punct(t, '{') || is_punct(t, '(') || is_punct(t, '[')) 350 ++depth; 351 else if (is_punct(t, '}') || is_punct(t, ')') || is_punct(t, ']')) 352 --depth; 353 else if (depth == 0 && is_punct(t, ',')) 354 ++count; 355 } 356 if (is_punct(&vec[len - 2], ',')) --count; 357 return count; 358 } 359 360 /* ============================================================ 361 * Scopes 362 * ============================================================ */ 363 364 /* A scope only builds its hashmap index once it holds more than this many 365 * entries; below it the linear LIFO scan is cheaper than a hashed lookup and 366 * needs no allocation. The bound is a constant, so even pre-index scopes are 367 * O(1) per lookup. */ 368 #define SCOPE_INDEX_THRESHOLD 12u 369 370 Scope* scope_new(Parser* p, Scope* parent) { 371 Scope* s = arena_new(p->pool->arena, Scope); 372 if (!s) perr(p, "out of memory in scope_new"); 373 memset(s, 0, sizeof *s); 374 s->parent = parent; 375 s->saved_vla_mark = p->vla_mark; 376 return s; 377 } 378 379 void scope_push(Parser* p) { p->scope = scope_new(p, p->scope); } 380 381 void scope_pop(Parser* p) { 382 if (p->scope) { 383 /* Unwind the binding cache: walk the popped scope's LIFO list head-first 384 * (newest define first) so multiple same-scope shadows of one Sym restore 385 * to the pre-scope value. e->shadowed is the binding that was current when 386 * e was defined, i.e. the value bind[name] must return once this scope is 387 * gone. */ 388 SymEntry* e; 389 for (e = p->scope->entries; e; e = e->next) 390 if (e->name) BindingTab_set(&p->bind, e->name, e->shadowed); 391 p->vla_mark = p->scope->saved_vla_mark; 392 p->scope = p->scope->parent; 393 } 394 } 395 396 /* Build a scope's name->entry index from its existing LIFO list. Insert 397 * newest-first with try_insert (which keeps the first writer) so the head — the 398 * current binding a linear scan would return — wins on shadowing. */ 399 static void scope_entries_index_build(Parser* p, Scope* s) { 400 SymEntry* e; 401 SymEntryMap_init_cap(&s->emap, &p->pool->arena_heap, 64u); 402 for (e = s->entries; e; e = e->next) 403 if (e->name) (void)SymEntryMap_try_insert(&s->emap, e->name, e, NULL); 404 } 405 406 static void scope_entries_index_put(Parser* p, Scope* s, SymEntry* e) { 407 if (!e->name) 408 return; /* anonymous: never name-looked-up, keep off the index */ 409 if (s->emap.cap) { 410 (void)SymEntryMap_set(&s->emap, e->name, e); /* newest define wins */ 411 } else if (s->nentries > SCOPE_INDEX_THRESHOLD) { 412 scope_entries_index_build(p, s); 413 } 414 } 415 416 static SymEntry* scope_entries_find(Scope* s, Sym name) { 417 SymEntry* e; 418 if (name && s->emap.cap) { 419 SymEntry** v = SymEntryMap_get(&s->emap, name); 420 return v ? *v : NULL; 421 } 422 for (e = s->entries; e; e = e->next) 423 if (e->name == name) return e; 424 return NULL; 425 } 426 427 SymEntry* scope_define(Parser* p, Sym name, SymEntryKind kind, 428 const Type* type) { 429 SymEntry* e = arena_new(p->pool->arena, SymEntry); 430 Scope* s = p->scope; 431 if (!e) perr(p, "out of memory in scope_define"); 432 memset(e, 0, sizeof *e); 433 e->name = name; 434 e->kind = (u8)kind; 435 e->type = type; 436 if (name) e->shadowed = BindingTab_get(&p->bind, name); 437 e->next = s->entries; 438 s->entries = e; 439 s->nentries++; 440 scope_entries_index_put(p, s, e); 441 if (name) BindingTab_set(&p->bind, name, e); 442 return e; 443 } 444 445 SymEntry* scope_lookup_current(Parser* p, Sym name) { 446 return p->scope ? scope_entries_find(p->scope, name) : NULL; 447 } 448 449 /* Walk the scope chain starting at `from` (inclusive), returning the first 450 * binding for `name`. scope_lookup is the common case starting at p->scope; a 451 * caller that has already probed the current scope can start at its parent. */ 452 static SymEntry* scope_lookup_from(Scope* from, Sym name) { 453 Scope* s; 454 for (s = from; s; s = s->parent) { 455 SymEntry* e = scope_entries_find(s, name); 456 if (e) return e; 457 } 458 return NULL; 459 } 460 461 SymEntry* scope_lookup(Parser* p, Sym name) { 462 /* Sym-keyed cache: the innermost-visible binding in one load. Equivalent to 463 * scope_lookup_from(p->scope, name) by construction (the cache tracks the 464 * newest define per scope and unwinds on pop); no caller passes name == 0. */ 465 return name ? BindingTab_get(&p->bind, name) : NULL; 466 } 467 468 static void sym_set_decl(SymEntry* e, DeclId id, DeclStorage storage, 469 DeclLinkage linkage, u32 flags, DeclState state) { 470 e->decl_id = id; 471 e->storage = (u8)storage; 472 e->linkage = (u8)linkage; 473 e->decl_flags = flags; 474 e->decl_state = (u8)state; 475 e->defined = (state == DSTATE_DEFINED || state == DSTATE_FUNC_DEFINED); 476 } 477 478 static SymEntry* external_func_lookup(Parser* p, Sym name) { 479 SymEntry** v = name ? ExternalFuncMap_get(&p->external_funcs, name) : NULL; 480 return v ? *v : NULL; 481 } 482 483 static void external_func_remember(Parser* p, Sym name, SymEntry* entry) { 484 if (!entry || !name) return; 485 (void)ExternalFuncMap_set(&p->external_funcs, name, entry); /* newest wins */ 486 } 487 488 static int is_ordinary_decl_kind(SymEntryKind k) { 489 return k == SEK_LOCAL || k == SEK_GLOBAL || k == SEK_FUNC || 490 k == SEK_TYPEDEF || k == SEK_ENUM_CST; 491 } 492 493 /* Apply the same-scope redefinition rule against `prior` (the binding present 494 * before the new entry is installed): reject an ordinary-kind redeclaration 495 * unless it is a typedef of a compatible type. */ 496 static void reject_redef_on(Parser* p, const SymEntry* prior, SymEntryKind kind, 497 const Type* type) { 498 if (!prior || !is_ordinary_decl_kind((SymEntryKind)prior->kind)) return; 499 if (prior->kind == SEK_TYPEDEF && kind == SEK_TYPEDEF && 500 type_compatible(prior->type, type)) { 501 return; 502 } 503 perr(p, "redefinition of identifier"); 504 } 505 506 /* Fused redefinition-check + define: one hash+probe on the scope index reads 507 * the prior binding (for the redef rule) AND installs the new entry, instead of 508 * probing the same key twice (a get for the redef check then a set in 509 * scope_define). Behavior is identical to a redef check followed by 510 * return scope_define(p, name, kind, type); 511 * — the redef rule fires on the captured prior before the new entry shadows it, 512 * and the LIFO list + newest-wins index semantics are preserved. Use this only 513 * at the rejecting declaration sites; plain scope_define stays for the 514 * non-rejecting redeclaration-merge sites. */ 515 static SymEntry* scope_define_checked(Parser* p, Sym name, SymEntryKind kind, 516 const Type* type) { 517 SymEntry* e = arena_new(p->pool->arena, SymEntry); 518 Scope* s = p->scope; 519 SymEntry* prior; 520 if (!e) perr(p, "out of memory in scope_define_checked"); 521 memset(e, 0, sizeof *e); 522 e->name = name; 523 e->kind = (u8)kind; 524 e->type = type; 525 /* The shadowed binding is the current innermost-visible one (== bind_get), 526 * not `prior`: prior is the current-scope prior (used only for the redef 527 * rule) and may be NULL while an outer binding exists, which must be the 528 * value restored on pop. */ 529 if (name) e->shadowed = BindingTab_get(&p->bind, name); 530 if (name && s->emap.cap) { 531 /* Active index: prepend to the LIFO list, then fold the prior-read and the 532 * index install into a single probe (newest define wins). */ 533 SymEntry* old = NULL; 534 e->next = s->entries; 535 s->entries = e; 536 s->nentries++; 537 (void)SymEntryMap_replace(&s->emap, name, e, &old); 538 prior = old; 539 } else { 540 /* No index yet (or anonymous): capture the prior binding before the prepend 541 * shadows it, then mirror scope_entries_index_put's threshold-trip build. 542 * Anonymous entries (name == 0) stay off the index, as before. */ 543 prior = scope_entries_find(s, name); 544 e->next = s->entries; 545 s->entries = e; 546 s->nentries++; 547 if (name && s->nentries > SCOPE_INDEX_THRESHOLD) 548 scope_entries_index_build(p, s); 549 } 550 reject_redef_on(p, prior, kind, type); 551 if (name) BindingTab_set(&p->bind, name, e); 552 return e; 553 } 554 555 static void tag_index_build(Parser* p, Scope* s) { 556 TagEntry* e; 557 TagEntryMap_init_cap(&s->tmap, &p->pool->arena_heap, 64u); 558 for (e = s->tags; e; e = e->next) 559 if (e->name) (void)TagEntryMap_try_insert(&s->tmap, e->name, e, NULL); 560 } 561 562 static void tag_index_put(Parser* p, Scope* s, TagEntry* e) { 563 if (!e->name) return; /* anonymous struct/union: not name-looked-up */ 564 if (s->tmap.cap) { 565 (void)TagEntryMap_set(&s->tmap, e->name, e); 566 } else if (s->ntags > SCOPE_INDEX_THRESHOLD) { 567 tag_index_build(p, s); 568 } 569 } 570 571 static TagEntry* tag_find_in(Scope* s, Sym name) { 572 TagEntry* e; 573 if (name && s->tmap.cap) { 574 TagEntry** v = TagEntryMap_get(&s->tmap, name); 575 return v ? *v : NULL; 576 } 577 for (e = s->tags; e; e = e->next) 578 if (e->name == name) return e; 579 return NULL; 580 } 581 582 TagEntry* tag_define(Parser* p, Sym name, TagDeclKind kind, Type* type, 583 int complete) { 584 TagEntry* e = arena_new(p->pool->arena, TagEntry); 585 Scope* s = p->scope; 586 if (!e) perr(p, "out of memory in tag_define"); 587 memset(e, 0, sizeof *e); 588 e->name = name; 589 e->kind = (u8)kind; 590 e->complete = (u8)(complete ? 1 : 0); 591 e->type = type; 592 e->next = s->tags; 593 s->tags = e; 594 s->ntags++; 595 tag_index_put(p, s, e); 596 return e; 597 } 598 599 TagEntry* tag_lookup(Parser* p, Sym name) { 600 Scope* s; 601 for (s = p->scope; s; s = s->parent) { 602 TagEntry* e = tag_find_in(s, name); 603 if (e) return e; 604 } 605 return NULL; 606 } 607 608 TagEntry* tag_lookup_local(Parser* p, Sym name) { 609 return tag_find_in(p->scope, name); 610 } 611 612 /* ============================================================ 613 * Type helpers 614 * ============================================================ */ 615 616 static const Type* ty_size_t(Parser* p) { 617 return c_abi_size_type(p->abi, p->pool); 618 } 619 620 /* C owns conventional function selection; CG owns the guard/check lowering. 621 * BASIC follows GCC's classic character-buffer threshold, STRONG covers every 622 * local array (including arrays nested in records) plus address-taken locals, 623 * and dynamic alloca selects either mode. */ 624 static int stack_type_selects(Parser* p, const Type* type, int strong) { 625 u16 i; 626 if (!type) return 0; 627 if (type->kind == TY_ARRAY) { 628 if (strong) return 1; 629 if ((type->arr.elem->kind == TY_CHAR || 630 type->arr.elem->kind == TY_SCHAR || 631 type->arr.elem->kind == TY_UCHAR) && 632 !type->arr.incomplete && 633 c_abi_sizeof(p->abi, p->pool, type) >= 8u) 634 return 1; 635 return stack_type_selects(p, type->arr.elem, strong); 636 } 637 if (type->kind == TY_STRUCT || type->kind == TY_UNION) { 638 for (i = 0; i < type->rec.nfields; ++i) { 639 if (stack_type_selects(p, type->rec.fields[i].type, strong)) return 1; 640 } 641 } 642 return 0; 643 } 644 645 void c_stack_protector_enable(Parser* p) { 646 if (!p || p->stack_protector_mode == KIT_STACK_PROTECTOR_NONE) 647 return; 648 if (p->stack_protector_scan) { 649 p->stack_protector_scan_selected = 1; 650 return; 651 } 652 if (p->stack_protector_enabled || !p->cur_func_emits) return; 653 kit_cg_stack_protector_enable(p->cg); 654 p->stack_protector_enabled = 1; 655 } 656 657 void c_stack_protector_note_type(Parser* p, const Type* type) { 658 if (!p || p->stack_protector_mode == KIT_STACK_PROTECTOR_NONE || 659 p->stack_protector_mode == KIT_STACK_PROTECTOR_ALL) 660 return; 661 if (stack_type_selects( 662 p, type, 663 p->stack_protector_mode == KIT_STACK_PROTECTOR_STRONG)) 664 c_stack_protector_enable(p); 665 } 666 667 void c_stack_protector_note_address(Parser* p) { 668 if (p && p->stack_protector_mode == KIT_STACK_PROTECTOR_STRONG) 669 c_stack_protector_enable(p); 670 } 671 672 /* ============================================================ 673 * Local-variable slot allocation 674 * ============================================================ */ 675 676 FrameSlot make_local_aligned(Parser* p, Sym name, const Type* type, SrcLoc loc, 677 u32 align_override) { 678 FrameSlotDesc fsd; 679 FrameSlot s; 680 SymEntry* e; 681 u32 nat = c_abi_alignof(p->abi, p->pool, type); 682 c_stack_protector_note_type(p, type); 683 memset(&fsd, 0, sizeof fsd); 684 fsd.type = type; 685 fsd.name = name; 686 fsd.loc = loc; 687 fsd.size = c_abi_sizeof(p->abi, p->pool, type); 688 fsd.align = (align_override > nat) ? align_override : nat; 689 fsd.kind = FS_LOCAL; 690 fsd.flags = FSF_NONE; 691 s = c_cg_local(p, &fsd); 692 e = scope_define_checked(p, name, SEK_LOCAL, type); 693 e->v.slot = s; 694 sym_set_decl(e, DECL_NONE, DS_AUTO, DL_NONE, DF_NONE, DSTATE_DEFINED); 695 return s; 696 } 697 698 FrameSlot make_local(Parser* p, Sym name, const Type* type, SrcLoc loc) { 699 return make_local_aligned(p, name, type, loc, 0); 700 } 701 702 static FrameSlot make_vla_size_slot(Parser* p) { 703 FrameSlotDesc fsd; 704 memset(&fsd, 0, sizeof fsd); 705 fsd.type = ty_size_t(p); 706 fsd.size = c_abi_sizeof(p->abi, p->pool, fsd.type); 707 fsd.align = c_abi_alignof(p->abi, p->pool, fsd.type); 708 fsd.kind = FS_LOCAL; 709 return c_cg_local(p, &fsd); 710 } 711 712 static void store_top_to_size_slot(Parser* p, FrameSlot slot) { 713 c_cg_push_local_typed(p, slot, ty_size_t(p)); 714 c_cg_swap(p); 715 coerce_top_to_lvalue(p); 716 c_cg_store_void(p); 717 } 718 719 static void reset_vla_pending(Parser* p) { 720 p->vla_pending = 0; 721 p->vla_pending_count_slot = FRAME_SLOT_NONE; 722 p->vla_pending_count_len = 0; 723 } 724 725 static VLABound* add_vla_bound(Parser* p, VLABound* head, const Type* array_ty, 726 FrameSlot byte_slot, FrameSlot count_slot) { 727 VLABound* b = arena_znew(p->pool->arena, VLABound); 728 b->array_ty = array_ty; 729 b->byte_slot = byte_slot; 730 b->count_slot = count_slot; 731 b->next = head; 732 return b; 733 } 734 735 static int build_vla_size(Parser* p, const Type* ty, u32* count_idx, 736 VLABound** bounds, FrameSlot* out_slot, 737 u32* out_static_size, SrcLoc loc) { 738 if (!ty || ty->kind != TY_ARRAY) { 739 *out_static_size = c_abi_sizeof(p->abi, p->pool, ty); 740 *out_slot = FRAME_SLOT_NONE; 741 return 0; 742 } 743 744 FrameSlot count_slot = FRAME_SLOT_NONE; 745 int count_dynamic = 0; 746 if (ty->arr.incomplete) { 747 if (*count_idx >= p->vla_pending_count_len) { 748 perr(p, "missing VLA bound for declarator"); 749 } 750 count_slot = p->vla_pending_count_slots[(*count_idx)++]; 751 count_dynamic = 1; 752 } 753 754 FrameSlot elem_slot = FRAME_SLOT_NONE; 755 u32 elem_static_size = 0; 756 int elem_dynamic = build_vla_size(p, ty->arr.elem, count_idx, bounds, 757 &elem_slot, &elem_static_size, loc); 758 759 if (count_dynamic || elem_dynamic) { 760 FrameSlot byte_slot = make_vla_size_slot(p); 761 c_cg_set_loc(p, loc); 762 if (count_dynamic) { 763 c_cg_push_local_typed(p, count_slot, ty_size_t(p)); 764 c_cg_load(p); 765 } else { 766 c_cg_push_int(p, (i64)ty->arr.count, ty_size_t(p)); 767 } 768 if (elem_dynamic) { 769 c_cg_push_local_typed(p, elem_slot, ty_size_t(p)); 770 c_cg_load(p); 771 } else { 772 c_cg_push_int(p, (i64)elem_static_size, ty_size_t(p)); 773 } 774 c_cg_binop(p, BO_IMUL); 775 store_top_to_size_slot(p, byte_slot); 776 *bounds = add_vla_bound(p, *bounds, ty, byte_slot, count_slot); 777 *out_slot = byte_slot; 778 *out_static_size = 0; 779 return 1; 780 } 781 782 *out_slot = FRAME_SLOT_NONE; 783 *out_static_size = ty->arr.count * elem_static_size; 784 return 0; 785 } 786 787 static FrameSlot finish_vla_layout(Parser* p, const Type* ty, SrcLoc loc, 788 VLABound** bounds_out) { 789 FrameSlot byte_slot = FRAME_SLOT_NONE; 790 u32 static_size = 0; 791 u32 count_idx = 0; 792 *bounds_out = NULL; 793 if (!build_vla_size(p, ty, &count_idx, bounds_out, &byte_slot, &static_size, 794 loc)) { 795 perr(p, "VLA declarator did not produce a runtime size"); 796 } 797 if (count_idx != p->vla_pending_count_len) { 798 perr(p, "unused VLA bound in declarator"); 799 } 800 reset_vla_pending(p); 801 return byte_slot; 802 } 803 804 static int type_array_depth(const Type* ty) { 805 int n = 0; 806 while (ty && ty->kind == TY_ARRAY) { 807 ++n; 808 ty = ty->arr.elem; 809 } 810 return n; 811 } 812 813 static void eval_param_vla_count(Parser* p, const ParamVLABoundExpr* expr, 814 FrameSlot slot) { 815 Tok save_cur = p->cur; 816 Tok save_next = p->next; 817 int save_has_next = p->has_next; 818 Tok* save_replay = p->replay; 819 u32 save_cap = p->replay_cap; 820 u32 save_len = p->replay_len; 821 u32 save_pos = p->replay_pos; 822 u8 save_active = p->replay_active; 823 Tok* replay; 824 825 if (!expr->has_expr || expr->ntoks == 0) { 826 perr(p, "missing VLA parameter bound"); 827 } 828 replay = arena_array(p->pool->arena, Tok, expr->ntoks + 1u); 829 memcpy(replay, expr->toks, sizeof(Tok) * expr->ntoks); 830 memset(&replay[expr->ntoks], 0, sizeof(Tok)); 831 replay[expr->ntoks].kind = TOK_EOF; 832 833 p->cur = replay[0]; 834 p->next.kind = TOK_EOF; 835 p->has_next = 0; 836 p->replay = replay; 837 p->replay_cap = expr->ntoks + 1u; 838 p->replay_len = expr->ntoks + 1u; 839 p->replay_pos = 1; 840 p->replay_active = 1; 841 842 parse_assign_expr(p); 843 to_rvalue(p); 844 if (p->cur.kind != TOK_EOF) { 845 perr(p, "unexpected token in VLA parameter bound"); 846 } 847 store_top_to_size_slot(p, slot); 848 849 p->cur = save_cur; 850 p->next = save_next; 851 p->has_next = save_has_next; 852 p->replay = save_replay; 853 p->replay_cap = save_cap; 854 p->replay_len = save_len; 855 p->replay_pos = save_pos; 856 p->replay_active = save_active; 857 } 858 859 static VLABound* build_param_vla_bounds(Parser* p, const ParamInfo* info, 860 SrcLoc loc) { 861 const Type* root = info->declared_type; 862 u32 dim_skip = 0; 863 u32 need; 864 VLABound* bounds = NULL; 865 866 if (!root || info->vla_bound_len == 0) return NULL; 867 if (root->kind == TY_ARRAY) { 868 dim_skip = 1; 869 root = root->arr.elem; 870 } else if (root->kind == TY_PTR) { 871 root = root->ptr.pointee; 872 } 873 need = (u32)type_array_depth(root); 874 if (need == 0) return NULL; 875 if (dim_skip + need > info->vla_bound_len) { 876 perr(p, "missing VLA parameter bound"); 877 } 878 879 reset_vla_pending(p); 880 for (u32 i = 0; i < need; ++i) { 881 const ParamVLABoundExpr* expr = &info->vla_bounds[dim_skip + i]; 882 FrameSlot slot = make_vla_size_slot(p); 883 eval_param_vla_count(p, expr, slot); 884 p->vla_pending = 1; 885 p->vla_pending_count_slots[p->vla_pending_count_len++] = slot; 886 } 887 (void)finish_vla_layout(p, root, loc, &bounds); 888 return bounds; 889 } 890 891 /* ============================================================ 892 * Static-local symbol naming 893 * ============================================================ */ 894 895 /* Mint a unique linker name for a static local: `<orig>.<counter>`. */ 896 Sym mint_static_local_sym(Parser* p, Sym orig) { 897 KitSlice orig_sl = kit_sym_str(p->pool->c, orig); 898 size_t olen = orig_sl.len; 899 const char* on = orig_sl.s; 900 char buf[128]; 901 u32 wlen = 0; 902 u32 id = ++p->static_local_counter; 903 if (olen > 100) olen = 100; 904 for (size_t i = 0; i < olen && wlen < sizeof buf - 1; ++i) { 905 buf[wlen++] = on[i]; 906 } 907 if (wlen < sizeof buf - 1) buf[wlen++] = '.'; 908 { 909 char digits[12]; 910 int dn = 0; 911 if (id == 0) digits[dn++] = '0'; 912 while (id) { 913 digits[dn++] = (char)('0' + (id % 10)); 914 id /= 10; 915 } 916 while (dn && wlen < sizeof buf - 1) buf[wlen++] = digits[--dn]; 917 } 918 return kit_sym_intern(p->pool->c, (KitSlice){.s = buf, .len = wlen}); 919 } 920 921 /* ============================================================ 922 * Declarations 923 * ============================================================ */ 924 925 /* Parse a single init-declarator after the decl-specs have been consumed. */ 926 static SymEntry* declare_function(Parser* p, Sym fname, const Type* fn_ty, 927 const DeclSpecs* specs, SrcLoc fname_loc, 928 const Attr* dattrs, Sym asm_label, 929 ObjSecId* out_section_id, u32* out_decl_flags, 930 Sym* out_alias_target); 931 932 static void parse_init_declarator(Parser* p, const DeclSpecs* specs) { 933 SrcLoc loc; 934 Sym name; 935 DeclaratorInfo dinfo; 936 const Type* var_ty = parse_declarator_full_info( 937 p, specs->type, /*allow_abstract=*/0, &name, &loc, NULL, &dinfo); 938 if ((specs->flags & DF_THREAD) && specs->storage != DS_STATIC && 939 specs->storage != DS_EXTERN) { 940 perr(p, "block-scope _Thread_local requires static or extern"); 941 } 942 validate_decl_type_constraints(p, specs, var_ty, 943 var_ty && var_ty->kind == TY_FUNC, 944 /*is_member=*/0); 945 946 if (specs->storage == DS_TYPEDEF) { 947 if (is_punct(&p->cur, '=')) { 948 perr(p, "typedef declarator cannot have initializer"); 949 } 950 { 951 SymEntry* e = scope_define_checked(p, name, SEK_TYPEDEF, var_ty); 952 sym_set_decl(e, DECL_NONE, DS_TYPEDEF, DL_NONE, specs->flags, 953 DSTATE_DECLARED); 954 if (p->vla_pending && var_ty && var_ty->kind == TY_ARRAY) { 955 VLABound* bounds = NULL; 956 FrameSlot byte_slot = finish_vla_layout(p, var_ty, loc, &bounds); 957 e->vla_byte_slot = byte_slot; 958 e->vla_bounds = bounds; 959 } else if (specs->vla_byte_slot != FRAME_SLOT_NONE) { 960 e->vla_byte_slot = specs->vla_byte_slot; 961 e->vla_bounds = specs->vla_bounds; 962 } 963 } 964 (void)loc; 965 return; 966 } 967 968 if (var_ty && var_ty->kind == TY_FUNC) { 969 ObjSecId section_id; 970 u32 decl_flags; 971 Sym alias_target; 972 if ((specs->storage == DS_AUTO && specs->storage_explicit) || 973 specs->storage == DS_REGISTER || specs->storage == DS_STATIC) { 974 perr(p, 975 "invalid storage-class specifier for block-scope function " 976 "declaration"); 977 } 978 if (is_punct(&p->cur, '=')) { 979 perr(p, "function declarator cannot have initializer"); 980 } 981 if (p->stack_protector_scan) { 982 SymEntry* prior = scope_lookup(p, name); 983 SymEntry* e = scope_lookup_current(p, name); 984 if (!e) e = scope_define(p, name, SEK_FUNC, var_ty); 985 e->v.sym = prior && prior->kind == SEK_FUNC ? prior->v.sym 986 : OBJ_SYM_NONE; 987 sym_set_decl(e, prior ? prior->decl_id : DECL_NONE, DS_EXTERN, 988 prior ? (DeclLinkage)prior->linkage : DL_EXTERNAL, 989 prior ? prior->decl_flags : DF_NONE, DSTATE_DECLARED); 990 } else { 991 (void)declare_function(p, name, var_ty, specs, loc, NULL, 992 dinfo.asm_label, §ion_id, &decl_flags, 993 &alias_target); 994 } 995 (void)section_id; 996 (void)decl_flags; 997 (void)alias_target; 998 return; 999 } 1000 1001 if (specs->storage == DS_STATIC) { 1002 Decl decl_in; 1003 DeclId did; 1004 ObjSymId sym; 1005 SymEntry* e; 1006 Sym lname; 1007 int has_init; 1008 u32 align_eff; 1009 has_init = accept_punct(p, '='); 1010 /* Complete `T x[] = {...}` before declaring the symbol so the registered 1011 * (CG) type carries the real element count. Backends such as the C target 1012 * derive function-local label-table sizes from the symbol's type, so the 1013 * declared type must already be the completed array. */ 1014 if (has_init && var_ty && var_ty->kind == TY_ARRAY && 1015 var_ty->arr.incomplete) { 1016 var_ty = complete_incomplete_array(p, var_ty); 1017 } 1018 if (p->stack_protector_scan) { 1019 e = scope_define_checked(p, name, SEK_GLOBAL, var_ty); 1020 e->v.sym = OBJ_SYM_NONE; 1021 sym_set_decl(e, DECL_NONE, DS_STATIC, DL_NONE, DF_STATIC_LOCAL, 1022 DSTATE_DEFINED); 1023 if (has_init) { 1024 if ((var_ty->kind == TY_ARRAY || var_ty->kind == TY_STRUCT || 1025 var_ty->kind == TY_UNION) && 1026 is_punct(&p->cur, '{')) { 1027 init_at(p, FRAME_SLOT_NONE, var_ty, 0, var_ty); 1028 } else { 1029 parse_assign_expr(p); 1030 c_cg_drop(p); 1031 } 1032 } 1033 return; 1034 } 1035 lname = mint_static_local_sym(p, name); 1036 memset(&decl_in, 0, sizeof decl_in); 1037 decl_in.name = lname; 1038 decl_in.asm_name = dinfo.asm_label; 1039 decl_in.type = var_ty; 1040 decl_in.loc = loc; 1041 decl_in.storage = DS_STATIC; 1042 decl_in.linkage = DL_INTERNAL; 1043 decl_in.visibility = SV_DEFAULT; 1044 decl_in.flags = DF_STATIC_LOCAL | (specs->flags & DF_THREAD); 1045 attr_list_to_decl(p->c, p->decls, specs->attrs, &decl_in); 1046 did = decl_declare(p->decls, &decl_in); 1047 sym = decl_obj_sym(p->decls, did); 1048 e = scope_define_checked(p, name, SEK_GLOBAL, var_ty); 1049 e->v.sym = sym; 1050 sym_set_decl(e, did, DS_STATIC, DL_NONE, decl_in.flags, DSTATE_DEFINED); 1051 align_eff = (specs->align > decl_in.align) ? specs->align : decl_in.align; 1052 define_static_object(p, sym, decl_in.section_id, var_ty, specs->quals, 1053 has_init, loc, align_eff); 1054 return; 1055 } 1056 1057 if (specs->storage == DS_EXTERN) { 1058 Decl decl_in; 1059 DeclId did; 1060 ObjSymId sym; 1061 SymEntry* e; 1062 SymEntry* prior; 1063 if (accept_punct(p, '=')) { 1064 perr(p, "block-scope extern with initializer not supported"); 1065 } 1066 prior = scope_lookup(p, name); 1067 if (p->stack_protector_scan) { 1068 e = scope_lookup_current(p, name); 1069 if (!e) e = scope_define(p, name, SEK_GLOBAL, var_ty); 1070 e->v.sym = prior && prior->kind == SEK_GLOBAL ? prior->v.sym 1071 : OBJ_SYM_NONE; 1072 sym_set_decl(e, prior ? prior->decl_id : DECL_NONE, DS_EXTERN, 1073 prior ? (DeclLinkage)prior->linkage : DL_EXTERNAL, 1074 prior ? prior->decl_flags : DF_NONE, DSTATE_DECLARED); 1075 return; 1076 } 1077 if (prior && prior->kind == SEK_GLOBAL) { 1078 SymEntry* cur = scope_lookup_current(p, name); 1079 const Type* composite = NULL; 1080 CSemCheck chk = 1081 c_sem_check_redeclaration(p->pool, prior->type, var_ty, &composite); 1082 if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message))); 1083 if (cur && cur->kind != SEK_GLOBAL) { 1084 perr(p, "redefinition of identifier"); 1085 } 1086 if (cur) return; 1087 e = scope_define(p, name, SEK_GLOBAL, var_ty); 1088 e->v.sym = prior->v.sym; 1089 sym_set_decl(e, prior->decl_id, DS_EXTERN, (DeclLinkage)prior->linkage, 1090 prior->decl_flags, (DeclState)prior->decl_state); 1091 return; 1092 } 1093 memset(&decl_in, 0, sizeof decl_in); 1094 decl_in.name = name; 1095 decl_in.asm_name = dinfo.asm_label; 1096 decl_in.type = var_ty; 1097 decl_in.loc = loc; 1098 decl_in.storage = DS_EXTERN; 1099 decl_in.linkage = DL_EXTERNAL; 1100 decl_in.visibility = p->default_visibility; 1101 decl_in.flags = specs->flags & DF_THREAD; 1102 attr_list_to_decl(p->c, p->decls, specs->attrs, &decl_in); 1103 did = decl_declare(p->decls, &decl_in); 1104 sym = decl_obj_sym(p->decls, did); 1105 e = scope_define_checked(p, name, SEK_GLOBAL, var_ty); 1106 e->v.sym = sym; 1107 sym_set_decl(e, did, DS_EXTERN, DL_EXTERNAL, decl_in.flags, 1108 DSTATE_DECLARED); 1109 return; 1110 } 1111 1112 if (var_ty && var_ty->kind == TY_ARRAY && 1113 (p->vla_pending || specs->vla_byte_slot != FRAME_SLOT_NONE)) { 1114 const Type* elem_ty = var_ty->arr.elem; 1115 const Type* ptr_ty = type_ptr(p->pool, elem_ty); 1116 FrameSlot byte_slot; 1117 FrameSlot ptr_slot; 1118 SymEntry* sym_entry; 1119 VLABound* bounds = NULL; 1120 c_stack_protector_enable(p); /* VLA lowers through dynamic alloca. */ 1121 if (p->vla_pending) { 1122 byte_slot = finish_vla_layout(p, var_ty, loc, &bounds); 1123 ++p->vla_mark; 1124 } else { 1125 byte_slot = specs->vla_byte_slot; 1126 bounds = specs->vla_bounds; 1127 } 1128 ptr_slot = make_local(p, name, ptr_ty, loc); 1129 c_cg_set_loc(p, loc); 1130 c_cg_push_local_typed(p, byte_slot, ty_size_t(p)); 1131 c_cg_load(p); 1132 c_cg_alloca(p); 1133 c_cg_push_local_typed(p, ptr_slot, ptr_ty); 1134 c_cg_swap(p); 1135 c_cg_store_void(p); 1136 sym_entry = scope_lookup(p, name); 1137 if (sym_entry && sym_entry->kind == SEK_LOCAL) { 1138 sym_entry->vla_byte_slot = byte_slot; 1139 sym_entry->vla_bounds = bounds; 1140 } 1141 if (accept_punct(p, '=')) { 1142 perr(p, "VLA initializers are not allowed (§6.7.9 ¶3)"); 1143 } 1144 return; 1145 } 1146 /* Non-VLA local. */ 1147 { 1148 int has_init = is_punct(&p->cur, '='); 1149 FrameSlot s; 1150 if (has_init && var_ty && var_ty->kind == TY_ARRAY && 1151 var_ty->arr.incomplete) { 1152 advance(p); /* '=' */ 1153 var_ty = complete_incomplete_array(p, var_ty); 1154 s = make_local_aligned(p, name, var_ty, loc, specs->align); 1155 if (specs->storage == DS_REGISTER) { 1156 SymEntry* e = scope_lookup_current(p, name); 1157 if (e && e->kind == SEK_LOCAL) { 1158 e->storage = DS_REGISTER; 1159 e->reg_asm_name = dinfo.asm_label; 1160 } 1161 } 1162 c_cg_set_loc(p, loc); 1163 init_at(p, s, var_ty, 0, var_ty); 1164 return; 1165 } 1166 s = make_local_aligned(p, name, var_ty, loc, specs->align); 1167 if (specs->storage == DS_REGISTER) { 1168 SymEntry* e = scope_lookup_current(p, name); 1169 if (e && e->kind == SEK_LOCAL) { 1170 e->storage = DS_REGISTER; 1171 e->reg_asm_name = dinfo.asm_label; 1172 } 1173 } 1174 if (accept_punct(p, '=')) { 1175 c_cg_set_loc(p, loc); 1176 if ((var_ty->kind == TY_STRUCT || var_ty->kind == TY_UNION) && 1177 !is_punct(&p->cur, '{')) { 1178 parse_assign_expr(p); 1179 emit_struct_copy_into_slot(p, s, var_ty, 0, var_ty); 1180 } else if (var_ty->kind == TY_ARRAY || var_ty->kind == TY_STRUCT || 1181 var_ty->kind == TY_UNION) { 1182 init_at(p, s, var_ty, 0, var_ty); 1183 } else { 1184 c_cg_push_local_typed(p, s, var_ty); 1185 parse_assign_expr(p); 1186 to_rvalue(p); 1187 { 1188 const Type* rhs = c_cg_top_type(p); 1189 CSemCheck chk = c_sem_check_assignment(p->pool, var_ty, rhs); 1190 if (!chk.ok) 1191 perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message))); 1192 } 1193 coerce_top_to_lvalue(p); 1194 c_cg_store_void(p); 1195 } 1196 } else if (p->auto_var_init == KIT_AUTOVAR_ZERO && var_ty && 1197 !(var_ty->kind == TY_ARRAY && var_ty->arr.incomplete)) { 1198 /* -ftrivial-auto-var-init=zero: an automatic variable with no explicit 1199 * initializer is implicitly zeroed (clang/gcc semantics). When the 1200 * variable is fully written before any read the store is dead and the 1201 * optimizer drops it. VLAs and incomplete arrays are left alone. */ 1202 c_cg_set_loc(p, loc); 1203 /* Zero the whole object in one memset rather than recursing to one store 1204 * per scalar leaf. The per-leaf path is O(leaves^2) on large aggregates 1205 * (each leaf store stashes a fresh frontend temp, growing g->nlocals, 1206 * which api_local_const_address_taken then re-scans on every store) and 1207 * explodes under ASAN — e.g. a 28 KB manifest local in src/api/package.c 1208 * stalled the debug bootstrap for minutes. memset is also what gcc/clang 1209 * emit for -ftrivial-auto-var-init=zero. */ 1210 zero_object_bytes_at(p, s, var_ty, 0, var_ty); 1211 } 1212 } 1213 } 1214 1215 void parse_local_decl(Parser* p, const DeclSpecs* specs) { 1216 if (accept_punct(p, ';')) return; 1217 parse_init_declarator(p, specs); 1218 while (accept_punct(p, ',')) { 1219 parse_init_declarator(p, specs); 1220 } 1221 expect_punct(p, ';', "';' after declaration"); 1222 } 1223 1224 /* ============================================================ 1225 * External (top-level) declarations 1226 * ============================================================ */ 1227 1228 void parse_param_list(Parser* p, ParamInfo** infos_out, u16* nparams_out, 1229 u8* variadic_out) { 1230 ParamInfo* infos; 1231 u32 cap = 4; 1232 u32 n = 0; 1233 *variadic_out = 0; 1234 *infos_out = NULL; 1235 *nparams_out = 0; 1236 1237 if (is_punct(&p->cur, ')')) { 1238 return; 1239 } 1240 if (is_kw(p, &p->cur, KW_VOID)) { 1241 Tok n2 = peek1(p); 1242 if (is_punct(&n2, ')')) { 1243 advance(p); /* `void` */ 1244 return; /* `(void)` */ 1245 } 1246 } 1247 1248 infos = (ParamInfo*)arena_array(p->pool->arena, ParamInfo, cap); 1249 for (;;) { 1250 DeclSpecs specs; 1251 Sym pname = 0; 1252 SrcLoc ploc = {0, 0, 0}; 1253 const Type* pty; 1254 if (accept_punct(p, P_ELLIPSIS)) { 1255 if (n == 0) perr(p, "ellipsis requires a preceding parameter"); 1256 *variadic_out = 1; 1257 break; 1258 } 1259 if (!parse_decl_specs(p, &specs)) { 1260 perr(p, "expected parameter type"); 1261 } 1262 if ((specs.storage_explicit && specs.storage != DS_REGISTER) || 1263 specs.storage == DS_TYPEDEF || (specs.flags & DF_THREAD)) { 1264 perr(p, "invalid storage-class specifier in parameter declaration"); 1265 } 1266 p->param_vla_bound_len = 0; 1267 p->in_param_decl++; 1268 pty = parse_declarator_full(p, specs.type, /*allow_abstract=*/1, &pname, 1269 &ploc); 1270 p->in_param_decl--; 1271 const Type* declared_pty = pty; 1272 if (pty && pty->kind == TY_ARRAY) { 1273 pty = type_ptr(p->pool, pty->arr.elem); 1274 } else if (pty && pty->kind == TY_FUNC) { 1275 pty = type_ptr(p->pool, pty); 1276 } 1277 if (pty && pty->kind == TY_VOID) { 1278 perr(p, "'void' must be the only parameter"); 1279 } 1280 validate_decl_type_constraints(p, &specs, pty, /*is_function=*/0, 1281 /*is_member=*/0); 1282 if (pname) { 1283 for (u32 pi = 0; pi < n; ++pi) { 1284 if (infos[pi].name == pname) perr(p, "redefinition of parameter"); 1285 } 1286 } 1287 if (n == cap) { 1288 cap *= 2; 1289 ParamInfo* nbuf = (ParamInfo*)arena_array(p->pool->arena, ParamInfo, cap); 1290 memcpy(nbuf, infos, sizeof(ParamInfo) * n); 1291 infos = nbuf; 1292 } 1293 infos[n].name = pname; 1294 infos[n].type = pty; 1295 infos[n].declared_type = declared_pty; 1296 infos[n].loc = ploc; 1297 infos[n].vla_bounds = NULL; 1298 infos[n].vla_bound_len = p->param_vla_bound_len; 1299 if (p->param_vla_bound_len) { 1300 ParamVLABoundExpr* bounds = arena_array(p->pool->arena, ParamVLABoundExpr, 1301 p->param_vla_bound_len); 1302 memcpy(bounds, p->param_vla_bounds, 1303 sizeof(ParamVLABoundExpr) * p->param_vla_bound_len); 1304 infos[n].vla_bounds = bounds; 1305 } 1306 ++n; 1307 if (!accept_punct(p, ',')) break; 1308 } 1309 *infos_out = infos; 1310 *nparams_out = (u16)n; 1311 } 1312 1313 static SymEntry* declare_function(Parser* p, Sym fname, const Type* fn_ty, 1314 const DeclSpecs* specs, SrcLoc fname_loc, 1315 const Attr* dattrs, Sym asm_label, 1316 ObjSecId* out_section_id, u32* out_decl_flags, 1317 Sym* out_alias_target) { 1318 SymEntry* visible; 1319 if (out_section_id) *out_section_id = OBJ_SEC_NONE; 1320 if (out_decl_flags) *out_decl_flags = 0; 1321 if (out_alias_target) *out_alias_target = 0; 1322 SymEntry* existing = scope_lookup_current(p, fname); 1323 if (existing && existing->kind != SEK_FUNC) { 1324 perr(p, "redefinition of identifier"); 1325 } 1326 if (existing && existing->kind == SEK_FUNC) { 1327 const Type* composite = NULL; 1328 CSemCheck chk = 1329 c_sem_check_redeclaration(p->pool, existing->type, fn_ty, &composite); 1330 if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message))); 1331 if (specs->storage == DS_STATIC && existing->linkage == DL_EXTERNAL) { 1332 perr(p, "static declaration follows non-static declaration"); 1333 } 1334 existing->type = composite ? composite : existing->type; 1335 Decl tmp; 1336 memset(&tmp, 0, sizeof tmp); 1337 attr_list_to_decl(p->c, p->decls, specs->attrs, &tmp); 1338 attr_list_to_decl(p->c, p->decls, dattrs, &tmp); 1339 if (out_section_id) *out_section_id = tmp.section_id; 1340 if (out_decl_flags) *out_decl_flags = tmp.flags; 1341 if (out_alias_target) *out_alias_target = tmp.alias_target; 1342 decl_apply_redecl_flags(p->decls, existing->decl_id, tmp.flags); 1343 external_func_remember(p, fname, existing); 1344 return existing; 1345 } 1346 /* `existing` is provably NULL here (both branches above perr or return), so 1347 * the current scope has no binding for fname. Skip re-probing it: walk from 1348 * the parent scope. */ 1349 visible = scope_lookup_from(p->scope ? p->scope->parent : NULL, fname); 1350 if (!existing && visible && visible->kind == SEK_FUNC) { 1351 existing = visible; 1352 } 1353 if (!existing) { 1354 existing = external_func_lookup(p, fname); 1355 } 1356 if (existing) { 1357 const Type* composite = NULL; 1358 CSemCheck chk = 1359 c_sem_check_redeclaration(p->pool, existing->type, fn_ty, &composite); 1360 if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message))); 1361 if (specs->storage == DS_STATIC && existing->linkage == DL_EXTERNAL) { 1362 perr(p, "static declaration follows non-static declaration"); 1363 } 1364 if (scope_lookup_current(p, fname) != existing) { 1365 SymEntry* e = scope_define(p, fname, SEK_FUNC, 1366 composite ? composite : existing->type); 1367 e->v.sym = existing->v.sym; 1368 sym_set_decl(e, existing->decl_id, (DeclStorage)existing->storage, 1369 (DeclLinkage)existing->linkage, existing->decl_flags, 1370 (DeclState)existing->decl_state); 1371 existing = e; 1372 } else if (composite) { 1373 existing->type = composite; 1374 } 1375 { 1376 Decl tmp; 1377 memset(&tmp, 0, sizeof tmp); 1378 attr_list_to_decl(p->c, p->decls, specs->attrs, &tmp); 1379 attr_list_to_decl(p->c, p->decls, dattrs, &tmp); 1380 if (out_section_id) *out_section_id = tmp.section_id; 1381 if (out_decl_flags) *out_decl_flags = tmp.flags; 1382 if (out_alias_target) *out_alias_target = tmp.alias_target; 1383 decl_apply_redecl_flags(p->decls, existing->decl_id, tmp.flags); 1384 } 1385 external_func_remember(p, fname, existing); 1386 return existing; 1387 } 1388 { 1389 Decl decl_in; 1390 DeclId did; 1391 ObjSymId fsym; 1392 SymEntry* e; 1393 memset(&decl_in, 0, sizeof decl_in); 1394 decl_in.name = fname; 1395 decl_in.asm_name = asm_label; 1396 decl_in.type = fn_ty; 1397 decl_in.loc = fname_loc; 1398 decl_in.storage = 1399 (specs->storage == DS_STATIC || 1400 ((specs->flags & DF_INLINE) && specs->storage != DS_EXTERN)) 1401 ? DS_STATIC 1402 : DS_EXTERN; 1403 decl_in.linkage = 1404 (decl_in.storage == DS_STATIC) ? DL_INTERNAL : DL_EXTERNAL; 1405 decl_in.visibility = 1406 decl_in.linkage == DL_EXTERNAL ? p->default_visibility : SV_DEFAULT; 1407 attr_list_to_decl(p->c, p->decls, specs->attrs, &decl_in); 1408 attr_list_to_decl(p->c, p->decls, dattrs, &decl_in); 1409 /* The `inline` specifier is a keyword carried on specs->flags, separate from 1410 * the __attribute__ flags attr_list_to_decl applies. It must be merged onto 1411 * the decl so decl_inline_policy() sees it on both the recorded symbol attrs 1412 * (decl_declare below) and the returned decl flags (out_decl_flags, used to 1413 * build the function descriptor). Without this, `static inline` functions 1414 * silently fell back to the DEFAULT inline policy — only the always_inline / 1415 * noinline attributes reached codegen — so a `static inline` body got no 1416 * stronger inlining than a plain static one. */ 1417 decl_in.flags |= (specs->flags & DF_INLINE); 1418 did = decl_declare(p->decls, &decl_in); 1419 fsym = decl_obj_sym(p->decls, did); 1420 e = scope_define(p, fname, SEK_FUNC, fn_ty); 1421 e->v.sym = fsym; 1422 sym_set_decl(e, did, decl_in.storage, decl_in.linkage, decl_in.flags, 1423 DSTATE_DECLARED); 1424 external_func_remember(p, fname, e); 1425 if (out_section_id) *out_section_id = decl_in.section_id; 1426 if (out_decl_flags) *out_decl_flags = decl_in.flags; 1427 if (out_alias_target) *out_alias_target = decl_in.alias_target; 1428 return e; 1429 } 1430 } 1431 1432 static void parse_function_body(Parser* p, ObjSymId fsym, const Type* fn_ty, 1433 const ABIFuncInfo* abi, const ParamInfo* infos, 1434 u16 nparams, SrcLoc fname_loc, 1435 ObjSecId section_id, u32 decl_flags) { 1436 CGFuncDesc fd; 1437 CGParamDesc* pds = NULL; 1438 1439 memset(&fd, 0, sizeof fd); 1440 fd.sym = fsym; 1441 fd.text_section_id = section_id; 1442 fd.group_id = OBJ_GROUP_NONE; 1443 fd.fn_type = fn_ty; 1444 fd.abi = abi; 1445 fd.params = NULL; 1446 fd.nparams = nparams; 1447 fd.loc = fname_loc; 1448 if (decl_flags & DF_NORETURN) fd.flags |= CGFD_NORETURN; 1449 if (decl_flags & DF_NOINLINE) 1450 fd.inline_policy = KIT_CG_INLINE_NEVER; 1451 else if (decl_flags & DF_ALWAYS_INLINE) 1452 fd.inline_policy = KIT_CG_INLINE_ALWAYS; 1453 else if (decl_flags & DF_INLINE) 1454 fd.inline_policy = KIT_CG_INLINE_HINT; 1455 1456 if (nparams) { 1457 pds = (CGParamDesc*)arena_array(p->pool->arena, CGParamDesc, nparams); 1458 memset(pds, 0, sizeof(CGParamDesc) * nparams); 1459 for (u16 i = 0; i < nparams; ++i) { 1460 pds[i].index = i; 1461 pds[i].name = infos[i].name; 1462 pds[i].type = infos[i].type; 1463 pds[i].slot = FRAME_SLOT_NONE; 1464 pds[i].abi = &abi->params[i]; 1465 pds[i].incoming = NULL; 1466 pds[i].nincoming = 0; 1467 pds[i].loc = infos[i].loc; 1468 } 1469 fd.params = pds; 1470 } 1471 1472 scope_push(p); /* parameter scope */ 1473 GotoLabel* saved_goto_labels = p->goto_labels; 1474 SwitchCtx* saved_switch = p->cur_switch; 1475 u8 saved_computed_goto = p->computed_goto_emitted; 1476 p->goto_labels = NULL; 1477 p->cur_switch = NULL; 1478 p->computed_goto_emitted = 0; 1479 c_cg_set_loc(p, fname_loc); 1480 /* Record whether this body emits before func_begin (which is itself gated on 1481 * emit-enabled): goto-label allocation keys off this, not the momentary 1482 * suppress_codegen depth, so a label first referenced inside a constant-false 1483 * region still gets a real CG-label id rather than the suppression sentinel. 1484 */ 1485 p->cur_func_emits = (u8)c_cg_emit_enabled(p); 1486 p->stack_protector_enabled = 0; 1487 c_cg_func_begin(p, &fd); 1488 1489 for (u16 i = 0; i < nparams; ++i) { 1490 FrameSlotDesc fsd; 1491 FrameSlot s; 1492 SymEntry* e; 1493 memset(&fsd, 0, sizeof fsd); 1494 fsd.type = infos[i].type; 1495 fsd.name = infos[i].name; 1496 fsd.loc = infos[i].loc; 1497 fsd.size = c_abi_sizeof(p->abi, p->pool, infos[i].type); 1498 fsd.align = c_abi_alignof(p->abi, p->pool, infos[i].type); 1499 fsd.kind = FS_PARAM; 1500 fsd.flags = FSF_NONE; 1501 s = c_cg_param_slot(p, i, &fsd); 1502 pds[i].slot = s; 1503 if (infos[i].name) { 1504 e = scope_define_checked(p, infos[i].name, SEK_LOCAL, infos[i].type); 1505 e->v.slot = s; 1506 sym_set_decl(e, DECL_NONE, DS_AUTO, DL_NONE, DF_NONE, DSTATE_DEFINED); 1507 e->vla_bounds = build_param_vla_bounds(p, &infos[i], infos[i].loc); 1508 } 1509 } 1510 1511 if (p->stack_protector_mode == KIT_STACK_PROTECTOR_ALL || 1512 p->stack_protector_preselected) 1513 c_stack_protector_enable(p); 1514 1515 parse_compound_stmt(p); 1516 if (fn_ty->fn.ret && fn_ty->fn.ret->kind != TY_VOID && 1517 fn_ty->fn.ret->kind != TY_STRUCT && fn_ty->fn.ret->kind != TY_UNION) { 1518 c_cg_push_int(p, 0, fn_ty->fn.ret); 1519 c_cg_ret(p, 1); 1520 } else { 1521 c_cg_ret(p, 0); 1522 } 1523 for (GotoLabel* gl = p->goto_labels; gl; gl = gl->next) { 1524 if (!gl->placed) { 1525 compiler_panic(p->c, gl->first_use, "goto to undefined label"); 1526 } 1527 } 1528 p->goto_labels = saved_goto_labels; 1529 p->cur_switch = saved_switch; 1530 p->computed_goto_emitted = saved_computed_goto; 1531 c_cg_func_end(p); 1532 scope_pop(p); 1533 } 1534 1535 /* Parse one external declaration. */ 1536 static void parse_external_decl(Parser* p) { 1537 DeclSpecs specs; 1538 Sym name; 1539 SrcLoc loc; 1540 const Type* base_ty; 1541 Attr* dattrs = NULL; 1542 DeclaratorInfo dinfo; 1543 1544 if (!parse_decl_specs(p, &specs)) { 1545 perr(p, "expected declaration"); 1546 } 1547 if (specs.storage == DS_AUTO && specs.storage_explicit) { 1548 perr(p, "invalid storage-class specifier at file scope"); 1549 } 1550 1551 if (accept_punct(p, ';')) return; 1552 1553 if (specs.storage == DS_TYPEDEF) { 1554 for (;;) { 1555 Sym tname = 0; 1556 SrcLoc tloc = {0, 0, 0}; 1557 const Type* tty = 1558 parse_declarator_full(p, specs.type, 1559 /*allow_abstract=*/0, &tname, &tloc); 1560 validate_decl_type_constraints(p, &specs, tty, 1561 tty && tty->kind == TY_FUNC, 1562 /*is_member=*/0); 1563 if (is_punct(&p->cur, '=')) { 1564 perr(p, "typedef declarator cannot have initializer"); 1565 } 1566 { 1567 SymEntry* te = scope_define_checked(p, tname, SEK_TYPEDEF, tty); 1568 sym_set_decl(te, DECL_NONE, DS_TYPEDEF, DL_NONE, specs.flags, 1569 DSTATE_DECLARED); 1570 } 1571 (void)tloc; 1572 if (!accept_punct(p, ',')) break; 1573 } 1574 expect_punct(p, ';', "';' after typedef declaration"); 1575 return; 1576 } 1577 1578 base_ty = parse_declarator_full_info(p, specs.type, /*allow_abstract=*/0, 1579 &name, &loc, &dattrs, &dinfo); 1580 1581 if (base_ty && base_ty->kind == TY_FUNC) { 1582 ParamInfo* infos = NULL; 1583 u16 nparams = 0; 1584 const Type* fn_ty; 1585 const ABIFuncInfo* abi; 1586 SymEntry* fent; 1587 1588 fn_ty = base_ty; 1589 infos = dinfo.fn_params; 1590 nparams = dinfo.fn_nparams; 1591 validate_decl_type_constraints(p, &specs, fn_ty, /*is_function=*/1, 1592 /*is_member=*/0); 1593 abi = c_abi_func_info(p->abi, p->pool, fn_ty); 1594 1595 ObjSecId fn_section_id; 1596 u32 fn_decl_flags; 1597 Sym fn_alias_target; 1598 fent = 1599 declare_function(p, name, fn_ty, &specs, loc, dattrs, dinfo.asm_label, 1600 &fn_section_id, &fn_decl_flags, &fn_alias_target); 1601 attr_list_append(&fent->attrs, dattrs); 1602 1603 if (is_punct(&p->cur, '{')) { 1604 int suppress_body_codegen = specs.storage == DS_EXTERN && 1605 ((specs.flags | fn_decl_flags) & DF_INLINE); 1606 if (fent->defined) perr(p, "redefinition of function"); 1607 fent->defined = 1; 1608 fent->decl_state = DSTATE_FUNC_DEFINED; 1609 Sym saved_func_name = p->cur_func_name; 1610 const Type* saved_func_ret = p->cur_func_ret; 1611 u8 saved_func_emits = p->cur_func_emits; 1612 p->cur_func_name = name; 1613 p->cur_func_ret = fn_ty->fn.ret; 1614 if (p->stack_protector_mode == KIT_STACK_PROTECTOR_BASIC || 1615 p->stack_protector_mode == KIT_STACK_PROTECTOR_STRONG) { 1616 record_function_body(p); 1617 p->stack_protector_scan = 1; 1618 p->stack_protector_scan_selected = 0; 1619 c_cg_codegen_suppress_push(p); 1620 parse_function_body(p, fent->v.sym, fn_ty, abi, infos, nparams, loc, 1621 fn_section_id, fn_decl_flags); 1622 c_cg_codegen_suppress_pop(p); 1623 p->stack_protector_scan = 0; 1624 p->stack_protector_preselected = 1625 p->stack_protector_scan_selected ? 1u : 0u; 1626 rewind_function_body(p, 0); 1627 } 1628 if (suppress_body_codegen) c_cg_codegen_suppress_push(p); 1629 parse_function_body(p, fent->v.sym, fn_ty, abi, infos, nparams, loc, 1630 fn_section_id, fn_decl_flags); 1631 if (suppress_body_codegen) c_cg_codegen_suppress_pop(p); 1632 p->stack_protector_preselected = 0; 1633 p->function_replay_active = 0; 1634 p->function_replay_hold = 0; 1635 p->cur_func_name = saved_func_name; 1636 p->cur_func_ret = saved_func_ret; 1637 p->cur_func_emits = saved_func_emits; 1638 return; 1639 } 1640 if (accept_punct(p, ';')) { 1641 if (fn_alias_target != 0) { 1642 SymEntry* te = scope_lookup(p, fn_alias_target); 1643 if (!te) { 1644 const char* nm = kit_sym_str(p->pool->c, fn_alias_target).s; 1645 compiler_panic(p->c, loc, "alias target '%.*s' is undefined", 1646 KIT_SLICE_ARG(kit_slice_cstr(nm ? nm : "?"))); 1647 } 1648 KitCgAlias alias; 1649 memset(&alias, 0, sizeof alias); 1650 alias.display_name = name; 1651 alias.linkage_name = kit_cg_c_linkage_name(p->c, name); 1652 alias.target = te->v.sym; 1653 alias.sym.bind = 1654 (fn_decl_flags & DF_WEAK) ? KIT_SB_WEAK : KIT_SB_GLOBAL; 1655 { 1656 const Decl* fd = decl_get(p->decls, fent->decl_id); 1657 alias.sym.visibility = 1658 fd ? (KitCgVisibility)fd->visibility : KIT_CG_VIS_DEFAULT; 1659 } 1660 if (kit_cg_alias(p->cg, alias) == KIT_CG_SYM_NONE) { 1661 const char* nm = kit_sym_str(p->pool->c, fn_alias_target).s; 1662 compiler_panic(p->c, loc, "alias target '%.*s' is undefined", 1663 KIT_SLICE_ARG(kit_slice_cstr(nm ? nm : "?"))); 1664 } 1665 } 1666 return; 1667 } 1668 perr(p, "expected '{' or ';' after function declarator"); 1669 } 1670 1671 /* Global object declaration. */ 1672 for (;;) { 1673 int has_init = is_punct(&p->cur, '='); 1674 int is_pure_extern = 1675 (specs.storage == DS_EXTERN || specs.storage == DS_REGISTER) && 1676 !has_init; 1677 SymEntry* existing = scope_lookup_current(p, name); 1678 ObjSymId sym = OBJ_SYM_NONE; 1679 ObjSecId section_id = OBJ_SEC_NONE; 1680 SymEntry* e = NULL; 1681 1682 if (existing && existing->kind != SEK_GLOBAL) { 1683 perr(p, "redefinition of identifier"); 1684 } 1685 validate_decl_type_constraints(p, &specs, base_ty, /*is_function=*/0, 1686 /*is_member=*/0); 1687 1688 if (existing && existing->kind == SEK_GLOBAL) { 1689 const Type* composite = NULL; 1690 CSemCheck chk = c_sem_check_redeclaration(p->pool, existing->type, 1691 base_ty, &composite); 1692 if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message))); 1693 if (specs.storage == DS_STATIC && existing->linkage == DL_EXTERNAL) { 1694 perr(p, "static declaration follows non-static declaration"); 1695 } 1696 sym = existing->v.sym; 1697 e = existing; 1698 if (has_init && e->defined) { 1699 perr(p, "redefinition of object"); 1700 } 1701 if (composite) e->type = composite; 1702 base_ty = e->type; 1703 } else { 1704 Decl decl_in; 1705 DeclId did; 1706 memset(&decl_in, 0, sizeof decl_in); 1707 decl_in.name = name; 1708 decl_in.asm_name = dinfo.asm_label; 1709 decl_in.type = base_ty; 1710 decl_in.loc = loc; 1711 if (specs.storage == DS_STATIC) { 1712 decl_in.storage = DS_STATIC; 1713 decl_in.linkage = DL_INTERNAL; 1714 } else { 1715 decl_in.storage = DS_EXTERN; 1716 decl_in.linkage = DL_EXTERNAL; 1717 } 1718 decl_in.visibility = 1719 decl_in.linkage == DL_EXTERNAL ? p->default_visibility : SV_DEFAULT; 1720 decl_in.flags = specs.flags & DF_THREAD; 1721 attr_list_to_decl(p->c, p->decls, specs.attrs, &decl_in); 1722 attr_list_to_decl(p->c, p->decls, dattrs, &decl_in); 1723 did = decl_declare(p->decls, &decl_in); 1724 sym = decl_obj_sym(p->decls, did); 1725 section_id = decl_in.section_id; 1726 e = scope_define(p, name, SEK_GLOBAL, base_ty); 1727 e->v.sym = sym; 1728 sym_set_decl(e, did, decl_in.storage, decl_in.linkage, decl_in.flags, 1729 DSTATE_DECLARED); 1730 } 1731 attr_list_append(&e->attrs, dattrs); 1732 1733 u32 attr_align = attrs_pick_aligned(specs.attrs); 1734 { 1735 u32 a2 = attrs_pick_aligned(dattrs); 1736 if (a2 > attr_align) attr_align = a2; 1737 } 1738 u32 align_eff = (specs.align > attr_align) ? specs.align : attr_align; 1739 1740 if (has_init) { 1741 if (e) e->defined = 1; 1742 if (e) e->decl_state = DSTATE_DEFINED; 1743 advance(p); /* '=' */ 1744 if (base_ty && base_ty->kind == TY_ARRAY && base_ty->arr.incomplete) { 1745 const Type* completed = complete_incomplete_array(p, base_ty); 1746 if (completed != base_ty) { 1747 base_ty = completed; 1748 if (e) e->type = base_ty; 1749 } 1750 } 1751 define_static_object(p, sym, section_id, base_ty, specs.quals, 1752 /*has_init=*/1, loc, align_eff); 1753 } else if (!is_pure_extern) { 1754 if (e && e->decl_state == DSTATE_DECLARED) { 1755 e->decl_state = DSTATE_TENTATIVE; 1756 } 1757 define_static_object(p, sym, section_id, base_ty, specs.quals, 1758 /*has_init=*/0, loc, align_eff); 1759 } 1760 1761 if (!accept_punct(p, ',')) break; 1762 dattrs = NULL; 1763 base_ty = parse_declarator_full_info(p, specs.type, /*allow_abstract=*/0, 1764 &name, &loc, &dattrs, &dinfo); 1765 if (base_ty && base_ty->kind == TY_FUNC) { 1766 perr(p, "function declarator in object declaration list"); 1767 } 1768 } 1769 expect_punct(p, ';', "';' after global declaration"); 1770 } 1771 1772 static void parse_file_scope_asm(Parser* p) { 1773 u8* bytes; 1774 size_t nbytes; 1775 advance(p); /* asm / __asm__ */ 1776 for (;;) { 1777 if (is_kw(p, &p->cur, 1778 KW_VOLATILE)) { /* matches `volatile` and `__volatile__` */ 1779 advance(p); 1780 continue; 1781 } 1782 break; 1783 } 1784 expect_punct(p, '(', "'(' after file-scope asm"); 1785 if (p->cur.kind != TOK_STR) { 1786 perr(p, "expected string literal in file-scope asm"); 1787 } 1788 bytes = decode_string_literal(p, &p->cur, &nbytes); 1789 advance(p); 1790 expect_punct(p, ')', "')' after file-scope asm"); 1791 expect_punct(p, ';', "';' after file-scope asm"); 1792 if (nbytes > 0) --nbytes; /* drop decode_string_literal's trailing NUL */ 1793 if (c_cg_emit_enabled(p)) { 1794 KitSlice asm_src = {{(const char*)bytes}, nbytes}; 1795 kit_cg_file_scope_asm(p->cg, asm_src); 1796 } 1797 } 1798 1799 static void parse_translation_unit(Parser* p) { 1800 while (p->cur.kind != TOK_EOF) { 1801 if (p->cur.kind == TOK_NEWLINE || is_pp_hash(&p->cur)) { 1802 advance(p); 1803 continue; 1804 } 1805 if (is_kw(p, &p->cur, KW_STATIC_ASSERT)) { 1806 parse_static_assert(p); 1807 continue; 1808 } 1809 if (is_kw(p, &p->cur, KW_ASM) || is_kw(p, &p->cur, KW_BUILTIN_ASM)) { 1810 parse_file_scope_asm(p); 1811 continue; 1812 } 1813 if (accept_punct(p, ';')) { 1814 continue; 1815 } 1816 parse_external_decl(p); 1817 } 1818 } 1819 1820 /* ============================================================ 1821 * Entry point 1822 * ============================================================ */ 1823 1824 static u8 parser_default_visibility(KitSymVis vis) { 1825 switch (vis) { 1826 case KIT_SV_HIDDEN: 1827 case KIT_SV_INTERNAL: 1828 return SV_HIDDEN; 1829 case KIT_SV_PROTECTED: 1830 return SV_PROTECTED; 1831 case KIT_SV_DEFAULT: 1832 default: 1833 return SV_DEFAULT; 1834 } 1835 } 1836 1837 void parse_c(Compiler* c, Pool* pool, Pp* pp, DeclTable* decls, CG* cg, 1838 KitSymVis default_visibility, int auto_var_init, 1839 int stack_protector, 1840 uint64_t disabled_backend_features) { 1841 Parser p; 1842 CKw i; 1843 u32 syscall_i; 1844 1845 memset(&p, 0, sizeof p); 1846 p.c = c; 1847 p.pp = pp; 1848 p.decls = decls; 1849 p.cg = cg; 1850 p.abi = c; 1851 p.pool = pool; 1852 p.default_visibility = parser_default_visibility(default_visibility); 1853 p.auto_var_init = (u8)auto_var_init; 1854 p.stack_protector_mode = (u8)stack_protector; 1855 p.general_regs_only = 1856 (disabled_backend_features & KIT_CG_BACKEND_SIMD) != 0; 1857 1858 /* Index storage for the scope/tag tables and the external-function table all 1859 * comes from the arena via the pool's shared arena-heap facade. */ 1860 ExternalFuncMap_init(&p.external_funcs, &p.pool->arena_heap); 1861 KwTab_init(&p.kw_map, &p.pool->arena_heap); 1862 BindingTab_init(&p.bind, &p.pool->arena_heap); 1863 1864 for (i = (CKw)1; i < KW_COUNT; ++i) { 1865 p.kw_sym[i] = kit_sym_intern(p.pool->c, kit_slice_cstr(kw_names[i])); 1866 (void)KwTab_set(&p.kw_map, p.kw_sym[i], (u8)i); /* canonical keyword */ 1867 } 1868 1869 p.sym_b_alloca = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_alloca")); 1870 p.sym_b_ctz = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_ctz")); 1871 p.sym_b_ctzl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_ctzl")); 1872 p.sym_b_ctzll = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_ctzll")); 1873 p.sym_b_clz = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_clz")); 1874 p.sym_b_clzl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_clzl")); 1875 p.sym_b_clzll = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_clzll")); 1876 p.sym_b_trap = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_trap")); 1877 p.sym_b_unreachable = 1878 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_unreachable")); 1879 p.sym_b_return_address = 1880 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_return_address")); 1881 p.sym_b_frame_address = 1882 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_frame_address")); 1883 p.sym_b_readcyclecounter = 1884 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_readcyclecounter")); 1885 for (syscall_i = 0; syscall_i < 7u; ++syscall_i) { 1886 char name[16]; 1887 memcpy(name, "__kit_syscall", 13u); 1888 name[13] = (char)('0' + syscall_i); 1889 name[14] = '\0'; 1890 p.sym_kit_syscall[syscall_i] = 1891 kit_sym_intern(p.pool->c, kit_slice_cstr(name)); 1892 } 1893 p.sym_b_memcpy = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_memcpy")); 1894 p.sym_b_memmove = 1895 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_memmove")); 1896 p.sym_b_memcmp = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_memcmp")); 1897 p.sym_b_memset = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_memset")); 1898 p.sym_b_clear_cache = 1899 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin___clear_cache")); 1900 p.sym_b_isnan = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isnan")); 1901 p.sym_b_fabs = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_fabs")); 1902 p.sym_b_fabsf = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_fabsf")); 1903 p.sym_b_fabsl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_fabsl")); 1904 p.sym_b_inf = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_inf")); 1905 p.sym_b_inff = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_inff")); 1906 p.sym_b_infl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_infl")); 1907 p.sym_b_huge_val = 1908 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_huge_val")); 1909 p.sym_b_huge_valf = 1910 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_huge_valf")); 1911 p.sym_b_huge_vall = 1912 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_huge_vall")); 1913 p.sym_b_nan = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_nan")); 1914 p.sym_b_nanf = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_nanf")); 1915 p.sym_b_nanl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_nanl")); 1916 p.sym_b_isless = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isless")); 1917 p.sym_b_islessequal = 1918 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_islessequal")); 1919 p.sym_b_isgreater = 1920 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isgreater")); 1921 p.sym_b_isgreaterequal = 1922 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isgreaterequal")); 1923 p.sym_b_islessgreater = 1924 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_islessgreater")); 1925 p.sym_b_isunordered = 1926 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isunordered")); 1927 p.sym_func = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__func__")); 1928 p.sym_func_gcc = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__FUNCTION__")); 1929 p.sym_pretty_func_gcc = 1930 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__PRETTY_FUNCTION__")); 1931 p.sym_b_expect = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_expect")); 1932 p.sym_b_offsetof = 1933 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_offsetof")); 1934 p.sym_b_constant_p = 1935 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_constant_p")); 1936 p.sym_b_va_list = 1937 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_list")); 1938 p.sym_b_va_start = 1939 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_start")); 1940 p.sym_b_va_arg = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_arg")); 1941 p.sym_b_va_end = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_end")); 1942 p.sym_b_va_copy = 1943 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_copy")); 1944 p.sym_attribute = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__attribute__")); 1945 p.sym_volatile_alias = 1946 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__volatile__")); 1947 p.sym_alignof_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__alignof__")); 1948 p.sym_typeof_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__typeof")); 1949 p.sym_typeof_alias2 = 1950 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__typeof__")); 1951 p.sym_asm_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__asm")); 1952 p.sym_inline_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__inline")); 1953 p.sym_inline_alias2 = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__inline__")); 1954 /* __restrict / __restrict__: GCC keyword spellings of `restrict`. glibc 1955 * headers use these as real keywords (and #undef any fallback macro under 1956 * __GNUC__), so recognize them in the parser, not just via a pp macro. */ 1957 p.sym_restrict_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__restrict")); 1958 p.sym_restrict_alias2 = 1959 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__restrict__")); 1960 p.sym_thread_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__thread")); 1961 /* GNU alias spellings -> their canonical CKw. Registered after the canonical 1962 * keywords above so the canonical mapping always wins (matching the old 1963 * ident_kw_inline fall-through, which scanned kw_sym[] before the aliases). 1964 */ 1965 (void)KwTab_set(&p.kw_map, p.sym_alignof_alias, (u8)KW_ALIGNOF); 1966 (void)KwTab_set(&p.kw_map, p.sym_asm_alias, (u8)KW_BUILTIN_ASM); 1967 (void)KwTab_set(&p.kw_map, p.sym_inline_alias, (u8)KW_INLINE); 1968 (void)KwTab_set(&p.kw_map, p.sym_inline_alias2, (u8)KW_INLINE); 1969 (void)KwTab_set(&p.kw_map, p.sym_restrict_alias, (u8)KW_RESTRICT); 1970 (void)KwTab_set(&p.kw_map, p.sym_restrict_alias2, (u8)KW_RESTRICT); 1971 (void)KwTab_set(&p.kw_map, p.sym_thread_alias, (u8)KW_THREAD_LOCAL); 1972 (void)KwTab_set(&p.kw_map, p.sym_volatile_alias, (u8)KW_VOLATILE); 1973 p.sym_int128 = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__int128")); 1974 p.sym_int128_t = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__int128_t")); 1975 p.sym_uint128_t = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__uint128_t")); 1976 p.sym_a_load_n = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_load_n")); 1977 p.sym_a_store_n = 1978 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_store_n")); 1979 p.sym_a_exchange_n = 1980 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_exchange_n")); 1981 p.sym_a_fetch_add = 1982 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_add")); 1983 p.sym_a_fetch_sub = 1984 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_sub")); 1985 p.sym_a_fetch_and = 1986 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_and")); 1987 p.sym_a_fetch_or = 1988 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_or")); 1989 p.sym_a_fetch_xor = 1990 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_xor")); 1991 p.sym_a_fetch_nand = 1992 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_nand")); 1993 p.sym_a_cas_n = 1994 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_compare_exchange_n")); 1995 p.sym_a_always_lock_free = 1996 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_always_lock_free")); 1997 p.sym_a_is_lock_free = 1998 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_is_lock_free")); 1999 p.sym_a_thread_fence = 2000 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_thread_fence")); 2001 p.sym_a_signal_fence = 2002 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_signal_fence")); 2003 p.sym_sync_synchronize = 2004 kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__sync_synchronize")); 2005 2006 p.scope = scope_new(&p, NULL); 2007 2008 p.cur = fetch_tok(&p); 2009 2010 parse_translation_unit(&p); 2011 }