parse_priv.h (24044B)
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 <kit/support/hashmap.h> 10 #include <kit/support/symtab.h> 11 #include <stdarg.h> 12 #include <string.h> 13 14 #include "abi/c_abi.h" 15 #include "decl/decl.h" 16 #include "decl/decl_attrs.h" 17 #include "lex/lex.h" 18 #include "parse/attr.h" 19 #include "parse/parse.h" 20 #include "pp/pp.h" 21 #include "sem/sem.h" 22 #include "type/type.h" 23 24 /* ============================================================ 25 * Keywords 26 * ============================================================ */ 27 typedef enum CKw { 28 KW_NONE = 0, 29 KW_AUTO, 30 KW_BREAK, 31 KW_CASE, 32 KW_CHAR, 33 KW_CONST, 34 KW_CONTINUE, 35 KW_DEFAULT, 36 KW_DO, 37 KW_DOUBLE, 38 KW_ELSE, 39 KW_ENUM, 40 KW_EXTERN, 41 KW_FLOAT, 42 KW_FLOAT16, /* _Float16 */ 43 KW_FOR, 44 KW_GOTO, 45 KW_IF, 46 KW_INLINE, 47 KW_INT, 48 KW_LONG, 49 KW_REGISTER, 50 KW_RESTRICT, 51 KW_RETURN, 52 KW_SHORT, 53 KW_SIGNED, 54 KW_SIZEOF, 55 KW_STATIC, 56 KW_STRUCT, 57 KW_SWITCH, 58 KW_TYPEDEF, 59 KW_UNION, 60 KW_UNSIGNED, 61 KW_VOID, 62 KW_VOLATILE, 63 KW_WHILE, 64 KW_BOOL, /* _Bool */ 65 KW_COMPLEX, /* _Complex */ 66 KW_IMAGINARY, /* _Imaginary */ 67 KW_ALIGNAS, /* _Alignas */ 68 KW_ALIGNOF, /* _Alignof */ 69 KW_ATOMIC, /* _Atomic */ 70 KW_GENERIC, /* _Generic */ 71 KW_NORETURN, /* _Noreturn */ 72 KW_STATIC_ASSERT, /* _Static_assert */ 73 KW_THREAD_LOCAL, /* _Thread_local */ 74 KW_ASM, /* GNU `asm` */ 75 KW_BUILTIN_ASM, /* GNU `__asm__` */ 76 KW_COUNT 77 } CKw; 78 79 /* ============================================================ 80 * Scope stack types 81 * ============================================================ */ 82 83 typedef enum SymEntryKind { 84 SEK_LOCAL, /* local variable or parameter source handle */ 85 SEK_GLOBAL, /* global var, OPK_GLOBAL via ObjSymId */ 86 SEK_FUNC, /* function decl, OPK_GLOBAL via ObjSymId */ 87 SEK_TYPEDEF, /* typedef name */ 88 SEK_ENUM_CST, /* enumeration constant */ 89 } SymEntryKind; 90 91 typedef struct SymEntry SymEntry; 92 typedef struct VLABound VLABound; 93 typedef struct StaticReloc StaticReloc; 94 struct VLABound { 95 const Type* array_ty; 96 FrameSlot byte_slot; 97 FrameSlot count_slot; 98 VLABound* next; 99 }; 100 101 typedef struct ParamVLABoundExpr ParamVLABoundExpr; 102 struct ParamVLABoundExpr { 103 Tok* toks; 104 u32 ntoks; 105 u8 has_expr; 106 u8 pad[3]; 107 }; 108 109 struct StaticReloc { 110 u32 offset; 111 u32 size; 112 ObjSymId target; /* symbol target when is_label == 0 */ 113 i64 addend; 114 CGLabel label; /* label target when is_label != 0 */ 115 u8 is_label; /* 1 -> label-address reloc (&&label), 0 -> symbol reloc */ 116 u8 pad[3]; 117 }; 118 119 struct SymEntry { 120 Sym name; 121 u8 kind; /* SymEntryKind */ 122 u8 defined; /* compatibility alias for decl_state >= DSTATE_DEFINED */ 123 u8 decl_state; 124 u8 storage; /* DeclStorage */ 125 u8 linkage; /* DeclLinkage */ 126 u8 pad[3]; 127 DeclId decl_id; 128 u32 decl_flags; 129 const Type* type; 130 union { 131 FrameSlot slot; 132 ObjSymId sym; 133 i64 enum_value; 134 } v; 135 FrameSlot vla_byte_slot; 136 VLABound* vla_bounds; 137 struct Attr* attrs; 138 /* For a `register T x __asm__("reg")` local: the interned hard-register name 139 * ("r10", "x8", ...) the variable is bound to. Pins x to that register when 140 * used as an inline-asm operand (GNU explicit register variables). 0 = none. 141 */ 142 Sym reg_asm_name; 143 SymEntry* next; 144 /* The binding that was current for this entry's name (in the innermost 145 * visible scope) at the moment this entry was defined; 0 = none. The 146 * Sym-keyed BindingTab cache on Parser restores bind[name] = shadowed when 147 * this entry's scope is popped, so scope_lookup is one array load instead of 148 * a scope-chain walk. memset-0 by scope_define/_checked, so default is NULL. 149 */ 150 SymEntry* shadowed; 151 }; 152 153 typedef struct TagEntry TagEntry; 154 struct TagEntry { 155 Sym name; 156 u8 kind; /* TagDeclKind */ 157 u8 complete; 158 u16 pad; 159 Type* type; 160 struct Attr* attrs; 161 TagEntry* next; 162 }; 163 164 /* Name -> entry indexes, keyed on the interned Sym (Sym 0 = "none" doubles as 165 * the hashmap empty sentinel). Each scope keeps its LIFO list as the source of 166 * truth and ordering, and lazily builds an index once it grows past 167 * SCOPE_INDEX_THRESHOLD, so the O(n^2) "scan the whole scope per declaration" 168 * cost (file scopes with thousands of globals/typedefs, functions with 169 * thousands of locals) collapses to O(1) average lookups while tiny block 170 * scopes stay on the cheap linear list. The maps allocate through the pool's 171 * shared arena-heap facade (Pool.arena_heap) so there is nothing to free. */ 172 KIT_HASHMAP_DEFINE(SymEntryMap, Sym, SymEntry*, kit_hash_u32); 173 KIT_HASHMAP_DEFINE(TagEntryMap, Sym, TagEntry*, kit_hash_u32); 174 KIT_HASHMAP_DEFINE(ExternalFuncMap, Sym, SymEntry*, kit_hash_u32); 175 176 /* Interned keyword/alias Sym -> CKw (stored as u8), built once in parse_c. 177 * Sym-indexed dense table: classifying an identifier is one in-range load, 178 * no hashing. Most identifiers in a body are interned after the keyword set 179 * (higher Sym than kw_cap), so they classify as KW_NONE without even a load. 180 * Storage comes from the pool's shared arena-heap facade (Pool.arena_heap). */ 181 KIT_SYMTAB_DEFINE(KwTab, u8); 182 183 /* Interned identifier Sym -> the SymEntry currently visible for that name (the 184 * innermost binding a scope-chain walk would return), or NULL when unbound. 185 * scope_define/_checked maintain it (newest define wins, prior saved in 186 * SymEntry.shadowed); scope_pop unwinds it. Lets scope_lookup be a single 187 * in-range load instead of a per-nesting-level scope_entries_find walk. Storage 188 * comes from the pool's shared arena-heap facade (Pool.arena_heap). */ 189 KIT_SYMTAB_DEFINE(BindingTab, SymEntry*); 190 191 typedef struct Scope Scope; 192 struct Scope { 193 SymEntry* entries; /* LIFO */ 194 TagEntry* tags; /* LIFO */ 195 Scope* parent; 196 u32 saved_vla_mark; 197 u32 nentries; /* count in `entries`; index built once it exceeds threshold */ 198 u32 ntags; /* count in `tags`; index built once it exceeds threshold */ 199 SymEntryMap emap; /* name -> entry; active (cap != 0) once built */ 200 TagEntryMap tmap; /* name -> tag; active (cap != 0) once built */ 201 }; 202 203 /* ============================================================ 204 * Switch/goto control-flow types 205 * ============================================================ */ 206 207 typedef struct CaseEntry CaseEntry; 208 struct CaseEntry { 209 i64 value; 210 CGLabel label; 211 CaseEntry* next; 212 }; 213 214 typedef struct SwitchCtx SwitchCtx; 215 struct SwitchCtx { 216 CaseEntry* cases; 217 CGLabel default_label; 218 FrameSlot value_slot; 219 const Type* value_type; 220 SwitchCtx* parent; 221 }; 222 223 typedef struct GotoLabel GotoLabel; 224 struct GotoLabel { 225 Sym name; 226 CGLabel label; 227 u8 placed; 228 u8 addr_taken; /* set when &&label is used (labels-as-values) */ 229 u8 pad[2]; 230 SrcLoc first_use; 231 u32 min_forward_vla_mark; 232 u32 label_vla_mark; 233 GotoLabel* next; 234 }; 235 236 /* ============================================================ 237 * Parser context 238 * ============================================================ */ 239 240 typedef struct Parser { 241 Compiler* c; 242 Pp* pp; 243 DeclTable* decls; 244 CG* cg; 245 KitCompiler* abi; 246 Pool* pool; 247 u8 default_visibility; /* SymVis */ 248 u8 auto_var_init; /* KitAutoVarInit: implicit init for uninit locals */ 249 u8 general_regs_only; /* -mgeneral-regs-only: reject C FP constructs */ 250 u8 stack_protector_mode; /* KitStackProtectorMode */ 251 u8 stack_protector_enabled; /* selected current function */ 252 u8 stack_protector_scan; /* semantic selection-only body pass */ 253 u8 stack_protector_scan_selected; 254 u8 stack_protector_preselected; 255 256 Tok cur; 257 Tok next; 258 int has_next; 259 260 Tok pending; 261 int has_pending; 262 263 Sym kw_sym[KW_COUNT]; 264 KwTab kw_map; /* keyword/alias Sym -> CKw; built once, see ident_kw_inline */ 265 266 Sym sym_b_alloca; 267 Sym sym_b_ctz; 268 Sym sym_b_ctzl; 269 Sym sym_b_ctzll; 270 Sym sym_b_clz; 271 Sym sym_b_clzl; 272 Sym sym_b_clzll; 273 Sym sym_b_trap; 274 Sym sym_b_unreachable; 275 Sym sym_b_memcpy; 276 Sym sym_b_memmove; 277 Sym sym_b_memcmp; 278 Sym sym_b_memset; 279 Sym sym_b_clear_cache; 280 Sym sym_b_isnan; 281 Sym sym_b_fabs; 282 Sym sym_b_fabsf; 283 Sym sym_b_fabsl; 284 Sym sym_b_inf; 285 Sym sym_b_inff; 286 Sym sym_b_infl; 287 Sym sym_b_huge_val; 288 Sym sym_b_huge_valf; 289 Sym sym_b_huge_vall; 290 Sym sym_b_nan; /* __builtin_nan */ 291 Sym sym_b_nanf; /* __builtin_nanf */ 292 Sym sym_b_nanl; /* __builtin_nanl */ 293 Sym sym_b_isless; /* __builtin_isless */ 294 Sym sym_b_islessequal; /* __builtin_islessequal */ 295 Sym sym_b_isgreater; /* __builtin_isgreater */ 296 Sym sym_b_isgreaterequal; /* __builtin_isgreaterequal */ 297 Sym sym_b_islessgreater; /* __builtin_islessgreater */ 298 Sym sym_b_isunordered; /* __builtin_isunordered */ 299 Sym sym_func; /* __func__ */ 300 Sym sym_func_gcc; /* __FUNCTION__ */ 301 Sym sym_pretty_func_gcc; /* __PRETTY_FUNCTION__ */ 302 Sym cur_func_name; /* name of the function whose body we're in, 303 * 0 at file scope */ 304 u8 cur_func_emits; /* the current function body is being emitted (a CG 305 * func was begun); 0 for whole-body-suppressed 306 * `extern inline` definitions. Distinct from the 307 * momentary `suppress_codegen` counter: goto labels 308 * persist across the whole body, so their CG-label 309 * ids must be real whenever the function emits, even 310 * if the first reference is in a transiently 311 * suppressed (constant-false) region. */ 312 const Type* cur_func_ret; 313 Sym sym_b_expect; 314 Sym sym_b_offsetof; 315 Sym sym_b_constant_p; /* __builtin_constant_p */ 316 Sym sym_b_va_list; 317 /* Cached singleton for __builtin_va_list — built lazily on first 318 * mention so every occurrence resolves to the same Type* (and the 319 * same TagId where applicable). Without the cache, c_abi_va_list_type 320 * mints a fresh struct type per occurrence and headers that pass 321 * locally-declared __builtin_va_list values to functions taking 322 * va_list (e.g. mingw's sec_api/stdio_s.h) fail type-equality. */ 323 const Type* type_b_va_list; 324 Sym sym_b_va_start; 325 Sym sym_b_va_arg; 326 Sym sym_b_va_end; 327 Sym sym_b_va_copy; 328 Sym sym_b_return_address; /* __builtin_return_address */ 329 Sym sym_b_frame_address; /* __builtin_frame_address */ 330 Sym sym_b_readcyclecounter; /* __builtin_readcyclecounter */ 331 Sym sym_kit_syscall[7]; /* __kit_syscall0 .. __kit_syscall6 */ 332 Sym sym_attribute; 333 Sym sym_volatile_alias; 334 Sym sym_alignof_alias; 335 Sym sym_typeof_alias; /* __typeof */ 336 Sym sym_typeof_alias2; /* __typeof__ */ 337 Sym sym_asm_alias; 338 Sym sym_inline_alias; 339 Sym sym_inline_alias2; 340 Sym sym_restrict_alias; 341 Sym sym_restrict_alias2; 342 Sym sym_thread_alias; 343 Sym sym_int128; /* __int128 */ 344 Sym sym_int128_t; /* __int128_t */ 345 Sym sym_uint128_t; /* __uint128_t */ 346 Sym sym_a_load_n; 347 Sym sym_a_store_n; 348 Sym sym_a_exchange_n; 349 Sym sym_a_fetch_add; 350 Sym sym_a_fetch_sub; 351 Sym sym_a_fetch_and; 352 Sym sym_a_fetch_or; 353 Sym sym_a_fetch_xor; 354 Sym sym_a_fetch_nand; 355 Sym sym_a_cas_n; 356 Sym sym_a_always_lock_free; 357 Sym sym_a_is_lock_free; 358 Sym sym_a_thread_fence; 359 Sym sym_a_signal_fence; 360 Sym sym_sync_synchronize; /* __sync_synchronize (legacy full barrier) */ 361 362 Scope* scope; 363 /* Sym -> innermost-visible binding cache; the O(1) read side of scope_lookup. 364 * Maintained by scope_define/_checked (write) and scope_pop (restore). */ 365 BindingTab bind; 366 /* name -> current file-scope function entry. Replaces what was an O(n) linear 367 * list walked on every function declaration/reference. Storage comes from the 368 * pool's shared arena-heap facade (Pool.arena_heap). */ 369 ExternalFuncMap external_funcs; 370 371 CGLabel cur_break; 372 CGLabel cur_continue; 373 374 SwitchCtx* cur_switch; 375 376 GotoLabel* goto_labels; 377 /* Set once a computed `goto *expr;` has been emitted in the current 378 * function. After this point taking a new label's address with `&&label` 379 * is rejected, because each computed goto's target set is finalized when 380 * it is emitted and a later address-taken label would not be in it. */ 381 u8 computed_goto_emitted; 382 383 u8 vla_pending; 384 FrameSlot vla_pending_count_slot; 385 FrameSlot vla_pending_count_slots[8]; 386 u8 vla_pending_count_len; 387 u32 vla_mark; 388 389 FrameSlot last_pushed_vla_slot; 390 VLABound* last_pushed_vla_bounds; 391 392 u8 in_param_decl; 393 ParamVLABoundExpr param_vla_bounds[8]; 394 u8 param_vla_bound_len; 395 u32 suppress_codegen; 396 397 u32 const_guard_depth; 398 u32 const_guard_not_eval; 399 const char* const_guard_error; 400 SrcLoc const_guard_error_loc; 401 402 u32 static_local_counter; 403 404 u32 compound_literal_counter; 405 406 Tok* replay; 407 u32 replay_cap; 408 u32 replay_len; 409 u32 replay_pos; 410 u8 replay_active; 411 412 /* A function body is buffered once for the stack-protector selection pass 413 * and replayed through the ordinary parser. This is distinct from `replay`, 414 * which initializer/type parsing may nest while consuming the body. */ 415 Tok* function_replay; 416 u32 function_replay_len; 417 u32 function_replay_pos; 418 u8 function_replay_active; 419 u8 function_replay_hold; 420 421 StaticReloc* static_relocs; 422 u32 static_relocs_len; 423 u32 static_relocs_cap; 424 } Parser; 425 426 /* ============================================================ 427 * DeclSpecs and TypeSpecAccum 428 * ============================================================ */ 429 430 typedef struct DeclSpecs { 431 const Type* type; 432 DeclStorage storage; 433 u32 flags; /* DeclFlag */ 434 u16 quals; 435 u8 storage_explicit; 436 u8 pad; 437 u32 align; 438 FrameSlot vla_byte_slot; 439 VLABound* vla_bounds; 440 Attr* attrs; 441 } DeclSpecs; 442 443 typedef struct TypeSpecAccum { 444 u8 saw_void; 445 u8 saw_char; 446 u8 saw_int; 447 u8 saw_short; 448 u8 long_count; 449 u8 saw_signed; 450 u8 saw_unsigned; 451 u8 saw_bool; 452 u8 saw_float; 453 u8 saw_double; 454 u8 saw_int128; /* __int128 / __int128_t / __uint128_t */ 455 u8 saw_explicit_type; 456 } TypeSpecAccum; 457 458 /* ============================================================ 459 * Shared token/diagnostic helpers (defined in parse.c) 460 * ============================================================ */ 461 462 _Noreturn void perr(Parser* p, const char* fmt, ...); 463 void reject_general_regs_only_fp(Parser* p, const char* what); 464 void advance(Parser* p); 465 Tok peek1(Parser* p); 466 void expect_punct(Parser* p, u32 punct, const char* what); 467 int accept_punct(Parser* p, u32 punct); 468 469 /* ============================================================ 470 * Scope/tag ops (defined in parse.c) 471 * ============================================================ */ 472 473 Scope* scope_new(Parser* p, Scope* parent); 474 void scope_push(Parser* p); 475 void scope_pop(Parser* p); 476 SymEntry* scope_define(Parser* p, Sym name, SymEntryKind kind, 477 const Type* type); 478 SymEntry* scope_lookup_current(Parser* p, Sym name); 479 SymEntry* scope_lookup(Parser* p, Sym name); 480 TagEntry* tag_define(Parser* p, Sym name, TagDeclKind kind, Type* type, 481 int complete); 482 TagEntry* tag_lookup(Parser* p, Sym name); 483 TagEntry* tag_lookup_local(Parser* p, Sym name); 484 485 /* ============================================================ 486 * Token predicate helpers (defined in parse.c — file-scope static, 487 * exposed here as inline equivalents; each .c file sees its own copy) 488 * ============================================================ */ 489 490 static inline int is_punct(const Tok* t, u32 punct) { 491 return t->kind == TOK_PUNCT && tok_punct(t) == punct; 492 } 493 494 static inline int is_pp_hash(const Tok* t) { return t->kind == TOK_PP_HASH; } 495 496 /* THE keyword classifier — the single canonical way keywordness is decided. 497 * Interned Sym -> CKw via kw_map; KW_NONE if the Sym is not a keyword. The map 498 * holds the canonical keyword spellings AND the GNU alias spellings 499 * (`__inline__` etc.), each mapping to its CKw, registered once in the kw_map 500 * population in parse_c — so aliases are classified identically to their 501 * canonical keyword, with no separate "alias-aware" path. Everything below (and 502 * the per-token classify_kw / is_kw adapters) routes through this. */ 503 static inline CKw ident_kw_inline(const Parser* p, Sym name) { 504 return name ? (CKw)KwTab_get(&p->kw_map, name) : KW_NONE; 505 } 506 507 /* A token's keyword identity (KW_NONE for a non-identifier or non-keyword). The 508 * one place to classify a Tok: classify once, then compare CKw. */ 509 static inline CKw classify_kw(const Parser* p, const Tok* t) { 510 return t->kind == TOK_IDENT ? ident_kw_inline(p, tok_ident(t)) : KW_NONE; 511 } 512 513 /* Is token t the keyword k? Thin boolean shape-adapter over classify_kw. */ 514 static inline int is_kw(const Parser* p, const Tok* t, CKw k) { 515 return classify_kw(p, t) == k; 516 } 517 518 static inline int c_type_is_scalar(const Type* ty) { 519 return type_is_arith(ty) || type_is_ptr(ty); 520 } 521 522 /* ============================================================ 523 * Shared types (needed across multiple modules) 524 * ============================================================ */ 525 526 typedef struct ParamInfo { 527 Sym name; 528 const Type* type; 529 const Type* declared_type; 530 SrcLoc loc; 531 ParamVLABoundExpr* vla_bounds; 532 u8 vla_bound_len; 533 } ParamInfo; 534 535 /* ============================================================ 536 * Declarator suffix types (defined in parse_type.c, shared here) 537 * ============================================================ */ 538 539 typedef enum DSuffKind { DS_ARRAY, DS_FUNC } DSuffKind; 540 typedef struct DeclSuffix { 541 u8 kind; /* DSuffKind */ 542 u32 count; /* element count; meaningful when !vla and !incomplete */ 543 u8 incomplete; /* true for `[]` (no size given) */ 544 u8 vla; /* true for `[expr]` with a non-constant size */ 545 FrameSlot vla_count_slot; 546 ParamInfo* params; 547 u16 nparams; 548 u8 variadic; 549 } DeclSuffix; 550 551 typedef struct DeclaratorInfo { 552 ParamInfo* fn_params; 553 u16 fn_nparams; 554 u8 fn_variadic; 555 Sym asm_label; 556 } DeclaratorInfo; 557 558 /* ============================================================ 559 * Cross-module forward declarations 560 * ============================================================ */ 561 562 /* parse_type.c */ 563 564 int parse_decl_specs(Parser* p, DeclSpecs* out); 565 const Type* parse_struct_or_union(Parser* p, TypeKind kind, 566 Attr** anon_attrs_out); 567 const Type* parse_enum(Parser* p, Attr** anon_attrs_out); 568 const Type* resolve_type_specs(Parser* p, const TypeSpecAccum* a, SrcLoc loc); 569 const Type* parse_type_name(Parser* p); 570 const Type* parse_pointer_layer(Parser* p, const Type* base); 571 const Type* parse_declarator_full(Parser* p, const Type* base, 572 int allow_abstract, Sym* name_out, 573 SrcLoc* loc_out); 574 const Type* parse_declarator_full_ex(Parser* p, const Type* base, 575 int allow_abstract, Sym* name_out, 576 SrcLoc* loc_out, Attr** attrs_out); 577 const Type* parse_declarator_full_info(Parser* p, const Type* base, 578 int allow_abstract, Sym* name_out, 579 SrcLoc* loc_out, Attr** attrs_out, 580 DeclaratorInfo* info_out); 581 const Type* parse_declarator(Parser* p, const Type* base, Sym* name_out, 582 SrcLoc* loc_out); 583 const Type* complete_incomplete_array(Parser* p, const Type* ty); 584 int starts_type_name(const Parser* p, const Tok* t); 585 int starts_attr(const Parser* p); 586 Attr* parse_attribute_spec_list(Parser* p); 587 void parse_and_discard_attributes(Parser* p); 588 int find_field(KitCompiler* abi, Pool* pool, const Type* rec, Sym name, 589 const Type** out_type, u32* out_offset, const Field** out_field); 590 u32 attrs_pick_aligned(const Attr* a); 591 void attr_list_append(Attr** head, Attr* add); 592 void parse_attrs_into(Parser* p, Attr** sink); 593 int parse_decl_suffix(Parser* p, DeclSuffix* out); 594 const Type* apply_decl_suffix(Parser* p, const Type* base, const DeclSuffix* s); 595 void validate_decl_type_constraints(Parser* p, const DeclSpecs* specs, 596 const Type* ty, int is_function, 597 int is_member); 598 599 /* parse_expr.c */ 600 void parse_expr(Parser* p); 601 void parse_assign_expr(Parser* p); 602 void parse_cond_expr(Parser* p); 603 void parse_unary(Parser* p); 604 void c_const_guard_not_eval_push(Parser* p); 605 void c_const_guard_not_eval_pop(Parser* p); 606 typedef struct CConstInt { 607 const Type* type; 608 u64 lo; 609 u64 hi; 610 } CConstInt; 611 CConstInt eval_const_int_typed(Parser* p, SrcLoc loc); 612 i64 eval_const_int(Parser* p, SrcLoc loc); 613 i64 const_int_as_i64(Parser* p, CConstInt v); 614 i64 parse_int_literal(Parser* p, const Tok* t); 615 double parse_float_literal(Parser* p, const Tok* t); 616 i64 decode_char_literal(Parser* p, const Tok* t); 617 const Type* char_literal_type(Parser* p, const Tok* t); 618 const Type* string_literal_elem_type(Parser* p, const Tok* t); 619 int string_literal_initializes_array(Parser* p, const Type* elem, const Tok* t); 620 u8* decode_string_literal(Parser* p, const Tok* t, size_t* nlen_out); 621 void to_rvalue(Parser* p); 622 void coerce_top_to_lvalue(Parser* p); 623 void coerce_top_to_type(Parser* p, const Type* dst); 624 KitCgSym emit_string_to_rodata(Parser* p, const u8* bytes, size_t n); 625 KitCgSym emit_string_literal_to_rodata(Parser* p, const u8* bytes, 626 size_t nbytes, const Type* elem_ty); 627 628 /* parse_init.c */ 629 void init_at(Parser* p, FrameSlot slot, const Type* arr_ty, u32 offset, 630 const Type* ty); 631 void zero_init_at(Parser* p, FrameSlot slot, const Type* arr_ty, u32 offset, 632 const Type* ty); 633 /* Zero a whole sub-object with a single kit_cg_memset, instead of recursing to 634 * one scalar store per leaf. Correct for any type (all-zero bytes is the zero 635 * value of every C type on supported targets) and avoids O(leaves^2) blowup on 636 * large aggregates. */ 637 void zero_object_bytes_at(Parser* p, FrameSlot slot, const Type* arr_ty, 638 u32 offset, const Type* ty); 639 void parse_static_init_at(Parser* p, u8* buf, u32 buflen, u32 offset, 640 const Type* ty); 641 void define_static_object(Parser* p, ObjSymId sym, ObjSecId section_id, 642 const Type* var_ty, u16 quals, int has_init, 643 SrcLoc loc, u32 align_override); 644 void srl_push(Parser* p, u32 offset, u32 size, ObjSymId target, i64 addend); 645 void srl_push_label(Parser* p, u32 offset, u32 size, CGLabel label, i64 addend); 646 void encode_int_le(u8* dst, u32 size, i64 v); 647 void push_subobject_lv(Parser* p, FrameSlot slot, const Type* arr_ty, 648 u32 offset, const Type* elem_ty); 649 void emit_struct_copy_into_slot(Parser* p, FrameSlot dst_slot, 650 const Type* dst_arr_ty, u32 dst_off, 651 const Type* ty); 652 int is_char_kind(const Type* ty); 653 654 /* parse_stmt.c */ 655 void parse_stmt(Parser* p); 656 void parse_compound_stmt(Parser* p); 657 void parse_static_assert(Parser* p); 658 GotoLabel* label_get_or_create(Parser* p, Sym name, SrcLoc loc); 659 /* Records that `name`'s address is taken (GNU labels-as-values) and returns 660 * its CG label. Used by both `&&label` expressions and static initializers. */ 661 CGLabel take_label_addr(Parser* p, Sym name, SrcLoc loc); 662 663 /* parse.c (residual — TU driver) */ 664 void parse_param_list(Parser* p, ParamInfo** infos_out, u16* nparams_out, 665 u8* variadic_out); 666 void parse_local_decl(Parser* p, const DeclSpecs* specs); 667 FrameSlot make_local(Parser* p, Sym name, const Type* type, SrcLoc loc); 668 FrameSlot make_local_aligned(Parser* p, Sym name, const Type* type, SrcLoc loc, 669 u32 align_override); 670 void c_stack_protector_enable(Parser* p); 671 void c_stack_protector_note_type(Parser* p, const Type* type); 672 void c_stack_protector_note_address(Parser* p); 673 Sym mint_static_local_sym(Parser* p, Sym orig); 674 void record_braced_block(Parser* p); 675 void replay_rewind(Parser* p); 676 u32 count_recorded_top_level_items(const Tok* vec, u32 len);