kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

parse.c (55181B)


      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(const Tok* t) { return t->loc; }
     83 
     84 _Noreturn void perr(Parser* p, const char* fmt, ...) {
     85   va_list ap;
     86   SrcLoc loc = tok_loc(&p->cur);
     87   va_start(ap, fmt);
     88   compiler_panicv(p->c, loc, fmt, ap);
     89 }
     90 
     91 /* ============================================================
     92  * Token helpers
     93  * ============================================================ */
     94 
     95 /* Width of an encoding prefix on a string-literal spelling: 0 for ordinary,
     96  * 1 for L/u/U, 2 for u8. */
     97 static size_t str_prefix_len(u16 flags) {
     98   if (flags & TF_STR_U8) return 2;
     99   if (flags & (TF_STR_WIDE | TF_STR_U16 | TF_STR_U32)) return 1;
    100   return 0;
    101 }
    102 
    103 #define STR_ENC_MASK (TF_STR_WIDE | TF_STR_U8 | TF_STR_U16 | TF_STR_U32)
    104 
    105 /* Fuse two adjacent TOK_STR tokens into one per C11 §6.4.5 ¶5. */
    106 static Tok fuse_string_lits(Parser* p, Tok a, Tok b) {
    107   u16 ae = (u16)(a.flags & STR_ENC_MASK);
    108   u16 be = (u16)(b.flags & STR_ENC_MASK);
    109   u16 fused_enc;
    110   KitSlice a_sl = kit_sym_str(p->pool->c, a.spelling);
    111   KitSlice b_sl = kit_sym_str(p->pool->c, b.spelling);
    112   size_t alen = a_sl.len, blen = b_sl.len;
    113   const char* as = a_sl.s;
    114   const char* bs = b_sl.s;
    115   size_t apfx, bpfx;
    116   size_t a_content_len, b_content_len;
    117   size_t out_pfx_len;
    118   size_t out_len;
    119   Heap* h = kit_compiler_context(p->c)->heap;
    120   char* buf;
    121   size_t k = 0;
    122   Tok out;
    123   if (!as || !bs) perr(p, "bad string literal in concatenation");
    124   if (ae != 0 && be != 0 && ae != be) {
    125     perr(p,
    126          "concatenating string literals with incompatible "
    127          "encoding prefixes");
    128   }
    129   fused_enc = ae ? ae : be;
    130   apfx = str_prefix_len(a.flags);
    131   bpfx = str_prefix_len(b.flags);
    132   if (alen < apfx + 2 || as[apfx] != '"' || as[alen - 1] != '"' ||
    133       blen < bpfx + 2 || bs[bpfx] != '"' || bs[blen - 1] != '"') {
    134     perr(p, "malformed string literal in concatenation");
    135   }
    136   a_content_len = alen - apfx - 2;
    137   b_content_len = blen - bpfx - 2;
    138   out_pfx_len = ae ? apfx : bpfx;
    139   out_len = out_pfx_len + 1 + a_content_len + b_content_len + 1;
    140   buf = (char*)h->alloc(h, out_len, 1);
    141   if (!buf) perr(p, "out of memory fusing string literals");
    142   if (out_pfx_len) {
    143     const char* src = ae ? as : bs;
    144     memcpy(buf + k, src, out_pfx_len);
    145     k += out_pfx_len;
    146   }
    147   buf[k++] = '"';
    148   if (a_content_len) {
    149     memcpy(buf + k, as + apfx + 1, a_content_len);
    150     k += a_content_len;
    151   }
    152   if (b_content_len) {
    153     memcpy(buf + k, bs + bpfx + 1, b_content_len);
    154     k += b_content_len;
    155   }
    156   buf[k++] = '"';
    157   out = a;
    158   out.spelling = kit_sym_intern(p->pool->c, (KitSlice){.s = buf, .len = k});
    159   out.flags = (u16)((a.flags & ~STR_ENC_MASK) | fused_enc);
    160   h->free(h, buf, 0);
    161   return out;
    162 }
    163 
    164 /* Pull one logical token from pp, collapsing adjacent TOK_STR runs. */
    165 static Tok fetch_tok(Parser* p) {
    166   Tok t;
    167   if (p->has_pending) {
    168     t = p->pending;
    169     p->has_pending = 0;
    170   } else {
    171     t = pp_next(p->pp);
    172   }
    173   if (t.kind != TOK_STR) return t;
    174   for (;;) {
    175     Tok n = pp_next(p->pp);
    176     if (n.kind != TOK_STR) {
    177       p->pending = n;
    178       p->has_pending = 1;
    179       return t;
    180     }
    181     t = fuse_string_lits(p, t, n);
    182   }
    183 }
    184 
    185 void advance(Parser* p) {
    186   if (p->replay_active) {
    187     if (p->replay_pos < p->replay_len) {
    188       p->cur = p->replay[p->replay_pos++];
    189       return;
    190     }
    191     p->replay_active = 0;
    192   }
    193   if (p->has_next) {
    194     p->cur = p->next;
    195     p->has_next = 0;
    196   } else {
    197     p->cur = fetch_tok(p);
    198   }
    199 }
    200 
    201 Tok peek1(Parser* p) {
    202   if (p->replay_active && p->replay_pos < p->replay_len) {
    203     return p->replay[p->replay_pos];
    204   }
    205   if (!p->has_next) {
    206     p->next = fetch_tok(p);
    207     p->has_next = 1;
    208   }
    209   return p->next;
    210 }
    211 
    212 void expect_punct(Parser* p, u32 punct, const char* what) {
    213   if (!accept_punct(p, punct)) {
    214     perr(p, "expected %.*s", KIT_SLICE_ARG(kit_slice_cstr(what)));
    215   }
    216 }
    217 
    218 int accept_punct(Parser* p, u32 punct) {
    219   if (is_punct(&p->cur, punct)) {
    220     advance(p);
    221     return 1;
    222   }
    223   return 0;
    224 }
    225 
    226 /* Record tokens from the current `{` through the matching `}` into the
    227  * parser's replay buffer. */
    228 void record_braced_block(Parser* p) {
    229   int depth = 0;
    230   if (!is_punct(&p->cur, '{')) perr(p, "internal: record on non-'{'");
    231   p->replay_len = 0;
    232   for (;;) {
    233     if (p->replay_len == p->replay_cap) {
    234       u32 new_cap = p->replay_cap ? p->replay_cap * 2 : 32;
    235       Tok* nv = arena_array(p->pool->arena, Tok, new_cap);
    236       if (!nv) perr(p, "out of memory in record_braced_block");
    237       if (p->replay && p->replay_len) {
    238         memcpy(nv, p->replay, p->replay_len * sizeof(Tok));
    239       }
    240       p->replay = nv;
    241       p->replay_cap = new_cap;
    242     }
    243     p->replay[p->replay_len++] = p->cur;
    244     if (is_punct(&p->cur, '{')) {
    245       ++depth;
    246     } else if (is_punct(&p->cur, '}')) {
    247       --depth;
    248       if (depth == 0) break;
    249     } else if (p->cur.kind == TOK_EOF) {
    250       perr(p, "unexpected end of file in initializer");
    251     }
    252     advance(p);
    253   }
    254 }
    255 
    256 /* After record_braced_block, rewind to replay from the start. */
    257 void replay_rewind(Parser* p) {
    258   if (p->replay_len == 0) perr(p, "internal: replay_rewind with empty buffer");
    259   p->cur = p->replay[0];
    260   p->replay_pos = 1;
    261   p->replay_active = 1;
    262   p->has_next = 0;
    263 }
    264 
    265 /* Count top-level items in a recorded brace list. */
    266 u32 count_recorded_top_level_items(const Tok* vec, u32 len) {
    267   u32 count;
    268   u32 i;
    269   int depth = 0;
    270   if (len < 2) return 0;
    271   if (len == 2) return 0; /* `{}` */
    272   count = 1;
    273   for (i = 1; i < len - 1; ++i) {
    274     const Tok* t = &vec[i];
    275     if (is_punct(t, '{') || is_punct(t, '(') || is_punct(t, '['))
    276       ++depth;
    277     else if (is_punct(t, '}') || is_punct(t, ')') || is_punct(t, ']'))
    278       --depth;
    279     else if (depth == 0 && is_punct(t, ','))
    280       ++count;
    281   }
    282   if (is_punct(&vec[len - 2], ',')) --count;
    283   return count;
    284 }
    285 
    286 /* ============================================================
    287  * Scopes
    288  * ============================================================ */
    289 
    290 Scope* scope_new(Parser* p, Scope* parent) {
    291   Scope* s = arena_new(p->pool->arena, Scope);
    292   if (!s) perr(p, "out of memory in scope_new");
    293   s->entries = NULL;
    294   s->tags = NULL;
    295   s->parent = parent;
    296   s->saved_vla_mark = p->vla_mark;
    297   return s;
    298 }
    299 
    300 void scope_push(Parser* p) { p->scope = scope_new(p, p->scope); }
    301 
    302 void scope_pop(Parser* p) {
    303   if (p->scope) {
    304     p->vla_mark = p->scope->saved_vla_mark;
    305     p->scope = p->scope->parent;
    306   }
    307 }
    308 
    309 SymEntry* scope_define(Parser* p, Sym name, SymEntryKind kind,
    310                        const Type* type) {
    311   SymEntry* e = arena_new(p->pool->arena, SymEntry);
    312   if (!e) perr(p, "out of memory in scope_define");
    313   memset(e, 0, sizeof *e);
    314   e->name = name;
    315   e->kind = (u8)kind;
    316   e->type = type;
    317   e->next = p->scope->entries;
    318   p->scope->entries = e;
    319   return e;
    320 }
    321 
    322 SymEntry* scope_lookup_current(Parser* p, Sym name) {
    323   SymEntry* e;
    324   if (!p->scope) return NULL;
    325   for (e = p->scope->entries; e; e = e->next) {
    326     if (e->name == name) return e;
    327   }
    328   return NULL;
    329 }
    330 
    331 SymEntry* scope_lookup(Parser* p, Sym name) {
    332   Scope* s;
    333   for (s = p->scope; s; s = s->parent) {
    334     SymEntry* e;
    335     for (e = s->entries; e; e = e->next) {
    336       if (e->name == name) return e;
    337     }
    338   }
    339   return NULL;
    340 }
    341 
    342 static void sym_set_decl(SymEntry* e, DeclId id, DeclStorage storage,
    343                          DeclLinkage linkage, u32 flags, DeclState state) {
    344   e->decl_id = id;
    345   e->storage = (u8)storage;
    346   e->linkage = (u8)linkage;
    347   e->decl_flags = flags;
    348   e->decl_state = (u8)state;
    349   e->defined = (state == DSTATE_DEFINED || state == DSTATE_FUNC_DEFINED);
    350 }
    351 
    352 static SymEntry* external_func_lookup(Parser* p, Sym name) {
    353   ExternalFuncDecl* f;
    354   for (f = p->external_funcs; f; f = f->next) {
    355     if (f->name == name) return f->entry;
    356   }
    357   return NULL;
    358 }
    359 
    360 static void external_func_remember(Parser* p, Sym name, SymEntry* entry) {
    361   ExternalFuncDecl* f;
    362   if (!entry) return;
    363   for (f = p->external_funcs; f; f = f->next) {
    364     if (f->name == name) {
    365       f->entry = entry;
    366       return;
    367     }
    368   }
    369   f = arena_new(p->pool->arena, ExternalFuncDecl);
    370   if (!f) perr(p, "out of memory in external_func_remember");
    371   f->name = name;
    372   f->entry = entry;
    373   f->next = p->external_funcs;
    374   p->external_funcs = f;
    375 }
    376 
    377 static int is_ordinary_decl_kind(SymEntryKind k) {
    378   return k == SEK_LOCAL || k == SEK_GLOBAL || k == SEK_FUNC ||
    379          k == SEK_TYPEDEF || k == SEK_ENUM_CST;
    380 }
    381 
    382 static void reject_same_scope_redefinition(Parser* p, Sym name,
    383                                            SymEntryKind kind,
    384                                            const Type* type) {
    385   SymEntry* e = scope_lookup_current(p, name);
    386   if (!e || !is_ordinary_decl_kind((SymEntryKind)e->kind)) return;
    387   if (e->kind == SEK_TYPEDEF && kind == SEK_TYPEDEF &&
    388       type_compatible(e->type, type)) {
    389     return;
    390   }
    391   perr(p, "redefinition of identifier");
    392 }
    393 
    394 TagEntry* tag_define(Parser* p, Sym name, TagDeclKind kind, Type* type,
    395                      int complete) {
    396   TagEntry* e = arena_new(p->pool->arena, TagEntry);
    397   if (!e) perr(p, "out of memory in tag_define");
    398   memset(e, 0, sizeof *e);
    399   e->name = name;
    400   e->kind = (u8)kind;
    401   e->complete = (u8)(complete ? 1 : 0);
    402   e->type = type;
    403   e->next = p->scope->tags;
    404   p->scope->tags = e;
    405   return e;
    406 }
    407 
    408 TagEntry* tag_lookup(Parser* p, Sym name) {
    409   Scope* s;
    410   for (s = p->scope; s; s = s->parent) {
    411     TagEntry* e;
    412     for (e = s->tags; e; e = e->next) {
    413       if (e->name == name) return e;
    414     }
    415   }
    416   return NULL;
    417 }
    418 
    419 TagEntry* tag_lookup_local(Parser* p, Sym name) {
    420   TagEntry* e;
    421   for (e = p->scope->tags; e; e = e->next) {
    422     if (e->name == name) return e;
    423   }
    424   return NULL;
    425 }
    426 
    427 /* ============================================================
    428  * Type helpers
    429  * ============================================================ */
    430 
    431 static const Type* ty_size_t(Parser* p) {
    432   return c_abi_size_type(p->abi, p->pool);
    433 }
    434 
    435 /* ============================================================
    436  * Local-variable slot allocation
    437  * ============================================================ */
    438 
    439 FrameSlot make_local_aligned(Parser* p, Sym name, const Type* type, SrcLoc loc,
    440                              u32 align_override) {
    441   FrameSlotDesc fsd;
    442   FrameSlot s;
    443   SymEntry* e;
    444   u32 nat = c_abi_alignof(p->abi, type);
    445   memset(&fsd, 0, sizeof fsd);
    446   fsd.type = type;
    447   fsd.name = name;
    448   fsd.loc = loc;
    449   fsd.size = c_abi_sizeof(p->abi, type);
    450   fsd.align = (align_override > nat) ? align_override : nat;
    451   fsd.kind = FS_LOCAL;
    452   fsd.flags = FSF_NONE;
    453   s = pcg_local(p, &fsd);
    454   reject_same_scope_redefinition(p, name, SEK_LOCAL, type);
    455   e = scope_define(p, name, SEK_LOCAL, type);
    456   e->v.slot = s;
    457   sym_set_decl(e, DECL_NONE, DS_AUTO, DL_NONE, DF_NONE, DSTATE_DEFINED);
    458   return s;
    459 }
    460 
    461 FrameSlot make_local(Parser* p, Sym name, const Type* type, SrcLoc loc) {
    462   return make_local_aligned(p, name, type, loc, 0);
    463 }
    464 
    465 static FrameSlot make_vla_size_slot(Parser* p) {
    466   FrameSlotDesc fsd;
    467   memset(&fsd, 0, sizeof fsd);
    468   fsd.type = ty_size_t(p);
    469   fsd.size = c_abi_sizeof(p->abi, fsd.type);
    470   fsd.align = c_abi_alignof(p->abi, fsd.type);
    471   fsd.kind = FS_LOCAL;
    472   return pcg_local(p, &fsd);
    473 }
    474 
    475 static void store_top_to_size_slot(Parser* p, FrameSlot slot) {
    476   pcg_push_local_typed(p, slot, ty_size_t(p));
    477   pcg_swap(p);
    478   coerce_top_to_lvalue(p);
    479   pcg_store(p);
    480   pcg_drop(p);
    481 }
    482 
    483 static void reset_vla_pending(Parser* p) {
    484   p->vla_pending = 0;
    485   p->vla_pending_count_slot = FRAME_SLOT_NONE;
    486   p->vla_pending_count_len = 0;
    487 }
    488 
    489 static VLABound* add_vla_bound(Parser* p, VLABound* head, const Type* array_ty,
    490                                FrameSlot byte_slot, FrameSlot count_slot) {
    491   VLABound* b = arena_znew(p->pool->arena, VLABound);
    492   b->array_ty = array_ty;
    493   b->byte_slot = byte_slot;
    494   b->count_slot = count_slot;
    495   b->next = head;
    496   return b;
    497 }
    498 
    499 static int build_vla_size(Parser* p, const Type* ty, u32* count_idx,
    500                           VLABound** bounds, FrameSlot* out_slot,
    501                           u32* out_static_size, SrcLoc loc) {
    502   if (!ty || ty->kind != TY_ARRAY) {
    503     *out_static_size = c_abi_sizeof(p->abi, ty);
    504     *out_slot = FRAME_SLOT_NONE;
    505     return 0;
    506   }
    507 
    508   FrameSlot count_slot = FRAME_SLOT_NONE;
    509   int count_dynamic = 0;
    510   if (ty->arr.incomplete) {
    511     if (*count_idx >= p->vla_pending_count_len) {
    512       perr(p, "missing VLA bound for declarator");
    513     }
    514     count_slot = p->vla_pending_count_slots[(*count_idx)++];
    515     count_dynamic = 1;
    516   }
    517 
    518   FrameSlot elem_slot = FRAME_SLOT_NONE;
    519   u32 elem_static_size = 0;
    520   int elem_dynamic = build_vla_size(p, ty->arr.elem, count_idx, bounds,
    521                                     &elem_slot, &elem_static_size, loc);
    522 
    523   if (count_dynamic || elem_dynamic) {
    524     FrameSlot byte_slot = make_vla_size_slot(p);
    525     pcg_set_loc(p, loc);
    526     if (count_dynamic) {
    527       pcg_push_local_typed(p, count_slot, ty_size_t(p));
    528       pcg_load(p);
    529     } else {
    530       pcg_push_int(p, (i64)ty->arr.count, ty_size_t(p));
    531     }
    532     if (elem_dynamic) {
    533       pcg_push_local_typed(p, elem_slot, ty_size_t(p));
    534       pcg_load(p);
    535     } else {
    536       pcg_push_int(p, (i64)elem_static_size, ty_size_t(p));
    537     }
    538     pcg_binop(p, BO_IMUL);
    539     store_top_to_size_slot(p, byte_slot);
    540     *bounds = add_vla_bound(p, *bounds, ty, byte_slot, count_slot);
    541     *out_slot = byte_slot;
    542     *out_static_size = 0;
    543     return 1;
    544   }
    545 
    546   *out_slot = FRAME_SLOT_NONE;
    547   *out_static_size = ty->arr.count * elem_static_size;
    548   return 0;
    549 }
    550 
    551 static FrameSlot finish_vla_layout(Parser* p, const Type* ty, SrcLoc loc,
    552                                    VLABound** bounds_out) {
    553   FrameSlot byte_slot = FRAME_SLOT_NONE;
    554   u32 static_size = 0;
    555   u32 count_idx = 0;
    556   *bounds_out = NULL;
    557   if (!build_vla_size(p, ty, &count_idx, bounds_out, &byte_slot, &static_size,
    558                       loc)) {
    559     perr(p, "VLA declarator did not produce a runtime size");
    560   }
    561   if (count_idx != p->vla_pending_count_len) {
    562     perr(p, "unused VLA bound in declarator");
    563   }
    564   reset_vla_pending(p);
    565   return byte_slot;
    566 }
    567 
    568 static int type_array_depth(const Type* ty) {
    569   int n = 0;
    570   while (ty && ty->kind == TY_ARRAY) {
    571     ++n;
    572     ty = ty->arr.elem;
    573   }
    574   return n;
    575 }
    576 
    577 static void eval_param_vla_count(Parser* p, const ParamVLABoundExpr* expr,
    578                                  FrameSlot slot) {
    579   Tok save_cur = p->cur;
    580   Tok save_next = p->next;
    581   int save_has_next = p->has_next;
    582   Tok* save_replay = p->replay;
    583   u32 save_cap = p->replay_cap;
    584   u32 save_len = p->replay_len;
    585   u32 save_pos = p->replay_pos;
    586   u8 save_active = p->replay_active;
    587   Tok* replay;
    588 
    589   if (!expr->has_expr || expr->ntoks == 0) {
    590     perr(p, "missing VLA parameter bound");
    591   }
    592   replay = arena_array(p->pool->arena, Tok, expr->ntoks + 1u);
    593   memcpy(replay, expr->toks, sizeof(Tok) * expr->ntoks);
    594   memset(&replay[expr->ntoks], 0, sizeof(Tok));
    595   replay[expr->ntoks].kind = TOK_EOF;
    596 
    597   p->cur = replay[0];
    598   p->next.kind = TOK_EOF;
    599   p->has_next = 0;
    600   p->replay = replay;
    601   p->replay_cap = expr->ntoks + 1u;
    602   p->replay_len = expr->ntoks + 1u;
    603   p->replay_pos = 1;
    604   p->replay_active = 1;
    605 
    606   parse_assign_expr(p);
    607   to_rvalue(p);
    608   if (p->cur.kind != TOK_EOF) {
    609     perr(p, "unexpected token in VLA parameter bound");
    610   }
    611   store_top_to_size_slot(p, slot);
    612 
    613   p->cur = save_cur;
    614   p->next = save_next;
    615   p->has_next = save_has_next;
    616   p->replay = save_replay;
    617   p->replay_cap = save_cap;
    618   p->replay_len = save_len;
    619   p->replay_pos = save_pos;
    620   p->replay_active = save_active;
    621 }
    622 
    623 static VLABound* build_param_vla_bounds(Parser* p, const ParamInfo* info,
    624                                         SrcLoc loc) {
    625   const Type* root = info->declared_type;
    626   u32 dim_skip = 0;
    627   u32 need;
    628   VLABound* bounds = NULL;
    629 
    630   if (!root || info->vla_bound_len == 0) return NULL;
    631   if (root->kind == TY_ARRAY) {
    632     dim_skip = 1;
    633     root = root->arr.elem;
    634   } else if (root->kind == TY_PTR) {
    635     root = root->ptr.pointee;
    636   }
    637   need = (u32)type_array_depth(root);
    638   if (need == 0) return NULL;
    639   if (dim_skip + need > info->vla_bound_len) {
    640     perr(p, "missing VLA parameter bound");
    641   }
    642 
    643   reset_vla_pending(p);
    644   for (u32 i = 0; i < need; ++i) {
    645     const ParamVLABoundExpr* expr = &info->vla_bounds[dim_skip + i];
    646     FrameSlot slot = make_vla_size_slot(p);
    647     eval_param_vla_count(p, expr, slot);
    648     p->vla_pending = 1;
    649     p->vla_pending_count_slots[p->vla_pending_count_len++] = slot;
    650   }
    651   (void)finish_vla_layout(p, root, loc, &bounds);
    652   return bounds;
    653 }
    654 
    655 /* ============================================================
    656  * Static-local symbol naming
    657  * ============================================================ */
    658 
    659 /* Mint a unique linker name for a static local: `<orig>.<counter>`. */
    660 Sym mint_static_local_sym(Parser* p, Sym orig) {
    661   KitSlice orig_sl = kit_sym_str(p->pool->c, orig);
    662   size_t olen = orig_sl.len;
    663   const char* on = orig_sl.s;
    664   char buf[128];
    665   u32 wlen = 0;
    666   u32 id = ++p->static_local_counter;
    667   if (olen > 100) olen = 100;
    668   for (size_t i = 0; i < olen && wlen < sizeof buf - 1; ++i) {
    669     buf[wlen++] = on[i];
    670   }
    671   if (wlen < sizeof buf - 1) buf[wlen++] = '.';
    672   {
    673     char digits[12];
    674     int dn = 0;
    675     if (id == 0) digits[dn++] = '0';
    676     while (id) {
    677       digits[dn++] = (char)('0' + (id % 10));
    678       id /= 10;
    679     }
    680     while (dn && wlen < sizeof buf - 1) buf[wlen++] = digits[--dn];
    681   }
    682   return kit_sym_intern(p->pool->c, (KitSlice){.s = buf, .len = wlen});
    683 }
    684 
    685 /* ============================================================
    686  * Declarations
    687  * ============================================================ */
    688 
    689 /* Parse a single init-declarator after the decl-specs have been consumed. */
    690 static SymEntry* declare_function(Parser* p, Sym fname, const Type* fn_ty,
    691                                   const DeclSpecs* specs, SrcLoc fname_loc,
    692                                   const Attr* dattrs, Sym asm_label,
    693                                   ObjSecId* out_section_id, u32* out_decl_flags,
    694                                   Sym* out_alias_target);
    695 
    696 static void parse_init_declarator(Parser* p, const DeclSpecs* specs) {
    697   SrcLoc loc;
    698   Sym name;
    699   DeclaratorInfo dinfo;
    700   const Type* var_ty = parse_declarator_full_info(
    701       p, specs->type, /*allow_abstract=*/0, &name, &loc, NULL, &dinfo);
    702   if ((specs->flags & DF_THREAD) && specs->storage != DS_STATIC &&
    703       specs->storage != DS_EXTERN) {
    704     perr(p, "block-scope _Thread_local requires static or extern");
    705   }
    706   validate_decl_type_constraints(p, specs, var_ty,
    707                                  var_ty && var_ty->kind == TY_FUNC,
    708                                  /*is_member=*/0);
    709 
    710   if (specs->storage == DS_TYPEDEF) {
    711     if (is_punct(&p->cur, '=')) {
    712       perr(p, "typedef declarator cannot have initializer");
    713     }
    714     {
    715       reject_same_scope_redefinition(p, name, SEK_TYPEDEF, var_ty);
    716       SymEntry* e = scope_define(p, name, SEK_TYPEDEF, var_ty);
    717       sym_set_decl(e, DECL_NONE, DS_TYPEDEF, DL_NONE, specs->flags,
    718                    DSTATE_DECLARED);
    719       if (p->vla_pending && var_ty && var_ty->kind == TY_ARRAY) {
    720         VLABound* bounds = NULL;
    721         FrameSlot byte_slot = finish_vla_layout(p, var_ty, loc, &bounds);
    722         e->vla_byte_slot = byte_slot;
    723         e->vla_bounds = bounds;
    724       } else if (specs->vla_byte_slot != FRAME_SLOT_NONE) {
    725         e->vla_byte_slot = specs->vla_byte_slot;
    726         e->vla_bounds = specs->vla_bounds;
    727       }
    728     }
    729     (void)loc;
    730     return;
    731   }
    732 
    733   if (var_ty && var_ty->kind == TY_FUNC) {
    734     ObjSecId section_id;
    735     u32 decl_flags;
    736     Sym alias_target;
    737     if ((specs->storage == DS_AUTO && specs->storage_explicit) ||
    738         specs->storage == DS_REGISTER || specs->storage == DS_STATIC) {
    739       perr(p,
    740            "invalid storage-class specifier for block-scope function "
    741            "declaration");
    742     }
    743     if (is_punct(&p->cur, '=')) {
    744       perr(p, "function declarator cannot have initializer");
    745     }
    746     (void)declare_function(p, name, var_ty, specs, loc, NULL, dinfo.asm_label,
    747                            &section_id, &decl_flags, &alias_target);
    748     (void)section_id;
    749     (void)decl_flags;
    750     (void)alias_target;
    751     return;
    752   }
    753 
    754   if (specs->storage == DS_STATIC) {
    755     Decl decl_in;
    756     DeclId did;
    757     ObjSymId sym;
    758     SymEntry* e;
    759     Sym lname = mint_static_local_sym(p, name);
    760     int has_init;
    761     u32 align_eff;
    762     has_init = accept_punct(p, '=');
    763     /* Complete `T x[] = {...}` before declaring the symbol so the registered
    764      * (CG) type carries the real element count. Backends such as the C target
    765      * derive function-local label-table sizes from the symbol's type, so the
    766      * declared type must already be the completed array. */
    767     if (has_init && var_ty && var_ty->kind == TY_ARRAY &&
    768         var_ty->arr.incomplete) {
    769       var_ty = complete_incomplete_array(p, var_ty);
    770     }
    771     memset(&decl_in, 0, sizeof decl_in);
    772     decl_in.name = lname;
    773     decl_in.asm_name = dinfo.asm_label;
    774     decl_in.type = var_ty;
    775     decl_in.loc = loc;
    776     decl_in.storage = DS_STATIC;
    777     decl_in.linkage = DL_INTERNAL;
    778     decl_in.visibility = SV_DEFAULT;
    779     decl_in.flags = DF_STATIC_LOCAL | (specs->flags & DF_THREAD);
    780     attr_list_to_decl(p->c, p->decls, specs->attrs, &decl_in);
    781     did = decl_declare(p->decls, &decl_in);
    782     sym = decl_obj_sym(p->decls, did);
    783     reject_same_scope_redefinition(p, name, SEK_GLOBAL, var_ty);
    784     e = scope_define(p, name, SEK_GLOBAL, var_ty);
    785     e->v.sym = sym;
    786     sym_set_decl(e, did, DS_STATIC, DL_NONE, decl_in.flags, DSTATE_DEFINED);
    787     align_eff = (specs->align > decl_in.align) ? specs->align : decl_in.align;
    788     define_static_object(p, sym, decl_in.section_id, var_ty, specs->quals,
    789                          has_init, loc, align_eff);
    790     return;
    791   }
    792 
    793   if (specs->storage == DS_EXTERN) {
    794     Decl decl_in;
    795     DeclId did;
    796     ObjSymId sym;
    797     SymEntry* e;
    798     SymEntry* prior;
    799     if (accept_punct(p, '=')) {
    800       perr(p, "block-scope extern with initializer not supported");
    801     }
    802     prior = scope_lookup(p, name);
    803     if (prior && prior->kind == SEK_GLOBAL) {
    804       SymEntry* cur = scope_lookup_current(p, name);
    805       const Type* composite = NULL;
    806       CSemCheck chk =
    807           c_sem_check_redeclaration(p->pool, prior->type, var_ty, &composite);
    808       if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message)));
    809       if (cur && cur->kind != SEK_GLOBAL) {
    810         perr(p, "redefinition of identifier");
    811       }
    812       if (cur) return;
    813       e = scope_define(p, name, SEK_GLOBAL, var_ty);
    814       e->v.sym = prior->v.sym;
    815       sym_set_decl(e, prior->decl_id, DS_EXTERN, (DeclLinkage)prior->linkage,
    816                    prior->decl_flags, (DeclState)prior->decl_state);
    817       return;
    818     }
    819     memset(&decl_in, 0, sizeof decl_in);
    820     decl_in.name = name;
    821     decl_in.asm_name = dinfo.asm_label;
    822     decl_in.type = var_ty;
    823     decl_in.loc = loc;
    824     decl_in.storage = DS_EXTERN;
    825     decl_in.linkage = DL_EXTERNAL;
    826     decl_in.visibility = p->default_visibility;
    827     decl_in.flags = specs->flags & DF_THREAD;
    828     attr_list_to_decl(p->c, p->decls, specs->attrs, &decl_in);
    829     did = decl_declare(p->decls, &decl_in);
    830     sym = decl_obj_sym(p->decls, did);
    831     reject_same_scope_redefinition(p, name, SEK_GLOBAL, var_ty);
    832     e = scope_define(p, name, SEK_GLOBAL, var_ty);
    833     e->v.sym = sym;
    834     sym_set_decl(e, did, DS_EXTERN, DL_EXTERNAL, decl_in.flags,
    835                  DSTATE_DECLARED);
    836     return;
    837   }
    838 
    839   if (var_ty && var_ty->kind == TY_ARRAY &&
    840       (p->vla_pending || specs->vla_byte_slot != FRAME_SLOT_NONE)) {
    841     const Type* elem_ty = var_ty->arr.elem;
    842     const Type* ptr_ty = type_ptr(p->pool, elem_ty);
    843     FrameSlot byte_slot;
    844     FrameSlot ptr_slot;
    845     SymEntry* sym_entry;
    846     VLABound* bounds = NULL;
    847     if (p->vla_pending) {
    848       byte_slot = finish_vla_layout(p, var_ty, loc, &bounds);
    849       ++p->vla_mark;
    850     } else {
    851       byte_slot = specs->vla_byte_slot;
    852       bounds = specs->vla_bounds;
    853     }
    854     ptr_slot = make_local(p, name, ptr_ty, loc);
    855     pcg_set_loc(p, loc);
    856     pcg_push_local_typed(p, byte_slot, ty_size_t(p));
    857     pcg_load(p);
    858     pcg_alloca(p);
    859     pcg_push_local_typed(p, ptr_slot, ptr_ty);
    860     pcg_swap(p);
    861     pcg_store(p);
    862     pcg_drop(p);
    863     sym_entry = scope_lookup(p, name);
    864     if (sym_entry && sym_entry->kind == SEK_LOCAL) {
    865       sym_entry->vla_byte_slot = byte_slot;
    866       sym_entry->vla_bounds = bounds;
    867     }
    868     if (accept_punct(p, '=')) {
    869       perr(p, "VLA initializers are not allowed (§6.7.9 ¶3)");
    870     }
    871     return;
    872   }
    873   /* Non-VLA local. */
    874   {
    875     int has_init = is_punct(&p->cur, '=');
    876     FrameSlot s;
    877     if (has_init && var_ty && var_ty->kind == TY_ARRAY &&
    878         var_ty->arr.incomplete) {
    879       advance(p); /* '=' */
    880       var_ty = complete_incomplete_array(p, var_ty);
    881       s = make_local_aligned(p, name, var_ty, loc, specs->align);
    882       if (specs->storage == DS_REGISTER) {
    883         SymEntry* e = scope_lookup_current(p, name);
    884         if (e && e->kind == SEK_LOCAL) {
    885           e->storage = DS_REGISTER;
    886           e->reg_asm_name = dinfo.asm_label;
    887         }
    888       }
    889       pcg_set_loc(p, loc);
    890       init_at(p, s, var_ty, 0, var_ty);
    891       return;
    892     }
    893     s = make_local_aligned(p, name, var_ty, loc, specs->align);
    894     if (specs->storage == DS_REGISTER) {
    895       SymEntry* e = scope_lookup_current(p, name);
    896       if (e && e->kind == SEK_LOCAL) {
    897         e->storage = DS_REGISTER;
    898         e->reg_asm_name = dinfo.asm_label;
    899       }
    900     }
    901     if (accept_punct(p, '=')) {
    902       pcg_set_loc(p, loc);
    903       if ((var_ty->kind == TY_STRUCT || var_ty->kind == TY_UNION) &&
    904           !is_punct(&p->cur, '{')) {
    905         parse_assign_expr(p);
    906         emit_struct_copy_into_slot(p, s, var_ty, 0, var_ty);
    907       } else if (var_ty->kind == TY_ARRAY || var_ty->kind == TY_STRUCT ||
    908                  var_ty->kind == TY_UNION) {
    909         init_at(p, s, var_ty, 0, var_ty);
    910       } else {
    911         pcg_push_local_typed(p, s, var_ty);
    912         parse_assign_expr(p);
    913         to_rvalue(p);
    914         {
    915           const Type* rhs = pcg_top_type(p);
    916           CSemCheck chk =
    917               c_sem_check_assignment(p->pool, var_ty, rhs, C_SEM_ASSIGN_INIT);
    918           if (!chk.ok)
    919             perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message)));
    920         }
    921         coerce_top_to_lvalue(p);
    922         pcg_store(p);
    923         pcg_drop(p);
    924       }
    925     }
    926   }
    927 }
    928 
    929 void parse_local_decl(Parser* p, const DeclSpecs* specs) {
    930   if (accept_punct(p, ';')) return;
    931   parse_init_declarator(p, specs);
    932   while (accept_punct(p, ',')) {
    933     parse_init_declarator(p, specs);
    934   }
    935   expect_punct(p, ';', "';' after declaration");
    936 }
    937 
    938 /* ============================================================
    939  * External (top-level) declarations
    940  * ============================================================ */
    941 
    942 void parse_param_list(Parser* p, ParamInfo** infos_out, u16* nparams_out,
    943                       u8* variadic_out) {
    944   ParamInfo* infos;
    945   u32 cap = 4;
    946   u32 n = 0;
    947   *variadic_out = 0;
    948   *infos_out = NULL;
    949   *nparams_out = 0;
    950 
    951   if (is_punct(&p->cur, ')')) {
    952     return;
    953   }
    954   if (is_kw(p, &p->cur, KW_VOID)) {
    955     Tok n2 = peek1(p);
    956     if (is_punct(&n2, ')')) {
    957       advance(p); /* `void` */
    958       return;     /* `(void)` */
    959     }
    960   }
    961 
    962   infos = (ParamInfo*)arena_array(p->pool->arena, ParamInfo, cap);
    963   for (;;) {
    964     DeclSpecs specs;
    965     Sym pname = 0;
    966     SrcLoc ploc = {0, 0, 0};
    967     const Type* pty;
    968     if (accept_punct(p, P_ELLIPSIS)) {
    969       if (n == 0) perr(p, "ellipsis requires a preceding parameter");
    970       *variadic_out = 1;
    971       break;
    972     }
    973     if (!parse_decl_specs(p, &specs)) {
    974       perr(p, "expected parameter type");
    975     }
    976     if ((specs.storage_explicit && specs.storage != DS_REGISTER) ||
    977         specs.storage == DS_TYPEDEF || (specs.flags & DF_THREAD)) {
    978       perr(p, "invalid storage-class specifier in parameter declaration");
    979     }
    980     p->param_vla_bound_len = 0;
    981     p->in_param_decl++;
    982     pty = parse_declarator_full(p, specs.type, /*allow_abstract=*/1, &pname,
    983                                 &ploc);
    984     p->in_param_decl--;
    985     const Type* declared_pty = pty;
    986     if (pty && pty->kind == TY_ARRAY) {
    987       pty = type_ptr(p->pool, pty->arr.elem);
    988     } else if (pty && pty->kind == TY_FUNC) {
    989       pty = type_ptr(p->pool, pty);
    990     }
    991     if (pty && pty->kind == TY_VOID) {
    992       perr(p, "'void' must be the only parameter");
    993     }
    994     validate_decl_type_constraints(p, &specs, pty, /*is_function=*/0,
    995                                    /*is_member=*/0);
    996     if (pname) {
    997       for (u32 pi = 0; pi < n; ++pi) {
    998         if (infos[pi].name == pname) perr(p, "redefinition of parameter");
    999       }
   1000     }
   1001     if (n == cap) {
   1002       cap *= 2;
   1003       ParamInfo* nbuf = (ParamInfo*)arena_array(p->pool->arena, ParamInfo, cap);
   1004       memcpy(nbuf, infos, sizeof(ParamInfo) * n);
   1005       infos = nbuf;
   1006     }
   1007     infos[n].name = pname;
   1008     infos[n].type = pty;
   1009     infos[n].declared_type = declared_pty;
   1010     infos[n].loc = ploc;
   1011     infos[n].vla_bounds = NULL;
   1012     infos[n].vla_bound_len = p->param_vla_bound_len;
   1013     if (p->param_vla_bound_len) {
   1014       ParamVLABoundExpr* bounds = arena_array(p->pool->arena, ParamVLABoundExpr,
   1015                                               p->param_vla_bound_len);
   1016       memcpy(bounds, p->param_vla_bounds,
   1017              sizeof(ParamVLABoundExpr) * p->param_vla_bound_len);
   1018       infos[n].vla_bounds = bounds;
   1019     }
   1020     ++n;
   1021     if (!accept_punct(p, ',')) break;
   1022   }
   1023   *infos_out = infos;
   1024   *nparams_out = (u16)n;
   1025 }
   1026 
   1027 static SymEntry* declare_function(Parser* p, Sym fname, const Type* fn_ty,
   1028                                   const DeclSpecs* specs, SrcLoc fname_loc,
   1029                                   const Attr* dattrs, Sym asm_label,
   1030                                   ObjSecId* out_section_id, u32* out_decl_flags,
   1031                                   Sym* out_alias_target) {
   1032   SymEntry* visible;
   1033   if (out_section_id) *out_section_id = OBJ_SEC_NONE;
   1034   if (out_decl_flags) *out_decl_flags = 0;
   1035   if (out_alias_target) *out_alias_target = 0;
   1036   SymEntry* existing = scope_lookup_current(p, fname);
   1037   if (existing && existing->kind != SEK_FUNC) {
   1038     perr(p, "redefinition of identifier");
   1039   }
   1040   if (existing && existing->kind == SEK_FUNC) {
   1041     const Type* composite = NULL;
   1042     CSemCheck chk =
   1043         c_sem_check_redeclaration(p->pool, existing->type, fn_ty, &composite);
   1044     if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message)));
   1045     if (specs->storage == DS_STATIC && existing->linkage == DL_EXTERNAL) {
   1046       perr(p, "static declaration follows non-static declaration");
   1047     }
   1048     existing->type = composite ? composite : existing->type;
   1049     Decl tmp;
   1050     memset(&tmp, 0, sizeof tmp);
   1051     attr_list_to_decl(p->c, p->decls, specs->attrs, &tmp);
   1052     attr_list_to_decl(p->c, p->decls, dattrs, &tmp);
   1053     if (out_section_id) *out_section_id = tmp.section_id;
   1054     if (out_decl_flags) *out_decl_flags = tmp.flags;
   1055     if (out_alias_target) *out_alias_target = tmp.alias_target;
   1056     decl_apply_redecl_flags(p->decls, existing->decl_id, tmp.flags);
   1057     external_func_remember(p, fname, existing);
   1058     return existing;
   1059   }
   1060   visible = scope_lookup(p, fname);
   1061   if (!existing && visible && visible->kind == SEK_FUNC) {
   1062     existing = visible;
   1063   }
   1064   if (!existing) {
   1065     existing = external_func_lookup(p, fname);
   1066   }
   1067   if (existing) {
   1068     const Type* composite = NULL;
   1069     CSemCheck chk =
   1070         c_sem_check_redeclaration(p->pool, existing->type, fn_ty, &composite);
   1071     if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message)));
   1072     if (specs->storage == DS_STATIC && existing->linkage == DL_EXTERNAL) {
   1073       perr(p, "static declaration follows non-static declaration");
   1074     }
   1075     if (scope_lookup_current(p, fname) != existing) {
   1076       SymEntry* e = scope_define(p, fname, SEK_FUNC,
   1077                                  composite ? composite : existing->type);
   1078       e->v.sym = existing->v.sym;
   1079       sym_set_decl(e, existing->decl_id, (DeclStorage)existing->storage,
   1080                    (DeclLinkage)existing->linkage, existing->decl_flags,
   1081                    (DeclState)existing->decl_state);
   1082       existing = e;
   1083     } else if (composite) {
   1084       existing->type = composite;
   1085     }
   1086     {
   1087       Decl tmp;
   1088       memset(&tmp, 0, sizeof tmp);
   1089       attr_list_to_decl(p->c, p->decls, specs->attrs, &tmp);
   1090       attr_list_to_decl(p->c, p->decls, dattrs, &tmp);
   1091       if (out_section_id) *out_section_id = tmp.section_id;
   1092       if (out_decl_flags) *out_decl_flags = tmp.flags;
   1093       if (out_alias_target) *out_alias_target = tmp.alias_target;
   1094       decl_apply_redecl_flags(p->decls, existing->decl_id, tmp.flags);
   1095     }
   1096     external_func_remember(p, fname, existing);
   1097     return existing;
   1098   }
   1099   {
   1100     Decl decl_in;
   1101     DeclId did;
   1102     ObjSymId fsym;
   1103     SymEntry* e;
   1104     memset(&decl_in, 0, sizeof decl_in);
   1105     decl_in.name = fname;
   1106     decl_in.asm_name = asm_label;
   1107     decl_in.type = fn_ty;
   1108     decl_in.loc = fname_loc;
   1109     decl_in.storage =
   1110         (specs->storage == DS_STATIC ||
   1111          ((specs->flags & DF_INLINE) && specs->storage != DS_EXTERN))
   1112             ? DS_STATIC
   1113             : DS_EXTERN;
   1114     decl_in.linkage =
   1115         (decl_in.storage == DS_STATIC) ? DL_INTERNAL : DL_EXTERNAL;
   1116     decl_in.visibility =
   1117         decl_in.linkage == DL_EXTERNAL ? p->default_visibility : SV_DEFAULT;
   1118     attr_list_to_decl(p->c, p->decls, specs->attrs, &decl_in);
   1119     attr_list_to_decl(p->c, p->decls, dattrs, &decl_in);
   1120     did = decl_declare(p->decls, &decl_in);
   1121     fsym = decl_obj_sym(p->decls, did);
   1122     e = scope_define(p, fname, SEK_FUNC, fn_ty);
   1123     e->v.sym = fsym;
   1124     sym_set_decl(e, did, decl_in.storage, decl_in.linkage, decl_in.flags,
   1125                  DSTATE_DECLARED);
   1126     external_func_remember(p, fname, e);
   1127     if (out_section_id) *out_section_id = decl_in.section_id;
   1128     if (out_decl_flags) *out_decl_flags = decl_in.flags;
   1129     if (out_alias_target) *out_alias_target = decl_in.alias_target;
   1130     return e;
   1131   }
   1132 }
   1133 
   1134 static void parse_function_body(Parser* p, ObjSymId fsym, const Type* fn_ty,
   1135                                 const ABIFuncInfo* abi, const ParamInfo* infos,
   1136                                 u16 nparams, SrcLoc fname_loc,
   1137                                 ObjSecId section_id, u32 decl_flags) {
   1138   CGFuncDesc fd;
   1139   CGParamDesc* pds = NULL;
   1140 
   1141   memset(&fd, 0, sizeof fd);
   1142   fd.sym = fsym;
   1143   fd.text_section_id = section_id;
   1144   fd.group_id = OBJ_GROUP_NONE;
   1145   fd.fn_type = fn_ty;
   1146   fd.abi = abi;
   1147   fd.params = NULL;
   1148   fd.nparams = nparams;
   1149   fd.loc = fname_loc;
   1150   if (decl_flags & DF_NORETURN) fd.flags |= CGFD_NORETURN;
   1151   if (decl_flags & DF_NOINLINE)
   1152     fd.inline_policy = KIT_CG_INLINE_NEVER;
   1153   else if (decl_flags & DF_ALWAYS_INLINE)
   1154     fd.inline_policy = KIT_CG_INLINE_ALWAYS;
   1155   else if (decl_flags & DF_INLINE)
   1156     fd.inline_policy = KIT_CG_INLINE_HINT;
   1157 
   1158   if (nparams) {
   1159     pds = (CGParamDesc*)arena_array(p->pool->arena, CGParamDesc, nparams);
   1160     memset(pds, 0, sizeof(CGParamDesc) * nparams);
   1161     for (u16 i = 0; i < nparams; ++i) {
   1162       pds[i].index = i;
   1163       pds[i].name = infos[i].name;
   1164       pds[i].type = infos[i].type;
   1165       pds[i].slot = FRAME_SLOT_NONE;
   1166       pds[i].abi = &abi->params[i];
   1167       pds[i].incoming = NULL;
   1168       pds[i].nincoming = 0;
   1169       pds[i].loc = infos[i].loc;
   1170     }
   1171     fd.params = pds;
   1172   }
   1173 
   1174   scope_push(p); /* parameter scope */
   1175   GotoLabel* saved_goto_labels = p->goto_labels;
   1176   SwitchCtx* saved_switch = p->cur_switch;
   1177   u8 saved_computed_goto = p->computed_goto_emitted;
   1178   p->goto_labels = NULL;
   1179   p->cur_switch = NULL;
   1180   p->computed_goto_emitted = 0;
   1181   pcg_set_loc(p, fname_loc);
   1182   pcg_func_begin(p, &fd);
   1183 
   1184   for (u16 i = 0; i < nparams; ++i) {
   1185     FrameSlotDesc fsd;
   1186     FrameSlot s;
   1187     SymEntry* e;
   1188     memset(&fsd, 0, sizeof fsd);
   1189     fsd.type = infos[i].type;
   1190     fsd.name = infos[i].name;
   1191     fsd.loc = infos[i].loc;
   1192     fsd.size = c_abi_sizeof(p->abi, infos[i].type);
   1193     fsd.align = c_abi_alignof(p->abi, infos[i].type);
   1194     fsd.kind = FS_PARAM;
   1195     fsd.flags = FSF_NONE;
   1196     s = pcg_param_slot(p, i, &fsd);
   1197     pds[i].slot = s;
   1198     if (infos[i].name) {
   1199       reject_same_scope_redefinition(p, infos[i].name, SEK_LOCAL,
   1200                                      infos[i].type);
   1201       e = scope_define(p, infos[i].name, SEK_LOCAL, infos[i].type);
   1202       e->v.slot = s;
   1203       sym_set_decl(e, DECL_NONE, DS_AUTO, DL_NONE, DF_NONE, DSTATE_DEFINED);
   1204       e->vla_bounds = build_param_vla_bounds(p, &infos[i], infos[i].loc);
   1205     }
   1206   }
   1207 
   1208   parse_compound_stmt(p);
   1209   if (fn_ty->fn.ret && fn_ty->fn.ret->kind != TY_VOID &&
   1210       fn_ty->fn.ret->kind != TY_STRUCT && fn_ty->fn.ret->kind != TY_UNION) {
   1211     pcg_push_int(p, 0, fn_ty->fn.ret);
   1212     pcg_ret(p, 1);
   1213   } else {
   1214     pcg_ret(p, 0);
   1215   }
   1216   for (GotoLabel* gl = p->goto_labels; gl; gl = gl->next) {
   1217     if (!gl->placed) {
   1218       compiler_panic(p->c, gl->first_use, "goto to undefined label");
   1219     }
   1220   }
   1221   p->goto_labels = saved_goto_labels;
   1222   p->cur_switch = saved_switch;
   1223   p->computed_goto_emitted = saved_computed_goto;
   1224   pcg_func_end(p);
   1225   scope_pop(p);
   1226 }
   1227 
   1228 /* Parse one external declaration. */
   1229 static void parse_external_decl(Parser* p) {
   1230   DeclSpecs specs;
   1231   Sym name;
   1232   SrcLoc loc;
   1233   const Type* base_ty;
   1234   Attr* dattrs = NULL;
   1235   DeclaratorInfo dinfo;
   1236 
   1237   if (!parse_decl_specs(p, &specs)) {
   1238     perr(p, "expected declaration");
   1239   }
   1240   if (specs.storage == DS_AUTO && specs.storage_explicit) {
   1241     perr(p, "invalid storage-class specifier at file scope");
   1242   }
   1243 
   1244   if (accept_punct(p, ';')) return;
   1245 
   1246   if (specs.storage == DS_TYPEDEF) {
   1247     for (;;) {
   1248       Sym tname = 0;
   1249       SrcLoc tloc = {0, 0, 0};
   1250       const Type* tty =
   1251           parse_declarator_full(p, specs.type,
   1252                                 /*allow_abstract=*/0, &tname, &tloc);
   1253       validate_decl_type_constraints(p, &specs, tty,
   1254                                      tty && tty->kind == TY_FUNC,
   1255                                      /*is_member=*/0);
   1256       if (is_punct(&p->cur, '=')) {
   1257         perr(p, "typedef declarator cannot have initializer");
   1258       }
   1259       reject_same_scope_redefinition(p, tname, SEK_TYPEDEF, tty);
   1260       {
   1261         SymEntry* te = scope_define(p, tname, SEK_TYPEDEF, tty);
   1262         sym_set_decl(te, DECL_NONE, DS_TYPEDEF, DL_NONE, specs.flags,
   1263                      DSTATE_DECLARED);
   1264       }
   1265       (void)tloc;
   1266       if (!accept_punct(p, ',')) break;
   1267     }
   1268     expect_punct(p, ';', "';' after typedef declaration");
   1269     return;
   1270   }
   1271 
   1272   base_ty = parse_declarator_full_info(p, specs.type, /*allow_abstract=*/0,
   1273                                        &name, &loc, &dattrs, &dinfo);
   1274 
   1275   if (base_ty && base_ty->kind == TY_FUNC) {
   1276     ParamInfo* infos = NULL;
   1277     u16 nparams = 0;
   1278     const Type* fn_ty;
   1279     const ABIFuncInfo* abi;
   1280     SymEntry* fent;
   1281 
   1282     fn_ty = base_ty;
   1283     infos = dinfo.fn_params;
   1284     nparams = dinfo.fn_nparams;
   1285     validate_decl_type_constraints(p, &specs, fn_ty, /*is_function=*/1,
   1286                                    /*is_member=*/0);
   1287     abi = c_abi_func_info(p->abi, p->pool, fn_ty);
   1288 
   1289     ObjSecId fn_section_id;
   1290     u32 fn_decl_flags;
   1291     Sym fn_alias_target;
   1292     fent = declare_function(p, name, fn_ty, &specs, loc, dattrs, dinfo.asm_label,
   1293                             &fn_section_id, &fn_decl_flags, &fn_alias_target);
   1294     attr_list_append(&fent->attrs, dattrs);
   1295 
   1296     if (is_punct(&p->cur, '{')) {
   1297       int suppress_body_codegen = specs.storage == DS_EXTERN &&
   1298                                   ((specs.flags | fn_decl_flags) & DF_INLINE);
   1299       if (fent->defined) perr(p, "redefinition of function");
   1300       fent->defined = 1;
   1301       fent->decl_state = DSTATE_FUNC_DEFINED;
   1302       Sym saved_func_name = p->cur_func_name;
   1303       const Type* saved_func_ret = p->cur_func_ret;
   1304       p->cur_func_name = name;
   1305       p->cur_func_ret = fn_ty->fn.ret;
   1306       if (suppress_body_codegen) pcg_codegen_suppress_push(p);
   1307       parse_function_body(p, fent->v.sym, fn_ty, abi, infos, nparams, loc,
   1308                           fn_section_id, fn_decl_flags);
   1309       if (suppress_body_codegen) pcg_codegen_suppress_pop(p);
   1310       p->cur_func_name = saved_func_name;
   1311       p->cur_func_ret = saved_func_ret;
   1312       return;
   1313     }
   1314     if (accept_punct(p, ';')) {
   1315       if (fn_alias_target != 0) {
   1316         SymEntry* te = scope_lookup(p, fn_alias_target);
   1317         if (!te) {
   1318           const char* nm = kit_sym_str(p->pool->c, fn_alias_target).s;
   1319           compiler_panic(p->c, loc, "alias target '%.*s' is undefined",
   1320                          KIT_SLICE_ARG(kit_slice_cstr(nm ? nm : "?")));
   1321         }
   1322         KitCgAlias alias;
   1323         memset(&alias, 0, sizeof alias);
   1324         alias.display_name = name;
   1325         alias.linkage_name = kit_cg_c_linkage_name(p->c, name);
   1326         alias.target = te->v.sym;
   1327         alias.sym.bind =
   1328             (fn_decl_flags & DF_WEAK) ? KIT_SB_WEAK : KIT_SB_GLOBAL;
   1329         {
   1330           const Decl* fd = decl_get(p->decls, fent->decl_id);
   1331           alias.sym.visibility =
   1332               fd ? (KitCgVisibility)fd->visibility : KIT_CG_VIS_DEFAULT;
   1333         }
   1334         if (kit_cg_alias(p->cg, alias) == KIT_CG_SYM_NONE) {
   1335           const char* nm = kit_sym_str(p->pool->c, fn_alias_target).s;
   1336           compiler_panic(p->c, loc, "alias target '%.*s' is undefined",
   1337                          KIT_SLICE_ARG(kit_slice_cstr(nm ? nm : "?")));
   1338         }
   1339       }
   1340       return;
   1341     }
   1342     perr(p, "expected '{' or ';' after function declarator");
   1343   }
   1344 
   1345   /* Global object declaration. */
   1346   for (;;) {
   1347     int has_init = is_punct(&p->cur, '=');
   1348     int is_pure_extern =
   1349         (specs.storage == DS_EXTERN || specs.storage == DS_REGISTER) &&
   1350         !has_init;
   1351     SymEntry* existing = scope_lookup_current(p, name);
   1352     ObjSymId sym = OBJ_SYM_NONE;
   1353     ObjSecId section_id = OBJ_SEC_NONE;
   1354     SymEntry* e = NULL;
   1355 
   1356     if (existing && existing->kind != SEK_GLOBAL) {
   1357       perr(p, "redefinition of identifier");
   1358     }
   1359     validate_decl_type_constraints(p, &specs, base_ty, /*is_function=*/0,
   1360                                    /*is_member=*/0);
   1361 
   1362     if (existing && existing->kind == SEK_GLOBAL) {
   1363       const Type* composite = NULL;
   1364       CSemCheck chk = c_sem_check_redeclaration(p->pool, existing->type,
   1365                                                 base_ty, &composite);
   1366       if (!chk.ok) perr(p, "%.*s", KIT_SLICE_ARG(kit_slice_cstr(chk.message)));
   1367       if (specs.storage == DS_STATIC && existing->linkage == DL_EXTERNAL) {
   1368         perr(p, "static declaration follows non-static declaration");
   1369       }
   1370       sym = existing->v.sym;
   1371       e = existing;
   1372       if (has_init && e->defined) {
   1373         perr(p, "redefinition of object");
   1374       }
   1375       if (composite) e->type = composite;
   1376       base_ty = e->type;
   1377     } else {
   1378       Decl decl_in;
   1379       DeclId did;
   1380       memset(&decl_in, 0, sizeof decl_in);
   1381       decl_in.name = name;
   1382       decl_in.asm_name = dinfo.asm_label;
   1383       decl_in.type = base_ty;
   1384       decl_in.loc = loc;
   1385       if (specs.storage == DS_STATIC) {
   1386         decl_in.storage = DS_STATIC;
   1387         decl_in.linkage = DL_INTERNAL;
   1388       } else {
   1389         decl_in.storage = DS_EXTERN;
   1390         decl_in.linkage = DL_EXTERNAL;
   1391       }
   1392       decl_in.visibility =
   1393           decl_in.linkage == DL_EXTERNAL ? p->default_visibility : SV_DEFAULT;
   1394       decl_in.flags = specs.flags & DF_THREAD;
   1395       attr_list_to_decl(p->c, p->decls, specs.attrs, &decl_in);
   1396       attr_list_to_decl(p->c, p->decls, dattrs, &decl_in);
   1397       did = decl_declare(p->decls, &decl_in);
   1398       sym = decl_obj_sym(p->decls, did);
   1399       section_id = decl_in.section_id;
   1400       e = scope_define(p, name, SEK_GLOBAL, base_ty);
   1401       e->v.sym = sym;
   1402       sym_set_decl(e, did, decl_in.storage, decl_in.linkage, decl_in.flags,
   1403                    DSTATE_DECLARED);
   1404     }
   1405     attr_list_append(&e->attrs, dattrs);
   1406 
   1407     u32 attr_align = attrs_pick_aligned(specs.attrs);
   1408     {
   1409       u32 a2 = attrs_pick_aligned(dattrs);
   1410       if (a2 > attr_align) attr_align = a2;
   1411     }
   1412     u32 align_eff = (specs.align > attr_align) ? specs.align : attr_align;
   1413 
   1414     if (has_init) {
   1415       if (e) e->defined = 1;
   1416       if (e) e->decl_state = DSTATE_DEFINED;
   1417       advance(p); /* '=' */
   1418       if (base_ty && base_ty->kind == TY_ARRAY && base_ty->arr.incomplete) {
   1419         const Type* completed = complete_incomplete_array(p, base_ty);
   1420         if (completed != base_ty) {
   1421           base_ty = completed;
   1422           if (e) e->type = base_ty;
   1423         }
   1424       }
   1425       define_static_object(p, sym, section_id, base_ty, specs.quals,
   1426                            /*has_init=*/1, loc, align_eff);
   1427     } else if (!is_pure_extern) {
   1428       if (e && e->decl_state == DSTATE_DECLARED) {
   1429         e->decl_state = DSTATE_TENTATIVE;
   1430       }
   1431       define_static_object(p, sym, section_id, base_ty, specs.quals,
   1432                            /*has_init=*/0, loc, align_eff);
   1433     }
   1434 
   1435     if (!accept_punct(p, ',')) break;
   1436     dattrs = NULL;
   1437     base_ty = parse_declarator_full_info(p, specs.type, /*allow_abstract=*/0,
   1438                                          &name, &loc, &dattrs, &dinfo);
   1439     if (base_ty && base_ty->kind == TY_FUNC) {
   1440       perr(p, "function declarator in object declaration list");
   1441     }
   1442   }
   1443   expect_punct(p, ';', "';' after global declaration");
   1444 }
   1445 
   1446 static void parse_file_scope_asm(Parser* p) {
   1447   u8* bytes;
   1448   size_t nbytes;
   1449   advance(p); /* asm / __asm__ */
   1450   for (;;) {
   1451     if (is_kw(p, &p->cur, KW_VOLATILE)) {
   1452       advance(p);
   1453       continue;
   1454     }
   1455     if (p->cur.kind == TOK_IDENT && p->cur.v.ident == p->sym_volatile_alias) {
   1456       advance(p);
   1457       continue;
   1458     }
   1459     break;
   1460   }
   1461   expect_punct(p, '(', "'(' after file-scope asm");
   1462   if (p->cur.kind != TOK_STR) {
   1463     perr(p, "expected string literal in file-scope asm");
   1464   }
   1465   bytes = decode_string_literal(p, &p->cur, &nbytes);
   1466   advance(p);
   1467   expect_punct(p, ')', "')' after file-scope asm");
   1468   expect_punct(p, ';', "';' after file-scope asm");
   1469   if (nbytes > 0) --nbytes; /* drop decode_string_literal's trailing NUL */
   1470   if (pcg_emit_enabled(p)) {
   1471     KitSlice asm_src = {{(const char*)bytes}, nbytes};
   1472     kit_cg_file_scope_asm(p->cg, asm_src);
   1473   }
   1474 }
   1475 
   1476 static void parse_translation_unit(Parser* p) {
   1477   while (p->cur.kind != TOK_EOF) {
   1478     if (p->cur.kind == TOK_NEWLINE || is_pp_hash(&p->cur)) {
   1479       advance(p);
   1480       continue;
   1481     }
   1482     if (is_kw(p, &p->cur, KW_STATIC_ASSERT)) {
   1483       parse_static_assert(p);
   1484       continue;
   1485     }
   1486     if (is_kw(p, &p->cur, KW_ASM) || is_kw(p, &p->cur, KW_BUILTIN_ASM)) {
   1487       parse_file_scope_asm(p);
   1488       continue;
   1489     }
   1490     if (accept_punct(p, ';')) {
   1491       continue;
   1492     }
   1493     parse_external_decl(p);
   1494   }
   1495 }
   1496 
   1497 /* ============================================================
   1498  * Entry point
   1499  * ============================================================ */
   1500 
   1501 static u8 parser_default_visibility(KitSymVis vis) {
   1502   switch (vis) {
   1503     case KIT_SV_HIDDEN:
   1504     case KIT_SV_INTERNAL:
   1505       return SV_HIDDEN;
   1506     case KIT_SV_PROTECTED:
   1507       return SV_PROTECTED;
   1508     case KIT_SV_DEFAULT:
   1509     default:
   1510       return SV_DEFAULT;
   1511   }
   1512 }
   1513 
   1514 void parse_c(Compiler* c, Pool* pool, Pp* pp, DeclTable* decls, CG* cg,
   1515              KitSymVis default_visibility) {
   1516   Parser p;
   1517   CKw i;
   1518   u32 syscall_i;
   1519 
   1520   memset(&p, 0, sizeof p);
   1521   p.c = c;
   1522   p.pp = pp;
   1523   p.decls = decls;
   1524   p.cg = cg;
   1525   p.abi = c;
   1526   p.pool = pool;
   1527   p.default_visibility = parser_default_visibility(default_visibility);
   1528 
   1529   for (i = (CKw)1; i < KW_COUNT; ++i) {
   1530     p.kw_sym[i] = kit_sym_intern(p.pool->c, kit_slice_cstr(kw_names[i]));
   1531   }
   1532 
   1533   p.sym_b_alloca = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_alloca"));
   1534   p.sym_b_ctz = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_ctz"));
   1535   p.sym_b_ctzl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_ctzl"));
   1536   p.sym_b_ctzll = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_ctzll"));
   1537   p.sym_b_clz = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_clz"));
   1538   p.sym_b_clzl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_clzl"));
   1539   p.sym_b_clzll = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_clzll"));
   1540   p.sym_b_trap = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_trap"));
   1541   p.sym_b_unreachable =
   1542       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_unreachable"));
   1543   p.sym_b_return_address =
   1544       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_return_address"));
   1545   p.sym_b_frame_address =
   1546       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_frame_address"));
   1547   for (syscall_i = 0; syscall_i < 7u; ++syscall_i) {
   1548     char name[16];
   1549     memcpy(name, "__kit_syscall", 13u);
   1550     name[13] = (char)('0' + syscall_i);
   1551     name[14] = '\0';
   1552     p.sym_kit_syscall[syscall_i] =
   1553         kit_sym_intern(p.pool->c, kit_slice_cstr(name));
   1554   }
   1555   p.sym_b_memcpy = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_memcpy"));
   1556   p.sym_b_memmove =
   1557       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_memmove"));
   1558   p.sym_b_memcmp = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_memcmp"));
   1559   p.sym_b_memset = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_memset"));
   1560   p.sym_b_clear_cache =
   1561       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin___clear_cache"));
   1562   p.sym_b_isnan = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isnan"));
   1563   p.sym_b_fabs = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_fabs"));
   1564   p.sym_b_fabsf = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_fabsf"));
   1565   p.sym_b_fabsl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_fabsl"));
   1566   p.sym_b_inf = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_inf"));
   1567   p.sym_b_inff = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_inff"));
   1568   p.sym_b_infl = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_infl"));
   1569   p.sym_b_huge_val =
   1570       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_huge_val"));
   1571   p.sym_b_huge_valf =
   1572       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_huge_valf"));
   1573   p.sym_b_huge_vall =
   1574       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_huge_vall"));
   1575   p.sym_b_isless = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isless"));
   1576   p.sym_b_islessequal =
   1577       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_islessequal"));
   1578   p.sym_b_isgreater =
   1579       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isgreater"));
   1580   p.sym_b_isgreaterequal =
   1581       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isgreaterequal"));
   1582   p.sym_b_islessgreater =
   1583       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_islessgreater"));
   1584   p.sym_b_isunordered =
   1585       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_isunordered"));
   1586   p.sym_func = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__func__"));
   1587   p.sym_func_gcc = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__FUNCTION__"));
   1588   p.sym_pretty_func_gcc =
   1589       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__PRETTY_FUNCTION__"));
   1590   p.sym_b_expect = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_expect"));
   1591   p.sym_b_offsetof =
   1592       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_offsetof"));
   1593   p.sym_b_va_list =
   1594       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_list"));
   1595   p.sym_b_va_start =
   1596       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_start"));
   1597   p.sym_b_va_arg = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_arg"));
   1598   p.sym_b_va_end = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_end"));
   1599   p.sym_b_va_copy =
   1600       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__builtin_va_copy"));
   1601   p.sym_attribute = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__attribute__"));
   1602   p.sym_volatile_alias =
   1603       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__volatile__"));
   1604   p.sym_alignof_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__alignof__"));
   1605   p.sym_asm_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__asm"));
   1606   p.sym_inline_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__inline"));
   1607   p.sym_inline_alias2 = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__inline__"));
   1608   /* __restrict / __restrict__: GCC keyword spellings of `restrict`. glibc
   1609    * headers use these as real keywords (and #undef any fallback macro under
   1610    * __GNUC__), so recognize them in the parser, not just via a pp macro. */
   1611   p.sym_restrict_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__restrict"));
   1612   p.sym_restrict_alias2 =
   1613       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__restrict__"));
   1614   p.sym_thread_alias = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__thread"));
   1615   p.sym_int128 = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__int128"));
   1616   p.sym_int128_t = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__int128_t"));
   1617   p.sym_uint128_t = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__uint128_t"));
   1618   p.sym_a_load_n = kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_load_n"));
   1619   p.sym_a_store_n =
   1620       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_store_n"));
   1621   p.sym_a_exchange_n =
   1622       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_exchange_n"));
   1623   p.sym_a_fetch_add =
   1624       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_add"));
   1625   p.sym_a_fetch_sub =
   1626       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_sub"));
   1627   p.sym_a_fetch_and =
   1628       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_and"));
   1629   p.sym_a_fetch_or =
   1630       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_or"));
   1631   p.sym_a_fetch_xor =
   1632       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_xor"));
   1633   p.sym_a_fetch_nand =
   1634       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_fetch_nand"));
   1635   p.sym_a_cas_n =
   1636       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_compare_exchange_n"));
   1637   p.sym_a_always_lock_free =
   1638       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_always_lock_free"));
   1639   p.sym_a_is_lock_free =
   1640       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_is_lock_free"));
   1641   p.sym_a_thread_fence =
   1642       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_thread_fence"));
   1643   p.sym_a_signal_fence =
   1644       kit_sym_intern(p.pool->c, KIT_SLICE_LIT("__atomic_signal_fence"));
   1645 
   1646   p.scope = scope_new(&p, NULL);
   1647 
   1648   p.cur = fetch_tok(&p);
   1649 
   1650   parse_translation_unit(&p);
   1651 }