kit

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

parse_priv.h (18597B)


      1 /* parse_priv.h — private header shared across parse_*.c modules.
      2  *
      3  * Declares: Parser struct, shared types (Scope, SymEntry, TagEntry,
      4  * DeclSpecs, TypeSpecAccum, CKw, TagDeclKind), forward decls of
      5  * cross-module functions, and inline/shared helpers. */
      6 
      7 #pragma once
      8 
      9 #include <stdarg.h>
     10 #include <string.h>
     11 
     12 #include "abi/c_abi.h"
     13 #include "decl/decl.h"
     14 #include "decl/decl_attrs.h"
     15 #include "lex/lex.h"
     16 #include "parse/attr.h"
     17 #include "parse/parse.h"
     18 #include "pp/pp.h"
     19 #include "sem/sem.h"
     20 #include "type/type.h"
     21 
     22 /* ============================================================
     23  * Keywords
     24  * ============================================================ */
     25 typedef enum CKw {
     26   KW_NONE = 0,
     27   KW_AUTO,
     28   KW_BREAK,
     29   KW_CASE,
     30   KW_CHAR,
     31   KW_CONST,
     32   KW_CONTINUE,
     33   KW_DEFAULT,
     34   KW_DO,
     35   KW_DOUBLE,
     36   KW_ELSE,
     37   KW_ENUM,
     38   KW_EXTERN,
     39   KW_FLOAT,
     40   KW_FLOAT16, /* _Float16 */
     41   KW_FOR,
     42   KW_GOTO,
     43   KW_IF,
     44   KW_INLINE,
     45   KW_INT,
     46   KW_LONG,
     47   KW_REGISTER,
     48   KW_RESTRICT,
     49   KW_RETURN,
     50   KW_SHORT,
     51   KW_SIGNED,
     52   KW_SIZEOF,
     53   KW_STATIC,
     54   KW_STRUCT,
     55   KW_SWITCH,
     56   KW_TYPEDEF,
     57   KW_UNION,
     58   KW_UNSIGNED,
     59   KW_VOID,
     60   KW_VOLATILE,
     61   KW_WHILE,
     62   KW_BOOL,          /* _Bool */
     63   KW_COMPLEX,       /* _Complex */
     64   KW_IMAGINARY,     /* _Imaginary */
     65   KW_ALIGNAS,       /* _Alignas */
     66   KW_ALIGNOF,       /* _Alignof */
     67   KW_ATOMIC,        /* _Atomic */
     68   KW_GENERIC,       /* _Generic */
     69   KW_NORETURN,      /* _Noreturn */
     70   KW_STATIC_ASSERT, /* _Static_assert */
     71   KW_THREAD_LOCAL,  /* _Thread_local */
     72   KW_ASM,           /* GNU `asm` */
     73   KW_BUILTIN_ASM,   /* GNU `__asm__` */
     74   KW_COUNT
     75 } CKw;
     76 
     77 /* ============================================================
     78  * Scope stack types
     79  * ============================================================ */
     80 
     81 typedef enum SymEntryKind {
     82   SEK_LOCAL,    /* local variable or parameter source handle */
     83   SEK_GLOBAL,   /* global var, OPK_GLOBAL via ObjSymId */
     84   SEK_FUNC,     /* function decl, OPK_GLOBAL via ObjSymId */
     85   SEK_TYPEDEF,  /* typedef name */
     86   SEK_ENUM_CST, /* enumeration constant */
     87 } SymEntryKind;
     88 
     89 typedef struct SymEntry SymEntry;
     90 typedef struct VLABound VLABound;
     91 typedef struct ExternalFuncDecl ExternalFuncDecl;
     92 typedef struct StaticReloc StaticReloc;
     93 struct VLABound {
     94   const Type* array_ty;
     95   FrameSlot byte_slot;
     96   FrameSlot count_slot;
     97   VLABound* next;
     98 };
     99 
    100 typedef struct ParamVLABoundExpr ParamVLABoundExpr;
    101 struct ParamVLABoundExpr {
    102   Tok* toks;
    103   u32 ntoks;
    104   u8 has_expr;
    105   u8 pad[3];
    106 };
    107 
    108 struct StaticReloc {
    109   u32 offset;
    110   u32 size;
    111   ObjSymId target; /* symbol target when is_label == 0 */
    112   i64 addend;
    113   CGLabel label; /* label target when is_label != 0 */
    114   u8 is_label;   /* 1 -> label-address reloc (&&label), 0 -> symbol reloc */
    115   u8 pad[3];
    116 };
    117 
    118 struct SymEntry {
    119   Sym name;
    120   u8 kind;    /* SymEntryKind */
    121   u8 defined; /* compatibility alias for decl_state >= DSTATE_DEFINED */
    122   u8 decl_state;
    123   u8 storage; /* DeclStorage */
    124   u8 linkage; /* DeclLinkage */
    125   u8 pad[3];
    126   DeclId decl_id;
    127   u32 decl_flags;
    128   const Type* type;
    129   union {
    130     FrameSlot slot;
    131     ObjSymId sym;
    132     i64 enum_value;
    133   } v;
    134   FrameSlot vla_byte_slot;
    135   VLABound* vla_bounds;
    136   struct Attr* attrs;
    137   /* For a `register T x __asm__("reg")` local: the interned hard-register name
    138    * ("r10", "x8", ...) the variable is bound to. Pins x to that register when
    139    * used as an inline-asm operand (GNU explicit register variables). 0 = none.
    140    */
    141   Sym reg_asm_name;
    142   SymEntry* next;
    143 };
    144 
    145 struct ExternalFuncDecl {
    146   Sym name;
    147   SymEntry* entry;
    148   ExternalFuncDecl* next;
    149 };
    150 
    151 typedef struct TagEntry TagEntry;
    152 struct TagEntry {
    153   Sym name;
    154   u8 kind; /* TagDeclKind */
    155   u8 complete;
    156   u16 pad;
    157   Type* type;
    158   struct Attr* attrs;
    159   TagEntry* next;
    160 };
    161 
    162 typedef struct Scope Scope;
    163 struct Scope {
    164   SymEntry* entries; /* LIFO */
    165   TagEntry* tags;    /* LIFO */
    166   Scope* parent;
    167   u32 saved_vla_mark;
    168 };
    169 
    170 /* ============================================================
    171  * Switch/goto control-flow types
    172  * ============================================================ */
    173 
    174 typedef struct CaseEntry CaseEntry;
    175 struct CaseEntry {
    176   i64 value;
    177   CGLabel label;
    178   CaseEntry* next;
    179 };
    180 
    181 typedef struct SwitchCtx SwitchCtx;
    182 struct SwitchCtx {
    183   CaseEntry* cases;
    184   CGLabel default_label;
    185   FrameSlot value_slot;
    186   const Type* value_type;
    187   SwitchCtx* parent;
    188 };
    189 
    190 typedef struct GotoLabel GotoLabel;
    191 struct GotoLabel {
    192   Sym name;
    193   CGLabel label;
    194   u8 placed;
    195   u8 addr_taken; /* set when &&label is used (labels-as-values) */
    196   u8 pad[2];
    197   SrcLoc first_use;
    198   u32 min_forward_vla_mark;
    199   u32 label_vla_mark;
    200   GotoLabel* next;
    201 };
    202 
    203 /* ============================================================
    204  * Parser context
    205  * ============================================================ */
    206 
    207 typedef struct Parser {
    208   Compiler* c;
    209   Pp* pp;
    210   DeclTable* decls;
    211   CG* cg;
    212   KitCompiler* abi;
    213   Pool* pool;
    214   u8 default_visibility; /* SymVis */
    215 
    216   const Type** cg_type_stack;
    217   u8* cg_value_flags;
    218   PcgLvAux* cg_lv_aux;
    219   u32 cg_type_sp;
    220   u32 cg_type_cap;
    221 
    222   Tok cur;
    223   Tok next;
    224   int has_next;
    225 
    226   Tok pending;
    227   int has_pending;
    228 
    229   Sym kw_sym[KW_COUNT];
    230 
    231   Sym sym_b_alloca;
    232   Sym sym_b_ctz;
    233   Sym sym_b_ctzl;
    234   Sym sym_b_ctzll;
    235   Sym sym_b_clz;
    236   Sym sym_b_clzl;
    237   Sym sym_b_clzll;
    238   Sym sym_b_trap;
    239   Sym sym_b_unreachable;
    240   Sym sym_b_memcpy;
    241   Sym sym_b_memmove;
    242   Sym sym_b_memcmp;
    243   Sym sym_b_memset;
    244   Sym sym_b_clear_cache;
    245   Sym sym_b_isnan;
    246   Sym sym_b_fabs;
    247   Sym sym_b_fabsf;
    248   Sym sym_b_fabsl;
    249   Sym sym_b_inf;
    250   Sym sym_b_inff;
    251   Sym sym_b_infl;
    252   Sym sym_b_huge_val;
    253   Sym sym_b_huge_valf;
    254   Sym sym_b_huge_vall;
    255   Sym sym_b_isless;         /* __builtin_isless */
    256   Sym sym_b_islessequal;    /* __builtin_islessequal */
    257   Sym sym_b_isgreater;      /* __builtin_isgreater */
    258   Sym sym_b_isgreaterequal; /* __builtin_isgreaterequal */
    259   Sym sym_b_islessgreater;  /* __builtin_islessgreater */
    260   Sym sym_b_isunordered;    /* __builtin_isunordered */
    261   Sym sym_func;             /* __func__ */
    262   Sym sym_func_gcc;         /* __FUNCTION__ */
    263   Sym sym_pretty_func_gcc;  /* __PRETTY_FUNCTION__ */
    264   Sym cur_func_name;        /* name of the function whose body we're in,
    265                              * 0 at file scope */
    266   const Type* cur_func_ret;
    267   Sym sym_b_expect;
    268   Sym sym_b_offsetof;
    269   Sym sym_b_va_list;
    270   /* Cached singleton for __builtin_va_list — built lazily on first
    271    * mention so every occurrence resolves to the same Type* (and the
    272    * same TagId where applicable).  Without the cache, c_abi_va_list_type
    273    * mints a fresh struct type per occurrence and headers that pass
    274    * locally-declared __builtin_va_list values to functions taking
    275    * va_list (e.g. mingw's sec_api/stdio_s.h) fail type-equality. */
    276   const Type* type_b_va_list;
    277   Sym sym_b_va_start;
    278   Sym sym_b_va_arg;
    279   Sym sym_b_va_end;
    280   Sym sym_b_va_copy;
    281   Sym sym_b_return_address; /* __builtin_return_address */
    282   Sym sym_b_frame_address;  /* __builtin_frame_address */
    283   Sym sym_kit_syscall[7];   /* __kit_syscall0 .. __kit_syscall6 */
    284   Sym sym_attribute;
    285   Sym sym_volatile_alias;
    286   Sym sym_alignof_alias;
    287   Sym sym_asm_alias;
    288   Sym sym_inline_alias;
    289   Sym sym_inline_alias2;
    290   Sym sym_restrict_alias;
    291   Sym sym_restrict_alias2;
    292   Sym sym_thread_alias;
    293   Sym sym_int128;    /* __int128 */
    294   Sym sym_int128_t;  /* __int128_t */
    295   Sym sym_uint128_t; /* __uint128_t */
    296   Sym sym_a_load_n;
    297   Sym sym_a_store_n;
    298   Sym sym_a_exchange_n;
    299   Sym sym_a_fetch_add;
    300   Sym sym_a_fetch_sub;
    301   Sym sym_a_fetch_and;
    302   Sym sym_a_fetch_or;
    303   Sym sym_a_fetch_xor;
    304   Sym sym_a_fetch_nand;
    305   Sym sym_a_cas_n;
    306   Sym sym_a_always_lock_free;
    307   Sym sym_a_is_lock_free;
    308   Sym sym_a_thread_fence;
    309   Sym sym_a_signal_fence;
    310 
    311   Scope* scope;
    312   ExternalFuncDecl* external_funcs;
    313 
    314   CGLabel cur_break;
    315   CGLabel cur_continue;
    316 
    317   SwitchCtx* cur_switch;
    318 
    319   GotoLabel* goto_labels;
    320   /* Set once a computed `goto *expr;` has been emitted in the current
    321    * function. After this point taking a new label's address with `&&label`
    322    * is rejected, because each computed goto's target set is finalized when
    323    * it is emitted and a later address-taken label would not be in it. */
    324   u8 computed_goto_emitted;
    325 
    326   u8 vla_pending;
    327   FrameSlot vla_pending_count_slot;
    328   FrameSlot vla_pending_count_slots[8];
    329   u8 vla_pending_count_len;
    330   u32 vla_mark;
    331 
    332   FrameSlot last_pushed_vla_slot;
    333   VLABound* last_pushed_vla_bounds;
    334 
    335   u8 in_param_decl;
    336   ParamVLABoundExpr param_vla_bounds[8];
    337   u8 param_vla_bound_len;
    338   u32 suppress_codegen;
    339 
    340   u32 static_local_counter;
    341 
    342   u32 compound_literal_counter;
    343 
    344   Tok* replay;
    345   u32 replay_cap;
    346   u32 replay_len;
    347   u32 replay_pos;
    348   u8 replay_active;
    349 
    350   StaticReloc* static_relocs;
    351   u32 static_relocs_len;
    352   u32 static_relocs_cap;
    353 } Parser;
    354 
    355 /* ============================================================
    356  * DeclSpecs and TypeSpecAccum
    357  * ============================================================ */
    358 
    359 typedef struct DeclSpecs {
    360   const Type* type;
    361   DeclStorage storage;
    362   u32 flags; /* DeclFlag */
    363   u16 quals;
    364   u8 storage_explicit;
    365   u8 pad;
    366   u32 align;
    367   FrameSlot vla_byte_slot;
    368   VLABound* vla_bounds;
    369   Attr* attrs;
    370 } DeclSpecs;
    371 
    372 typedef struct TypeSpecAccum {
    373   u8 saw_void;
    374   u8 saw_char;
    375   u8 saw_int;
    376   u8 saw_short;
    377   u8 long_count;
    378   u8 saw_signed;
    379   u8 saw_unsigned;
    380   u8 saw_bool;
    381   u8 saw_float;
    382   u8 saw_double;
    383   u8 saw_int128; /* __int128 / __int128_t / __uint128_t */
    384   u8 saw_explicit_type;
    385 } TypeSpecAccum;
    386 
    387 /* ============================================================
    388  * Shared token/diagnostic helpers (defined in parse.c)
    389  * ============================================================ */
    390 
    391 _Noreturn void perr(Parser* p, const char* fmt, ...);
    392 void advance(Parser* p);
    393 Tok peek1(Parser* p);
    394 void expect_punct(Parser* p, u32 punct, const char* what);
    395 int accept_punct(Parser* p, u32 punct);
    396 
    397 /* ============================================================
    398  * Scope/tag ops (defined in parse.c)
    399  * ============================================================ */
    400 
    401 Scope* scope_new(Parser* p, Scope* parent);
    402 void scope_push(Parser* p);
    403 void scope_pop(Parser* p);
    404 SymEntry* scope_define(Parser* p, Sym name, SymEntryKind kind,
    405                        const Type* type);
    406 SymEntry* scope_lookup_current(Parser* p, Sym name);
    407 SymEntry* scope_lookup(Parser* p, Sym name);
    408 TagEntry* tag_define(Parser* p, Sym name, TagDeclKind kind, Type* type,
    409                      int complete);
    410 TagEntry* tag_lookup(Parser* p, Sym name);
    411 TagEntry* tag_lookup_local(Parser* p, Sym name);
    412 
    413 /* ============================================================
    414  * Token predicate helpers (defined in parse.c — file-scope static,
    415  * exposed here as inline equivalents; each .c file sees its own copy)
    416  * ============================================================ */
    417 
    418 static inline int is_punct(const Tok* t, u32 punct) {
    419   return t->kind == TOK_PUNCT && t->v.punct == punct;
    420 }
    421 
    422 static inline int is_pp_hash(const Tok* t) { return t->kind == TOK_PP_HASH; }
    423 
    424 static inline CKw ident_kw_inline(const Parser* p, Sym name) {
    425   CKw i;
    426   for (i = (CKw)1; i < KW_COUNT; ++i) {
    427     if (p->kw_sym[i] == name) return i;
    428   }
    429   if (name == p->sym_alignof_alias) return KW_ALIGNOF;
    430   if (name == p->sym_asm_alias) return KW_BUILTIN_ASM;
    431   if (name == p->sym_inline_alias || name == p->sym_inline_alias2)
    432     return KW_INLINE;
    433   if (name == p->sym_restrict_alias || name == p->sym_restrict_alias2)
    434     return KW_RESTRICT;
    435   if (name == p->sym_thread_alias) return KW_THREAD_LOCAL;
    436   return KW_NONE;
    437 }
    438 
    439 static inline int is_kw(const Parser* p, const Tok* t, CKw k) {
    440   if (t->kind != TOK_IDENT) return 0;
    441   if (t->v.ident == p->kw_sym[k]) return 1;
    442   if (k == KW_ALIGNOF && t->v.ident == p->sym_alignof_alias) return 1;
    443   if (k == KW_BUILTIN_ASM && t->v.ident == p->sym_asm_alias) return 1;
    444   if (k == KW_INLINE &&
    445       (t->v.ident == p->sym_inline_alias || t->v.ident == p->sym_inline_alias2))
    446     return 1;
    447   if (k == KW_RESTRICT &&
    448       (t->v.ident == p->sym_restrict_alias ||
    449        t->v.ident == p->sym_restrict_alias2))
    450     return 1;
    451   if (k == KW_THREAD_LOCAL && t->v.ident == p->sym_thread_alias) return 1;
    452   return 0;
    453 }
    454 
    455 static inline int c_type_is_scalar(const Type* ty) {
    456   return type_is_arith(ty) || type_is_ptr(ty);
    457 }
    458 
    459 /* ============================================================
    460  * Shared types (needed across multiple modules)
    461  * ============================================================ */
    462 
    463 typedef struct ParamInfo {
    464   Sym name;
    465   const Type* type;
    466   const Type* declared_type;
    467   SrcLoc loc;
    468   ParamVLABoundExpr* vla_bounds;
    469   u8 vla_bound_len;
    470 } ParamInfo;
    471 
    472 /* ============================================================
    473  * Declarator suffix types (defined in parse_type.c, shared here)
    474  * ============================================================ */
    475 
    476 typedef enum DSuffKind { DS_ARRAY, DS_FUNC } DSuffKind;
    477 typedef struct DeclSuffix {
    478   u8 kind;       /* DSuffKind */
    479   u32 count;     /* element count; meaningful when !vla and !incomplete */
    480   u8 incomplete; /* true for `[]` (no size given) */
    481   u8 vla;        /* true for `[expr]` with a non-constant size */
    482   FrameSlot vla_count_slot;
    483   ParamInfo* params;
    484   u16 nparams;
    485   u8 variadic;
    486 } DeclSuffix;
    487 
    488 typedef struct DeclaratorInfo {
    489   ParamInfo* fn_params;
    490   u16 fn_nparams;
    491   u8 fn_variadic;
    492   Sym asm_label;
    493 } DeclaratorInfo;
    494 
    495 /* ============================================================
    496  * Cross-module forward declarations
    497  * ============================================================ */
    498 
    499 /* parse_type.c */
    500 
    501 int parse_decl_specs(Parser* p, DeclSpecs* out);
    502 const Type* parse_struct_or_union(Parser* p, TypeKind kind,
    503                                   Attr** anon_attrs_out);
    504 const Type* parse_enum(Parser* p, Attr** anon_attrs_out);
    505 const Type* resolve_type_specs(Parser* p, const TypeSpecAccum* a, SrcLoc loc);
    506 const Type* parse_type_name(Parser* p);
    507 const Type* parse_pointer_layer(Parser* p, const Type* base);
    508 const Type* parse_declarator_full(Parser* p, const Type* base,
    509                                   int allow_abstract, Sym* name_out,
    510                                   SrcLoc* loc_out);
    511 const Type* parse_declarator_full_ex(Parser* p, const Type* base,
    512                                      int allow_abstract, Sym* name_out,
    513                                      SrcLoc* loc_out, Attr** attrs_out);
    514 const Type* parse_declarator_full_info(Parser* p, const Type* base,
    515                                        int allow_abstract, Sym* name_out,
    516                                        SrcLoc* loc_out, Attr** attrs_out,
    517                                        DeclaratorInfo* info_out);
    518 const Type* parse_declarator(Parser* p, const Type* base, Sym* name_out,
    519                              SrcLoc* loc_out);
    520 const Type* complete_incomplete_array(Parser* p, const Type* ty);
    521 int starts_type_name(const Parser* p, const Tok* t);
    522 int starts_attr(const Parser* p);
    523 Attr* parse_attribute_spec_list(Parser* p);
    524 void parse_and_discard_attributes(Parser* p);
    525 int find_field(KitCompiler* abi, Pool* pool, const Type* rec, Sym name,
    526                const Type** out_type, u32* out_offset, const Field** out_field);
    527 u32 attrs_pick_aligned(const Attr* a);
    528 void attr_list_append(Attr** head, Attr* add);
    529 void parse_attrs_into(Parser* p, Attr** sink);
    530 int parse_decl_suffix(Parser* p, DeclSuffix* out);
    531 const Type* apply_decl_suffix(Parser* p, const Type* base, const DeclSuffix* s);
    532 void validate_decl_type_constraints(Parser* p, const DeclSpecs* specs,
    533                                     const Type* ty, int is_function,
    534                                     int is_member);
    535 
    536 /* parse_expr.c */
    537 void parse_expr(Parser* p);
    538 void parse_assign_expr(Parser* p);
    539 void parse_cond_expr(Parser* p);
    540 void parse_unary(Parser* p);
    541 typedef struct CConstInt {
    542   const Type* type;
    543   u64 lo;
    544   u64 hi;
    545 } CConstInt;
    546 CConstInt eval_const_int_typed(Parser* p, SrcLoc loc);
    547 i64 eval_const_int(Parser* p, SrcLoc loc);
    548 i64 const_int_as_i64(Parser* p, CConstInt v);
    549 i64 parse_int_literal(Parser* p, const Tok* t);
    550 double parse_float_literal(Parser* p, const Tok* t);
    551 i64 decode_char_literal(Parser* p, const Tok* t);
    552 const Type* char_literal_type(Parser* p, const Tok* t);
    553 const Type* string_literal_elem_type(Parser* p, const Tok* t);
    554 int string_literal_initializes_array(Parser* p, const Type* elem, const Tok* t);
    555 u8* decode_string_literal(Parser* p, const Tok* t, size_t* nlen_out);
    556 void to_rvalue(Parser* p);
    557 void coerce_top_to_lvalue(Parser* p);
    558 void coerce_top_to_type(Parser* p, const Type* dst);
    559 KitCgSym emit_string_to_rodata(Parser* p, const u8* bytes, size_t n);
    560 KitCgSym emit_string_literal_to_rodata(Parser* p, const u8* bytes,
    561                                        size_t nbytes, const Type* elem_ty);
    562 
    563 /* parse_init.c */
    564 void init_at(Parser* p, FrameSlot slot, const Type* arr_ty, u32 offset,
    565              const Type* ty);
    566 void parse_static_init_at(Parser* p, u8* buf, u32 buflen, u32 offset,
    567                           const Type* ty);
    568 void define_static_object(Parser* p, ObjSymId sym, ObjSecId section_id,
    569                           const Type* var_ty, u16 quals, int has_init,
    570                           SrcLoc loc, u32 align_override);
    571 void srl_push(Parser* p, u32 offset, u32 size, ObjSymId target, i64 addend);
    572 void srl_push_label(Parser* p, u32 offset, u32 size, CGLabel label, i64 addend);
    573 void encode_int_le(u8* dst, u32 size, i64 v);
    574 void push_subobject_lv(Parser* p, FrameSlot slot, const Type* arr_ty,
    575                        u32 offset, const Type* elem_ty);
    576 void emit_struct_copy_into_slot(Parser* p, FrameSlot dst_slot,
    577                                 const Type* dst_arr_ty, u32 dst_off,
    578                                 const Type* ty);
    579 int is_char_kind(const Type* ty);
    580 
    581 /* parse_stmt.c */
    582 void parse_stmt(Parser* p);
    583 void parse_compound_stmt(Parser* p);
    584 void parse_static_assert(Parser* p);
    585 GotoLabel* label_get_or_create(Parser* p, Sym name, SrcLoc loc);
    586 /* Records that `name`'s address is taken (GNU labels-as-values) and returns
    587  * its CG label. Used by both `&&label` expressions and static initializers. */
    588 CGLabel take_label_addr(Parser* p, Sym name, SrcLoc loc);
    589 
    590 /* parse.c (residual — TU driver) */
    591 void parse_param_list(Parser* p, ParamInfo** infos_out, u16* nparams_out,
    592                       u8* variadic_out);
    593 void parse_local_decl(Parser* p, const DeclSpecs* specs);
    594 FrameSlot make_local(Parser* p, Sym name, const Type* type, SrcLoc loc);
    595 FrameSlot make_local_aligned(Parser* p, Sym name, const Type* type, SrcLoc loc,
    596                              u32 align_override);
    597 Sym mint_static_local_sym(Parser* p, Sym orig);
    598 void record_braced_block(Parser* p);
    599 void replay_rewind(Parser* p);
    600 u32 count_recorded_top_level_items(const Tok* vec, u32 len);