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);