pp.c (52007B)
1 /* C11 preprocessor (translation phase 4). 2 * 3 * Streams tokens via pp_next: directives are consumed, macro invocations are 4 * expanded, and TOK_NEWLINE is preserved so pp_emit_text can reconstruct the 5 * line structure of the source. 6 * 7 * The token-source stack carries either a Lexer (file or #include'd file) or 8 * a pre-built Tok[] buffer (macro expansion). A macro replacement-list buffer 9 * is a "disabled frame" (cpplib model): while it is live on the source stack 10 * its owning macro's disabled_depth is non-zero, so a recursive occurrence of 11 * that macro during rescan is returned permanently un-expanded (TF_NO_EXPAND) 12 * rather than re-replaced. This replaces the per-token Prosser hideset. 13 * 14 * Residual module: source stack, pp_next / pp_next_raw (public streaming), 15 * pp_new/free, predefined macros, lifecycle, keyword interning. */ 16 17 #include <kit/compile.h> 18 #include <kit/source.h> 19 20 #include "pp/pp_priv.h" 21 22 /* ============================================================ 23 * Source stack 24 * ============================================================ */ 25 26 static TokSrc* src_top(Pp* pp) { 27 return pp->nsources ? &pp->sources[pp->nsources - 1] : NULL; 28 } 29 30 void src_push(Pp* pp, TokSrc s) { 31 if (pp->nsources == pp->sources_cap) { 32 u32 nc = pp->sources_cap ? pp->sources_cap * 2 : 8; 33 pp->sources = 34 (TokSrc*)pp_xrealloc(pp, pp->sources, sizeof(TokSrc) * pp->sources_cap, 35 sizeof(TokSrc) * nc, _Alignof(TokSrc)); 36 pp->sources_cap = nc; 37 } 38 pp->sources[pp->nsources++] = s; 39 } 40 41 void src_pop(Pp* pp) { 42 TokSrc* t; 43 if (!pp->nsources) return; 44 t = &pp->sources[pp->nsources - 1]; 45 /* Re-enable the macro whose replacement-list frame this is (cpplib 46 * disabled-frame model): popping the frame ends the rescan during which the 47 * macro was unavailable. Balances the increment in push_buf_uniform/replay. */ 48 if (t->disabled_owner) --t->disabled_owner->disabled_depth; 49 if (t->kind == SRC_LEX && t->lex) { 50 /* Commit the multiple-include memo for this file before closing it: a 51 * fully #ifndef-wrapped file records its controlling macro; a #pragma once 52 * file records the once flag. A later #include of the same resolved path 53 * then skips re-lexing it entirely (see do_include). */ 54 if (t->path_key && pp->inc_cache_ready) { 55 IncEntry* e = IncCache_get(&pp->inc_cache, t->path_key); 56 if (e) { 57 if (t->once) e->once = 1; 58 if (t->guard_state == GUARD_AFTER && t->guard_macro) 59 e->guard = t->guard_macro; 60 } 61 } 62 lex_close(t->lex); 63 t->lex = NULL; 64 } 65 --pp->nsources; 66 } 67 68 /* Synthesize a lean EOF token into *out. */ 69 static void tok_eof(Tok* out) { 70 out->kind = TOK_EOF; 71 out->flags = 0; 72 out->aux = 0; 73 out->loc = (LocRef){0, 0}; 74 out->text = (TextRef){TEXT_NONE, 0, 0, 0}; 75 } 76 77 /* Read next raw token from the top source, writing it through `out`. Sets 78 * *out to TOK_EOF when the stack is empty. Pops empty buffer/lexer sources 79 * as it descends. `src_kind_out`, if non-NULL, receives the kind of the 80 * source the token came from (SRC_LEX vs SRC_BUF). Used by pp_next_raw to 81 * gate directive recognition to lex-sourced tokens only — a `#` produced by 82 * macro expansion never starts a directive (§6.10.3.4 ¶3). */ 83 void src_next_raw_into(Pp* pp, Tok* out, u8* src_kind_out) { 84 TokSrc* s; 85 while ((s = src_top(pp)) != NULL) { 86 if (s->kind == SRC_BUF) { 87 if (s->i < s->n) { 88 *out = s->toks[s->i]; 89 if (src_kind_out) *src_kind_out = SRC_BUF; 90 /* Pointer-replayed body: apply the per-invocation loc and (first token 91 * only) BOL/SPACE flags the old fresh-copy path baked in. */ 92 if (s->has_loc_override) { 93 if (s->i == 0) { 94 out->flags = (u16)((out->flags & ~(TF_AT_BOL | TF_HAS_SPACE)) | 95 s->first_flags_or); 96 } 97 out->loc = s->loc_override; 98 } 99 ++s->i; 100 return; 101 } 102 if (s->scope_top) { 103 tok_eof(out); 104 if (src_kind_out) *src_kind_out = SRC_BUF; 105 return; 106 } 107 src_pop(pp); 108 continue; 109 } 110 /* SRC_LEX */ 111 lex_next(s->lex, out); 112 if (out->kind == TOK_EOF) { 113 if (pp->nsources > 1) { 114 src_pop(pp); 115 continue; 116 } 117 if (src_kind_out) *src_kind_out = SRC_LEX; 118 return; 119 } 120 /* Multiple-include-guard detection: real code before the opening guard 121 * directive, or after the controlling #endif, disqualifies the whole-file 122 * #ifndef guard. A newline is whitespace and a beginning-of-line `#` is a 123 * directive introducer — both transparent; anything else is content. */ 124 if (!pp->reading_directive && 125 (s->guard_state == GUARD_START || s->guard_state == GUARD_AFTER) && 126 out->kind != TOK_NEWLINE && 127 !(out->kind == TOK_PP_HASH && (out->flags & TF_AT_BOL))) { 128 s->guard_state = GUARD_FAILED; 129 } 130 /* #line numbering is no longer applied here: a lean token carries only a 131 * byte offset, and the #line delta is recorded as a positional overlay 132 * segment (see pp_add_line_seg) applied lazily by pp_materialize_loc. */ 133 if (src_kind_out) *src_kind_out = SRC_LEX; 134 return; 135 } 136 tok_eof(out); 137 if (src_kind_out) *src_kind_out = SRC_LEX; 138 } 139 140 /* Thin by-value shim for the cold/general callers (arg collection, paren 141 * peek) that pass a NULL src_kind and don't sit in the hot -E loop. */ 142 Tok src_next_raw(Pp* pp, u8* src_kind_out) { 143 Tok t; 144 src_next_raw_into(pp, &t, src_kind_out); 145 return t; 146 } 147 148 /* ============================================================ 149 * Buffer source push helpers 150 * ============================================================ */ 151 152 /* Push a non-macro buffer source (pushed-back peek tokens, a #pragma / #embed 153 * payload, an arg-prescan scope). No disabled frame: these payloads do not 154 * disable any macro during their rescan. */ 155 void push_buf(Pp* pp, Tok* toks, u32 n) { 156 TokSrc s; 157 memset(&s, 0, sizeof(s)); 158 s.kind = SRC_BUF; 159 s.toks = toks; 160 s.i = 0; 161 s.n = n; 162 src_push(pp, s); 163 } 164 165 /* Push a macro replacement-list buffer (function-like substituted body, paste 166 * result). `owner` is the macro being expanded: marking the frame with it and 167 * incrementing owner->disabled_depth makes the macro unavailable for the whole 168 * rescan of this replacement (cpplib disabled-frame model); src_pop decrements 169 * it. Set the owner on `s` BEFORE src_push (which copies by value); the 170 * increment lands on the macro itself, which is fine. */ 171 void push_buf_uniform(Pp* pp, Tok* toks, u32 n, Macro* owner) { 172 TokSrc s; 173 memset(&s, 0, sizeof(s)); 174 s.kind = SRC_BUF; 175 s.toks = toks; 176 s.i = 0; 177 s.n = n; 178 s.disabled_owner = owner; 179 if (owner) ++owner->disabled_depth; 180 src_push(pp, s); 181 } 182 183 /* Push an immutable token buffer (a no-`##` macro body) for pointer-replay. 184 * The const-cast on `toks` is sound: replay is strictly read-only — the two 185 * read sites (src_next_raw_into, the pp_pull_into fast path) load each token by 186 * value and never write back through s->toks. The per-read loc/flags override 187 * (has_loc_override) reproduces the mutations the old fresh-copy path baked in, 188 * so the shared body is surfaced byte-for-byte without copying it. */ 189 void push_buf_replay(Pp* pp, const Tok* toks, u32 n, Macro* owner, 190 LocRef loc_override, u16 first_flags_or) { 191 TokSrc s; 192 memset(&s, 0, sizeof(s)); 193 s.kind = SRC_BUF; 194 s.toks = (Tok*)toks; 195 s.has_loc_override = 1; 196 s.loc_override = loc_override; 197 s.first_flags_or = first_flags_or; 198 s.i = 0; 199 s.n = n; 200 s.disabled_owner = owner; 201 if (owner) ++owner->disabled_depth; 202 src_push(pp, s); 203 } 204 205 /* ============================================================ 206 * Public streaming entries 207 * ============================================================ */ 208 209 void pp_next_parse(Pp* pp, Tok* out) { 210 /* Public parser-feed stream: filter newlines so consumers like the C parser 211 * don't need to handle them. pp_emit_text uses pp_next_raw via its own loop. 212 * 213 * The top-of-loop read uses pp_next_into, which already drops non-directive 214 * newlines internally; the peek-after-hash (t2) and pragma-swallow reads 215 * below stay on pp_next_raw because they must still see a TOK_NEWLINE (as a 216 * non-pragma push-back token, and as the swallow terminator). 217 * 218 * Also drop forwarded `#pragma` lines: do_pragma pushes the directive back 219 * onto the source stack so pp_emit_text can re-emit it verbatim in cpp mode, 220 * but the C parser (cc mode) would see the trailing tokens as stray 221 * identifiers. When we see TOK_PP_HASH followed by `pragma`, swallow tokens 222 * through the next NEWLINE. */ 223 for (;;) { 224 Tok t; 225 pp_next_into(pp, &t); 226 if (t.kind == TOK_PP_HASH) { 227 Tok t2; 228 pp_next_raw(pp, &t2); 229 if (t2.kind == TOK_IDENT && tok_ident(&t2) == pp->sym_pragma) { 230 for (;;) { 231 Tok tt; 232 pp_next_raw(pp, &tt); 233 if (tt.kind == TOK_NEWLINE || tt.kind == TOK_EOF) break; 234 } 235 continue; 236 } 237 /* Not a pragma — push the peeked token back as a 1-element buffer 238 * so the next pp_next_raw returns it, and surface the hash now. */ 239 Tok* keep = arena_array(pp->xarena, Tok, 1); 240 keep[0] = t2; 241 push_buf(pp, keep, 1); 242 *out = t; 243 return; 244 } 245 *out = t; 246 return; 247 } 248 } 249 250 /* ============================================================ 251 * pp_emit_text 252 * ============================================================ */ 253 254 /* Stage output bytes into a caller buffer, flushing to the Writer only when it 255 * fills (or for a pathologically long spelling). Collapses the former ~2 256 * indirect kit_writer_write calls per token — each a function-pointer call into 257 * a tiny memcpy — into one bulk write per buffer-full. (fdw_write keeps its own 258 * 64 KB buffer; this second cheap staging layer removes the per-token call + 259 * bounds-check, not redundant copying of the bulk.) */ 260 static void pp_emit_stage(Writer* out, char* buf, size_t cap, size_t* on, 261 const char* s, size_t n) { 262 if (!n) return; 263 if (n > cap) { 264 if (*on) { 265 (void)kit_writer_write(out, buf, *on); 266 *on = 0; 267 } 268 (void)kit_writer_write(out, s, n); 269 return; 270 } 271 if (*on + n > cap) { 272 (void)kit_writer_write(out, buf, *on); 273 *on = 0; 274 } 275 memcpy(buf + *on, s, n); 276 *on += n; 277 } 278 279 void pp_emit_text(Pp* pp, Writer* out) { 280 char obuf[16384]; 281 size_t on = 0; 282 int at_bol = 1; 283 for (;;) { 284 Tok t; 285 KitSlice s; 286 pp_next_raw(pp, &t); 287 if (t.kind == TOK_EOF) break; 288 if (t.kind == TOK_NEWLINE) { 289 pp_emit_stage(out, obuf, sizeof obuf, &on, "\n", 1); 290 at_bol = 1; 291 continue; 292 } 293 if (!at_bol && (t.flags & (TF_HAS_SPACE | TF_AT_BOL))) { 294 /* TF_AT_BOL on a non-leading output token means the source 295 * had a line break here that the line-tracking cursor isn't 296 * preserving — fall back to a single space so the tokens 297 * don't run together. */ 298 pp_emit_stage(out, obuf, sizeof obuf, &on, " ", 1); 299 } 300 s = pp_text_slice(pp, &t); 301 if (s.len) pp_emit_stage(out, obuf, sizeof obuf, &on, s.s, s.len); 302 at_bol = 0; 303 } 304 if (on) (void)kit_writer_write(out, obuf, on); 305 } 306 307 /* ============================================================ 308 * SrcInfo registry — lazy loc + retained text 309 * ============================================================ */ 310 311 SrcInfo* pp_srcinfo(Pp* pp, u32 file_id) { 312 if (file_id >= pp->srcinfo_cap) { 313 u32 nc = pp->srcinfo_cap ? pp->srcinfo_cap * 2 : 16; 314 while (nc <= file_id) nc *= 2; 315 pp->srcinfo = (SrcInfo*)pp_xrealloc( 316 pp, pp->srcinfo, sizeof(SrcInfo) * pp->srcinfo_cap, 317 sizeof(SrcInfo) * nc, _Alignof(SrcInfo)); 318 memset(pp->srcinfo + pp->srcinfo_cap, 0, 319 sizeof(SrcInfo) * (nc - pp->srcinfo_cap)); 320 pp->srcinfo_cap = nc; 321 } 322 return &pp->srcinfo[file_id]; 323 } 324 325 void pp_register_srcinfo(Pp* pp, Lexer* lex) { 326 u32 fid = lex_file_id(lex); 327 SrcInfo* si = pp_srcinfo(pp, fid); 328 u32 nspl = 0; 329 si->buf = lex_buf(lex); 330 si->len = lex_buf_len(lex); 331 si->owns_buf = (u8)lex_owns_buf(lex); 332 si->splices = (u32*)lex_splices(lex, &nspl); 333 si->nsplices = nspl; 334 si->shebang_off = lex_shebang_off(lex); 335 si->line_built = 0; 336 si->line_off = NULL; 337 si->nlines = 0; 338 si->line_cursor = 0; 339 si->segs = NULL; 340 si->nsegs = 0; 341 si->segs_cap = 0; 342 /* PP now owns the buffer + splice table; the lexer must not free them. */ 343 lex_disown_buf(lex); 344 } 345 346 void pp_add_line_seg(Pp* pp, u32 file_id, u32 off, i32 delta, Sym file) { 347 SrcInfo* si = pp_srcinfo(pp, file_id); 348 if (si->nsegs == si->segs_cap) { 349 u32 nc = si->segs_cap ? si->segs_cap * 2 : 4; 350 si->segs = 351 (LineSeg*)pp_xrealloc(pp, si->segs, sizeof(LineSeg) * si->segs_cap, 352 sizeof(LineSeg) * nc, _Alignof(LineSeg)); 353 si->segs_cap = nc; 354 } 355 si->segs[si->nsegs].off = off; 356 si->segs[si->nsegs].delta = delta; 357 si->segs[si->nsegs].file = file; 358 ++si->nsegs; 359 } 360 361 /* Build the physical line-start index for a source by replaying the lexer's 362 * line accounting over the (immutable, fully-folded) buffer. A line-break event 363 * has a "trigger" offset equal to the line_start it establishes: a '\n' at 364 * offset p triggers at p+1; a folded splice at offset s triggers at s. The 365 * lexer processes both in scan order, so the sorted multiset of triggers, 366 * prefixed by line 1's origin (shebang_off, else 0), reproduces line/col 367 * exactly: line(off) = 1 + count(triggers <= off); col = off - origin + 1. */ 368 static void srcinfo_build_lines(Pp* pp, SrcInfo* si) { 369 const char* b = si->buf; 370 const char* e = b + si->len; 371 const char* p; 372 const char* nl; 373 u32 nnl = 0, k, sp; 374 u32* lo; 375 /* Count newlines via memchr (NEON-accelerated) rather than a scalar byte 376 * loop — this build is the one-time cost paid the first time a loc in this 377 * source is materialized. */ 378 for (p = b; (nl = (const char*)memchr(p, '\n', (size_t)(e - p))) != NULL;) 379 ++nnl, p = nl + 1; 380 { 381 u32 cap = 1u + nnl + si->nsplices; 382 lo = (u32*)pp_xrealloc(pp, NULL, 0, sizeof(u32) * cap, _Alignof(u32)); 383 } 384 k = 0; 385 lo[k++] = si->shebang_off; 386 sp = 0; 387 for (p = b; (nl = (const char*)memchr(p, '\n', (size_t)(e - p))) != NULL;) { 388 u32 nlv = (u32)(nl - b) + 1u; 389 while (sp < si->nsplices && si->splices[sp] < nlv) 390 lo[k++] = si->splices[sp++]; 391 lo[k++] = nlv; 392 p = nl + 1; 393 } 394 while (sp < si->nsplices) lo[k++] = si->splices[sp++]; 395 si->line_off = lo; 396 si->nlines = k; 397 si->line_cursor = 0; 398 si->line_built = 1; 399 } 400 401 /* Largest index k in line_off[0..n) with line_off[k] <= off (n >= 1). */ 402 static u32 line_index(const u32* lo, u32 n, u32 off) { 403 u32 a = 0, b = n; 404 while (a < b) { 405 u32 m = a + (b - a) / 2u; 406 if (lo[m] <= off) 407 a = m + 1u; 408 else 409 b = m; 410 } 411 return a ? a - 1u : 0u; 412 } 413 414 /* Cursored line lookup: loc materialization walks the source in near-monotonic 415 * byte order (the parser advances forward), so the previously-returned line is 416 * almost always the answer or one step behind. Hit-in-line and short forward 417 * runs are O(1); a far forward jump or any backward jump falls back to the 418 * binary search. Updates the cursor for the next call. */ 419 static u32 line_index_cursored(SrcInfo* si, u32 off) { 420 const u32* lo = si->line_off; 421 u32 n = si->nlines; 422 u32 c = si->line_cursor; 423 if (c >= n) c = 0; 424 if (lo[c] <= off) { 425 if (c + 1u >= n || off < lo[c + 1u]) 426 return c; /* same line — the hot case */ 427 { 428 u32 step = 0; 429 while (c + 1u < n && lo[c + 1u] <= off && step < 8u) ++c, ++step; 430 if (c + 1u < n && lo[c + 1u] <= off) c = line_index(lo, n, off); 431 } 432 } else { 433 c = line_index(lo, n, off); /* backward jump */ 434 } 435 si->line_cursor = c; 436 return c; 437 } 438 439 static i32 seg_delta_at(const SrcInfo* si, u32 off) { 440 i32 d = 0; 441 u32 i; 442 for (i = 0; i < si->nsegs; ++i) { 443 if (si->segs[i].off <= off) 444 d = si->segs[i].delta; 445 else 446 break; 447 } 448 return d; 449 } 450 451 static Sym seg_file_at(const SrcInfo* si, u32 off) { 452 Sym f = 0; 453 u32 i; 454 for (i = 0; i < si->nsegs; ++i) { 455 if (si->segs[i].off <= off) 456 f = si->segs[i].file; 457 else 458 break; 459 } 460 return f; 461 } 462 463 SrcLoc pp_materialize_loc(Pp* pp, LocRef loc) { 464 SrcLoc r; 465 SrcInfo* si; 466 u32 k; 467 r.file_id = loc.file_id; 468 r.line = 0; 469 r.col = 0; 470 if (!loc.file_id) return r; 471 si = pp_srcinfo(pp, loc.file_id); 472 if (!si->buf) return r; 473 if (!si->line_built) srcinfo_build_lines(pp, si); 474 k = line_index_cursored(si, loc.off); 475 r.line = (u32)((i32)(k + 1u) + seg_delta_at(si, loc.off)); 476 r.col = loc.off - si->line_off[k] + 1u; 477 return r; 478 } 479 480 u32 pp_phys_line(Pp* pp, LocRef loc) { 481 SrcInfo* si; 482 if (!loc.file_id) return 0; 483 si = pp_srcinfo(pp, loc.file_id); 484 if (!si->buf) return 0; 485 if (!si->line_built) srcinfo_build_lines(pp, si); 486 return line_index(si->line_off, si->nlines, loc.off) + 1u; 487 } 488 489 Sym pp_materialize_file(Pp* pp, LocRef loc) { 490 SrcInfo* si; 491 Sym f; 492 KitSourceFile sf; 493 if (!loc.file_id) return 0; 494 si = pp_srcinfo(pp, loc.file_id); 495 f = si->buf ? seg_file_at(si, loc.off) : 0; 496 if (f) return f; 497 if (kit_source_file(pp->c, loc.file_id, &sf) == KIT_OK) return sf.name; 498 return 0; 499 } 500 501 /* ============================================================ 502 * Text materialization 503 * ============================================================ */ 504 505 KitSlice pp_text_slice(Pp* pp, const Tok* t) { 506 KitSlice s; 507 switch (t->text.kind) { 508 case TEXT_SRC: { 509 SrcInfo* si = pp_srcinfo(pp, t->text.file_id); 510 s.s = si->buf + t->text.off; 511 s.len = t->text.len_or_sym; 512 return s; 513 } 514 case TEXT_SYM: 515 return kit_sym_str(pp->pool->c, (Sym)t->text.len_or_sym); 516 default: /* TEXT_NONE: a canonical punctuator reconstructs from its code */ 517 if (t->kind == TOK_PUNCT || t->kind == TOK_PP_HASH || 518 t->kind == TOK_PP_PASTE) { 519 u32 n; 520 s.s = punct_canon(t->aux, &n); 521 s.len = n; 522 return s; 523 } 524 s.s = ""; 525 s.len = 0; 526 return s; 527 } 528 } 529 530 Sym pp_text_intern(Pp* pp, const Tok* t) { 531 if (t->text.kind == TEXT_SYM) return (Sym)t->text.len_or_sym; 532 return kit_sym_intern(pp->pool->c, pp_text_slice(pp, t)); 533 } 534 535 int pp_text_eq_cstr(Pp* pp, const Tok* t, const char* s) { 536 KitSlice sl = pp_text_slice(pp, t); 537 size_t n = s ? strlen(s) : 0; 538 return sl.len == n && (n == 0 || memcmp(sl.s, s, n) == 0); 539 } 540 541 /* ============================================================ 542 * Lifecycle and configuration 543 * ============================================================ */ 544 545 static void pp_intern_keywords(Pp* pp) { 546 Pool* p = pp->pool; 547 pp->sym_define = kit_sym_intern(p->c, KIT_SLICE_LIT("define")); 548 pp->sym_undef = kit_sym_intern(p->c, KIT_SLICE_LIT("undef")); 549 pp->sym_include = kit_sym_intern(p->c, KIT_SLICE_LIT("include")); 550 pp->sym_include_next = kit_sym_intern(p->c, KIT_SLICE_LIT("include_next")); 551 pp->sym_assembler = kit_sym_intern(p->c, KIT_SLICE_LIT("__ASSEMBLER__")); 552 pp->sym_has_include = kit_sym_intern(p->c, KIT_SLICE_LIT("__has_include")); 553 pp->sym_has_include_next = 554 kit_sym_intern(p->c, KIT_SLICE_LIT("__has_include_next")); 555 pp->sym_if = kit_sym_intern(p->c, KIT_SLICE_LIT("if")); 556 pp->sym_ifdef = kit_sym_intern(p->c, KIT_SLICE_LIT("ifdef")); 557 pp->sym_ifndef = kit_sym_intern(p->c, KIT_SLICE_LIT("ifndef")); 558 pp->sym_elif = kit_sym_intern(p->c, KIT_SLICE_LIT("elif")); 559 pp->sym_else = kit_sym_intern(p->c, KIT_SLICE_LIT("else")); 560 pp->sym_endif = kit_sym_intern(p->c, KIT_SLICE_LIT("endif")); 561 pp->sym_line = kit_sym_intern(p->c, KIT_SLICE_LIT("line")); 562 pp->sym_pragma = kit_sym_intern(p->c, KIT_SLICE_LIT("pragma")); 563 pp->sym_once = kit_sym_intern(p->c, KIT_SLICE_LIT("once")); 564 pp->sym_pragma_kw = pp->sym_pragma; 565 pp->sym_error = kit_sym_intern(p->c, KIT_SLICE_LIT("error")); 566 pp->sym_warning = kit_sym_intern(p->c, KIT_SLICE_LIT("warning")); 567 pp->sym_embed = kit_sym_intern(p->c, KIT_SLICE_LIT("embed")); 568 pp->sym_defined = kit_sym_intern(p->c, KIT_SLICE_LIT("defined")); 569 pp->sym_va_args = kit_sym_intern(p->c, KIT_SLICE_LIT("__VA_ARGS__")); 570 pp->sym_line__ = kit_sym_intern(p->c, KIT_SLICE_LIT("__LINE__")); 571 pp->sym_file__ = kit_sym_intern(p->c, KIT_SLICE_LIT("__FILE__")); 572 pp->sym_date__ = kit_sym_intern(p->c, KIT_SLICE_LIT("__DATE__")); 573 pp->sym_time__ = kit_sym_intern(p->c, KIT_SLICE_LIT("__TIME__")); 574 pp->sym_stdc__ = kit_sym_intern(p->c, KIT_SLICE_LIT("__STDC__")); 575 pp->sym_stdc_hosted__ = 576 kit_sym_intern(p->c, KIT_SLICE_LIT("__STDC_HOSTED__")); 577 pp->sym_stdc_version__ = 578 kit_sym_intern(p->c, KIT_SLICE_LIT("__STDC_VERSION__")); 579 pp->sym__pragma = kit_sym_intern(p->c, KIT_SLICE_LIT("_Pragma")); 580 } 581 582 /* Decompose unix seconds into UTC y/M/d/h/m/s. Algorithm: Howard Hinnant, 583 * "chrono-compatible Low-Level Date Algorithms" (civil_from_days). Valid 584 * for any int64 input; uses floor division so negative epoch values 585 * (pre-1970) work correctly. */ 586 typedef struct PpYMD { 587 int y; /* full year, e.g. 2026 */ 588 int M; /* 1..12 */ 589 int d; /* 1..31 */ 590 int h; /* 0..23 */ 591 int m; /* 0..59 */ 592 int s; /* 0..59 */ 593 } PpYMD; 594 595 static void pp_break_time(int64_t t, PpYMD* out) { 596 int64_t days, secs; 597 int64_t z, era, doe, yoe, y, doy, mp, d, mo; 598 /* Floor-divide t by 86400. */ 599 days = t / 86400; 600 secs = t - days * 86400; 601 if (secs < 0) { 602 secs += 86400; 603 days -= 1; 604 } 605 out->h = (int)(secs / 3600); 606 out->m = (int)((secs / 60) % 60); 607 out->s = (int)(secs % 60); 608 609 z = days + 719468; /* shift to era starting 0000-03-01 */ 610 era = (z >= 0 ? z : z - 146096) / 146097; 611 doe = z - era * 146097; /* [0,146096] */ 612 yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; /* [0,399] */ 613 y = yoe + era * 400; 614 doy = doe - (365 * yoe + yoe / 4 - yoe / 100); /* [0,365] */ 615 mp = (5 * doy + 2) / 153; /* [0,11], Mar=0 */ 616 d = doy - (153 * mp + 2) / 5 + 1; /* [1,31] */ 617 mo = mp + (mp < 10 ? 3 : -9); /* [1,12] */ 618 y += (mo <= 2); 619 out->y = (int)y; 620 out->M = (int)mo; 621 out->d = (int)d; 622 } 623 624 /* Compute __DATE__ and __TIME__ from env->now (unix seconds, host-supplied; 625 * negative means "no clock"). Per C11 §6.10.8.1: __DATE__ is "Mmm dd yyyy" 626 * (dd is space-padded if < 10), __TIME__ is "hh:mm:ss". Both quoted. */ 627 static void compute_date_time(Pp* pp) { 628 static const char* mons[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 629 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; 630 char date[24]; 631 char tm[16]; 632 int64_t t = kit_compiler_context(pp->c)->now; 633 PpYMD ymd; 634 if (t < 0) { 635 pp->val_date_str = 636 kit_sym_intern(pp->pool->c, KIT_SLICE_LIT("\"??? ?? ????\"")); 637 pp->val_time_str = 638 kit_sym_intern(pp->pool->c, KIT_SLICE_LIT("\"??:??:??\"")); 639 return; 640 } 641 pp_break_time(t, &ymd); 642 { 643 int dd = ymd.d, yyyy = ymd.y; 644 int p = 0; 645 date[p++] = '"'; 646 memcpy(date + p, mons[ymd.M - 1], 3); 647 p += 3; 648 date[p++] = ' '; 649 date[p++] = (dd >= 10) ? (char)('0' + dd / 10) : ' '; 650 date[p++] = (char)('0' + dd % 10); 651 date[p++] = ' '; 652 date[p++] = (char)('0' + (yyyy / 1000) % 10); 653 date[p++] = (char)('0' + (yyyy / 100) % 10); 654 date[p++] = (char)('0' + (yyyy / 10) % 10); 655 date[p++] = (char)('0' + (yyyy) % 10); 656 date[p++] = '"'; 657 pp->val_date_str = 658 kit_sym_intern(pp->pool->c, (KitSlice){.s = date, .len = (size_t)p}); 659 } 660 { 661 int hh = ymd.h, mm = ymd.m, ss = ymd.s; 662 int p = 0; 663 tm[p++] = '"'; 664 tm[p++] = (char)('0' + (hh / 10) % 10); 665 tm[p++] = (char)('0' + hh % 10); 666 tm[p++] = ':'; 667 tm[p++] = (char)('0' + (mm / 10) % 10); 668 tm[p++] = (char)('0' + mm % 10); 669 tm[p++] = ':'; 670 tm[p++] = (char)('0' + (ss / 10) % 10); 671 tm[p++] = (char)('0' + ss % 10); 672 tm[p++] = '"'; 673 pp->val_time_str = 674 kit_sym_intern(pp->pool->c, (KitSlice){.s = tm, .len = (size_t)p}); 675 } 676 } 677 678 static void pp_register_static_predefined(Pp* pp) { 679 pp_define(pp, "__kit__", "1"); 680 pp_define(pp, "__kit_major__", "0"); 681 pp_define(pp, "__kit_minor__", "0"); 682 pp_define(pp, "__kit_patchlevel__", "0"); 683 pp_define(pp, "__STDC__", "1"); 684 pp_define(pp, "__STDC_HOSTED__", "0"); 685 pp_define(pp, "__STDC_VERSION__", "201112L"); 686 /* C11 memory_order constants used by __atomic_* builtins. Values match the 687 * `MemOrder` enum in src/arch/arch.h so eval_const_int -> MemOrder is a 688 * direct cast. */ 689 pp_define(pp, "__ATOMIC_RELAXED", "0"); 690 pp_define(pp, "__ATOMIC_CONSUME", "1"); 691 pp_define(pp, "__ATOMIC_ACQUIRE", "2"); 692 pp_define(pp, "__ATOMIC_RELEASE", "3"); 693 pp_define(pp, "__ATOMIC_ACQ_REL", "4"); 694 pp_define(pp, "__ATOMIC_SEQ_CST", "5"); 695 /* GNU `__extension__` is a pedantic-quiet prefix on non-standard constructs 696 * (statement exprs, anonymous structs, `long long` in C89, ...). kit's parser 697 * is permissive about those already and the keyword has no effect on parsing, 698 * so erase it. Needed on every OS, not just mingw: glibc's headers (e.g. 699 * <stdlib.h>'s `__extension__ typedef struct { ... } lldiv_t;`) use it 700 * pervasively, and musl's cleaner ISO-C headers simply never tripped it. */ 701 pp_define(pp, "__extension__", ""); 702 /* GCC keyword spellings of the C qualifiers/`signed`. GNU libc and the Linux 703 * kernel UAPI headers use these directly in GCC mode (e.g. 704 * <asm-generic/int-ll64.h>'s `typedef __signed__ char __s8;`). kit parses the 705 * canonical keywords; map the GCC spellings onto them. (`__restrict` is 706 * additionally a parser keyword alias for the configs that #undef the macro.) 707 */ 708 pp_define(pp, "__volatile__", "volatile"); 709 pp_define(pp, "__const__", "const"); 710 pp_define(pp, "__signed__", "signed"); 711 } 712 713 /* OS-keyed predefined macros: the single place to extend per operating system. 714 * Each OS arm owns its full set of OS-specific predefines (including the 715 * arch-specific MSVC machine macros, which are an OS-flavor concern, not a 716 * data-model one). Add a new `case` to support another OS personality; the 717 * data-model / type-width macros stay in pp_register_target_predefined since 718 * they are OS-independent. */ 719 static void pp_register_os_predefined(Pp* pp, KitTargetSpec target) { 720 switch (target.os) { 721 case KIT_OS_WINDOWS: 722 /* Windows / mingw predefined macros. kit targets the mingw 723 * flavor (DWARF debug info, mingwex CRT) rather than MSVC, so we 724 * advertise __MINGW{32,64}__ and friends but never set _MSC_VER. 725 * Both _WIN32 and the legacy unprefixed WIN32 are defined; _WIN64 726 * is set on 64-bit targets only. The MSVC-compat machine macros 727 * (_M_X64 / _M_AMD64 / _M_ARM64) are useful for headers that gate 728 * on them but harmless to set everywhere — mingw's own headers 729 * tolerate them. */ 730 pp_define(pp, "_WIN32", "1"); 731 pp_define(pp, "WIN32", "1"); 732 pp_define(pp, "__MINGW32__", "1"); 733 if (target.ptr_size == 8) { 734 pp_define(pp, "_WIN64", "1"); 735 pp_define(pp, "__MINGW64__", "1"); 736 } 737 if (target.arch == KIT_ARCH_X86_64) { 738 pp_define(pp, "_M_X64", "100"); 739 pp_define(pp, "_M_AMD64", "100"); 740 } else if (target.arch == KIT_ARCH_ARM_64) { 741 pp_define(pp, "_M_ARM64", "1"); 742 } 743 /* mingw's <vadefs.h> / many CRT headers gate __builtin_va_list / 744 * __gnuc_va_list on __GNUC__. kit implements the va_* builtins 745 * and __builtin_va_list with the GCC contract, so impersonating a 746 * conservative GCC vintage lets the mingw header tree compile. 747 * We pick 4.0 — old enough that no header expects GCC-specific 748 * extensions kit doesn't implement (e.g. transactional memory, 749 * GIMPLE plugins), but new enough to clear every __GNUC__ >= N 750 * gate we've seen in practice. */ 751 pp_define(pp, "__GNUC__", "4"); 752 pp_define(pp, "__GNUC_MINOR__", "0"); 753 pp_define(pp, "__GNUC_PATCHLEVEL__", "0"); 754 /* __has_builtin / __has_attribute / __has_include_next: clang/GCC 755 * preprocessor extensions. mingw's _mingw.h gates inline-asm 756 * intrinsic definitions on whether the compiler claims to have 757 * them as builtins (e.g. __debugbreak, __fastfail, __prefetch). 758 * kit doesn't model individual builtin lookups; claim "yes" 759 * uniformly so mingw skips its inline-asm fallbacks (which use 760 * intel/{$}-form asm syntax kit's parser doesn't accept). */ 761 pp_define(pp, "__has_builtin(x)", "1"); 762 pp_define(pp, "__has_feature(x)", "0"); 763 pp_define(pp, "__has_attribute(x)", "0"); 764 /* MSVC fixed-width integer types. mingw's corecrt.h uses these 765 * directly (e.g. `typedef unsigned __int64 size_t;`). Map to the 766 * C standard equivalents. */ 767 pp_define(pp, "__int8", "char"); 768 pp_define(pp, "__int16", "short"); 769 pp_define(pp, "__int32", "int"); 770 pp_define(pp, "__int64", "long long"); 771 /* mingw's psdk_inc/intrin-impl.h emits an inline implementation 772 * for every MSVC intrinsic (_lrotl, _BitScanForward, ...) and 773 * gates them with __INTRINSIC_PROLOG, which uses ## to paste the 774 * intrinsic's name into a `defined(__INTRINSIC_DEFINED_<name>)` 775 * test. Once an intrinsic gets defined, a later re-invocation of 776 * the same gate macro hits a kit pp bug where a *defined* 777 * symbol referenced inside `defined()` gets expanded before the 778 * `defined` operator captures it. Predefining 779 * __INTRINSIC_ONLYSPECIAL flips the gate's second clause so 780 * none of the inline intrinsics are emitted (mingw expects this 781 * idiom for non-special builds; the linker pulls them from 782 * libmingwex/libmsvcrt instead). This sidesteps the pp bug 783 * entirely. */ 784 pp_define(pp, "__INTRINSIC_ONLYSPECIAL", "1"); 785 /* __declspec(...) is the MSVC syntax for attributes. mingw uses 786 * it in headers for dllimport/dllexport, alignment, noreturn, 787 * etc. kit's COFF linker routes externs through the IAT 788 * regardless of the dllimport hint and doesn't yet model 789 * dllexport via this attribute — so we erase it as a no-op 790 * macro. (Note: this is at the preprocessor layer; the parser 791 * still needs to handle the syntax if/when the macro is removed.) 792 */ 793 pp_define(pp, "__declspec(x)", ""); 794 /* __extension__ is erased unconditionally in 795 * pp_register_static_predefined. */ 796 /* __restrict / __restrict__: GCC-flavored alternates to the C99 797 * `restrict` keyword. kit parses `restrict` already; map the 798 * GCC spellings onto it. */ 799 pp_define(pp, "__restrict", "restrict"); 800 pp_define(pp, "__restrict__", "restrict"); 801 /* __volatile__/__const__/__signed__ erased->canonical unconditionally in 802 * pp_register_static_predefined (GNU spellings glibc/UAPI headers use). 803 */ 804 /* MSVC calling-convention attributes. On x86_64 they're no-ops 805 * (every function uses the Win64 ABI) and on ARM64 likewise; on 806 * i386 they actually mean something but kit doesn't target it. 807 * Defining them as empty macros lets mingw headers that say 808 * `void __cdecl foo(void)` parse correctly. Same posture mingw's 809 * own GCC takes: __MINGW_USYMBOL((__cdecl__)). */ 810 /* MSVC calling-convention attributes — no-ops on Win64. kit 811 * pre-defines them empty *only when* mingw's headers don't 812 * themselves redefine them; we use the __MINGW_<x>_REDEFINE form 813 * via `#undef` first to play nicely with mingw's own 814 * redefinitions (mingw's _mingw.h does `#define __cdecl 815 * __attribute__((__cdecl__))` further down). Setting them empty 816 * here is safe because kit's parser will see the redefinition 817 * before any header uses them. */ 818 pp_define(pp, "__cdecl", ""); 819 pp_define(pp, "__stdcall", ""); 820 pp_define(pp, "__fastcall", ""); 821 pp_define(pp, "__thiscall", ""); 822 pp_define(pp, "__vectorcall", ""); 823 pp_define(pp, "_cdecl", ""); 824 pp_define(pp, "_stdcall", ""); 825 pp_define(pp, "_fastcall", ""); 826 /* __forceinline / __inline / __w64: mingw's _mingw.h redefines 827 * them itself when __GNUC__ is set, so we leave them alone here 828 * to avoid a redefinition-with-different-replacement error. */ 829 break; 830 case KIT_OS_LINUX: 831 case KIT_OS_ANDROID: 832 case KIT_OS_MACOS: 833 case KIT_OS_IOS: 834 case KIT_OS_IOS_SIMULATOR: 835 case KIT_OS_FREEBSD: 836 case KIT_OS_FREESTANDING: 837 case KIT_OS_WASI: 838 /* No OS-specific predefines beyond the shared data-model set. */ 839 break; 840 } 841 } 842 843 /* Target-dependent predefined macros consumed by rt/include/stddef.h and 844 * rt/include/stdint.h. The set mirrors the subset of GCC/Clang's __*_TYPE__ 845 * / __*_MAX__ namespace that those headers reference. We split only on 846 * pointer width plus the target data model: LP64 for Unix-like 64-bit targets, 847 * LLP64 for 64-bit Windows, and ILP32 for 32-bit targets. */ 848 static void pp_register_target_predefined(Pp* pp) { 849 KitTargetSpec target = kit_compiler_target_spec(pp->c); 850 const KitPredefinedMacro* arch_defs = NULL; 851 uint32_t narch_defs = kit_compiler_arch_predefines(pp->c, &arch_defs); 852 uint32_t i; 853 int ptr64 = (target.ptr_size == 8); 854 int lp64 = kit_target_uses_lp64(target); 855 /* sizeof(wchar_t) is a resolved data-model fact carried on the spec. */ 856 int wchar16 = (target.wchar_size == 2); 857 858 for (i = 0; i < narch_defs; ++i) { 859 pp_define(pp, arch_defs[i].name.s, arch_defs[i].body.s); 860 } 861 862 /* Float-ABI-dependent arch macros (e.g. RISC-V __riscv_float_abi_* / 863 * __riscv_flen) come from a separate getter because the static table above 864 * can encode only one float profile; these track the resolved float ABI. */ 865 { 866 const KitPredefinedMacro* fp_defs = NULL; 867 uint32_t nfp_defs = kit_compiler_arch_float_predefines(pp->c, &fp_defs); 868 for (i = 0; i < nfp_defs; ++i) { 869 pp_define(pp, fp_defs[i].name.s, fp_defs[i].body.s); 870 } 871 } 872 873 /* Feature-keyed arch macros (e.g. ARM's __ARM_ARCH_7M__ vs __ARM_ARCH_7EM__, 874 * __ARM_FEATURE_DSP) come from a separate getter because the static table 875 * above can encode only one extension profile; these track the resolved 876 * -march/-mcpu/-mattr feature words. */ 877 { 878 const KitPredefinedMacro* feat_defs = NULL; 879 uint32_t nfeat_defs = kit_compiler_arch_feature_predefines(pp->c, &feat_defs); 880 for (i = 0; i < nfeat_defs; ++i) { 881 pp_define(pp, feat_defs[i].name.s, feat_defs[i].body.s); 882 } 883 } 884 885 /* __USER_LABEL_PREFIX__ is the C source-symbol prefix the object format 886 * prepends ("_" for Mach-O, "" else); read it from the CG target rather 887 * than re-deriving from the object-format identity. */ 888 pp_define(pp, "__USER_LABEL_PREFIX__", kit_cg_target_c_label_prefix(pp->c)); 889 890 /* Byte / type sizes. kit uses a single LP64 (or ILP32) model across 891 * every supported target: int=4, short=2, long-long=8, float=4, double=8, 892 * long-double=8 (sharing the double representation — see the 893 * __LDBL_* block below). long and pointer-derived types track ptr_size. 894 * These macros let portable C code probe widths without first pulling in 895 * <limits.h> / <stddef.h>. */ 896 pp_define(pp, "__CHAR_BIT__", "8"); 897 pp_define(pp, "__SIZEOF_SHORT__", "2"); 898 pp_define(pp, "__SIZEOF_INT__", "4"); 899 pp_define(pp, "__SIZEOF_LONG__", lp64 ? "8" : "4"); 900 pp_define(pp, "__SIZEOF_LONG_LONG__", "8"); 901 pp_define(pp, "__SIZEOF_POINTER__", ptr64 ? "8" : "4"); 902 pp_define(pp, "__SIZEOF_SIZE_T__", ptr64 ? "8" : "4"); 903 pp_define(pp, "__SIZEOF_PTRDIFF_T__", ptr64 ? "8" : "4"); 904 pp_define(pp, "__SIZEOF_WCHAR_T__", wchar16 ? "2" : "4"); 905 pp_define(pp, "__SIZEOF_WINT_T__", "4"); 906 pp_define(pp, "__SIZEOF_FLOAT__", "4"); 907 pp_define(pp, "__SIZEOF_DOUBLE__", "8"); 908 pp_define(pp, "__SIZEOF_LONG_DOUBLE__", 909 kit_target_long_double_is_binary128(target) ? "16" : "8"); 910 911 /* OS-specific predefines (Windows/mingw + MSVC machine macros) live in one 912 * os-keyed table — pp_register_os_predefined — so adding an OS personality 913 * touches a single place. Emitted here, between the data-model size macros 914 * and the stddef.h type aliases, to preserve the predefined-macro ordering. 915 */ 916 pp_register_os_predefined(pp, target); 917 918 /* stddef.h base aliases */ 919 if (lp64) { 920 pp_define(pp, "__SIZE_TYPE__", "unsigned long"); 921 pp_define(pp, "__PTRDIFF_TYPE__", "long"); 922 } else if (ptr64) { 923 pp_define(pp, "__SIZE_TYPE__", "unsigned long long"); 924 pp_define(pp, "__PTRDIFF_TYPE__", "long long"); 925 } else { 926 pp_define(pp, "__SIZE_TYPE__", "unsigned int"); 927 pp_define(pp, "__PTRDIFF_TYPE__", "int"); 928 } 929 pp_define(pp, "__WCHAR_TYPE__", wchar16 ? "unsigned short" : "int"); 930 pp_define(pp, "__CHAR16_TYPE__", "unsigned short"); 931 pp_define(pp, "__CHAR32_TYPE__", "unsigned int"); 932 933 /* stdint.h exact-width aliases (widths <= 32 are model-independent) */ 934 pp_define(pp, "__INT8_TYPE__", "signed char"); 935 pp_define(pp, "__INT16_TYPE__", "short"); 936 pp_define(pp, "__INT32_TYPE__", "int"); 937 pp_define(pp, "__UINT8_TYPE__", "unsigned char"); 938 pp_define(pp, "__UINT16_TYPE__", "unsigned short"); 939 pp_define(pp, "__UINT32_TYPE__", "unsigned int"); 940 pp_define(pp, "__INT64_TYPE__", lp64 ? "long" : "long long"); 941 pp_define(pp, "__UINT64_TYPE__", 942 lp64 ? "unsigned long" : "unsigned long long"); 943 944 /* Least-width == exact-width on every target kit knows about */ 945 pp_define(pp, "__INT_LEAST8_TYPE__", "signed char"); 946 pp_define(pp, "__INT_LEAST16_TYPE__", "short"); 947 pp_define(pp, "__INT_LEAST32_TYPE__", "int"); 948 pp_define(pp, "__UINT_LEAST8_TYPE__", "unsigned char"); 949 pp_define(pp, "__UINT_LEAST16_TYPE__", "unsigned short"); 950 pp_define(pp, "__UINT_LEAST32_TYPE__", "unsigned int"); 951 pp_define(pp, "__INT_LEAST64_TYPE__", lp64 ? "long" : "long long"); 952 pp_define(pp, "__UINT_LEAST64_TYPE__", 953 lp64 ? "unsigned long" : "unsigned long long"); 954 955 /* Fast types: fast8 stays at `signed char`; fast16/32/64 widen to the 956 * register-width integer so the operation fits in a single instruction. */ 957 pp_define(pp, "__INT_FAST8_TYPE__", "signed char"); 958 pp_define(pp, "__UINT_FAST8_TYPE__", "unsigned char"); 959 pp_define(pp, "__INT_FAST8_MAX__", "127"); 960 pp_define(pp, "__UINT_FAST8_MAX__", "255"); 961 if (ptr64) { 962 pp_define(pp, "__INT_FAST16_TYPE__", lp64 ? "long" : "long long"); 963 pp_define(pp, "__INT_FAST32_TYPE__", lp64 ? "long" : "long long"); 964 pp_define(pp, "__INT_FAST64_TYPE__", lp64 ? "long" : "long long"); 965 pp_define(pp, "__UINT_FAST16_TYPE__", 966 lp64 ? "unsigned long" : "unsigned long long"); 967 pp_define(pp, "__UINT_FAST32_TYPE__", 968 lp64 ? "unsigned long" : "unsigned long long"); 969 pp_define(pp, "__UINT_FAST64_TYPE__", 970 lp64 ? "unsigned long" : "unsigned long long"); 971 pp_define(pp, "__INT_FAST16_MAX__", 972 lp64 ? "9223372036854775807L" : "9223372036854775807LL"); 973 pp_define(pp, "__INT_FAST32_MAX__", 974 lp64 ? "9223372036854775807L" : "9223372036854775807LL"); 975 pp_define(pp, "__INT_FAST64_MAX__", 976 lp64 ? "9223372036854775807L" : "9223372036854775807LL"); 977 pp_define(pp, "__UINT_FAST16_MAX__", 978 lp64 ? "18446744073709551615UL" : "18446744073709551615ULL"); 979 pp_define(pp, "__UINT_FAST32_MAX__", 980 lp64 ? "18446744073709551615UL" : "18446744073709551615ULL"); 981 pp_define(pp, "__UINT_FAST64_MAX__", 982 lp64 ? "18446744073709551615UL" : "18446744073709551615ULL"); 983 } else { 984 pp_define(pp, "__INT_FAST16_TYPE__", "int"); 985 pp_define(pp, "__INT_FAST32_TYPE__", "int"); 986 pp_define(pp, "__INT_FAST64_TYPE__", "long long"); 987 pp_define(pp, "__UINT_FAST16_TYPE__", "unsigned int"); 988 pp_define(pp, "__UINT_FAST32_TYPE__", "unsigned int"); 989 pp_define(pp, "__UINT_FAST64_TYPE__", "unsigned long long"); 990 pp_define(pp, "__INT_FAST16_MAX__", "2147483647"); 991 pp_define(pp, "__INT_FAST32_MAX__", "2147483647"); 992 pp_define(pp, "__INT_FAST64_MAX__", "9223372036854775807LL"); 993 pp_define(pp, "__UINT_FAST16_MAX__", "4294967295U"); 994 pp_define(pp, "__UINT_FAST32_MAX__", "4294967295U"); 995 pp_define(pp, "__UINT_FAST64_MAX__", "18446744073709551615ULL"); 996 } 997 998 /* Pointer-holding integers + ptrdiff/size maxes */ 999 if (lp64) { 1000 pp_define(pp, "__LONG_MAX__", "9223372036854775807L"); 1001 pp_define(pp, "__INTPTR_TYPE__", "long"); 1002 pp_define(pp, "__UINTPTR_TYPE__", "unsigned long"); 1003 pp_define(pp, "__INTPTR_MAX__", "9223372036854775807L"); 1004 pp_define(pp, "__UINTPTR_MAX__", "18446744073709551615UL"); 1005 pp_define(pp, "__PTRDIFF_MAX__", "9223372036854775807L"); 1006 pp_define(pp, "__SIZE_MAX__", "18446744073709551615UL"); 1007 } else if (ptr64) { 1008 pp_define(pp, "__LONG_MAX__", "2147483647L"); 1009 pp_define(pp, "__INTPTR_TYPE__", "long long"); 1010 pp_define(pp, "__UINTPTR_TYPE__", "unsigned long long"); 1011 pp_define(pp, "__INTPTR_MAX__", "9223372036854775807LL"); 1012 pp_define(pp, "__UINTPTR_MAX__", "18446744073709551615ULL"); 1013 pp_define(pp, "__PTRDIFF_MAX__", "9223372036854775807LL"); 1014 pp_define(pp, "__SIZE_MAX__", "18446744073709551615ULL"); 1015 } else { 1016 pp_define(pp, "__LONG_MAX__", "2147483647L"); 1017 pp_define(pp, "__INTPTR_TYPE__", "int"); 1018 pp_define(pp, "__UINTPTR_TYPE__", "unsigned int"); 1019 pp_define(pp, "__INTPTR_MAX__", "2147483647"); 1020 pp_define(pp, "__UINTPTR_MAX__", "4294967295U"); 1021 pp_define(pp, "__PTRDIFF_MAX__", "2147483647"); 1022 pp_define(pp, "__SIZE_MAX__", "4294967295U"); 1023 } 1024 1025 /* Greatest-width integers + matching _C() suffix macros */ 1026 if (lp64) { 1027 pp_define(pp, "__INTMAX_TYPE__", "long"); 1028 pp_define(pp, "__UINTMAX_TYPE__", "unsigned long"); 1029 pp_define(pp, "__INTMAX_MAX__", "9223372036854775807L"); 1030 pp_define(pp, "__UINTMAX_MAX__", "18446744073709551615UL"); 1031 pp_define(pp, "__INT64_C(c)", "c ## L"); 1032 pp_define(pp, "__UINT64_C(c)", "c ## UL"); 1033 pp_define(pp, "__INTMAX_C(c)", "c ## L"); 1034 pp_define(pp, "__UINTMAX_C(c)", "c ## UL"); 1035 /* Suffix tokens (the form <stdint.h> uses to build INT64_C/etc.). GCC and 1036 * clang predefine these; kit must too so kit-compiled TUs that include its 1037 * freestanding <stdint.h> get the right-typed 64-bit constants. */ 1038 pp_define(pp, "__INT64_C_SUFFIX__", "L"); 1039 pp_define(pp, "__UINT64_C_SUFFIX__", "UL"); 1040 pp_define(pp, "__INTMAX_C_SUFFIX__", "L"); 1041 pp_define(pp, "__UINTMAX_C_SUFFIX__", "UL"); 1042 } else { 1043 pp_define(pp, "__INTMAX_TYPE__", "long long"); 1044 pp_define(pp, "__UINTMAX_TYPE__", "unsigned long long"); 1045 pp_define(pp, "__INTMAX_MAX__", "9223372036854775807LL"); 1046 pp_define(pp, "__UINTMAX_MAX__", "18446744073709551615ULL"); 1047 pp_define(pp, "__INT64_C(c)", "c ## LL"); 1048 pp_define(pp, "__UINT64_C(c)", "c ## ULL"); 1049 pp_define(pp, "__INTMAX_C(c)", "c ## LL"); 1050 pp_define(pp, "__UINTMAX_C(c)", "c ## ULL"); 1051 pp_define(pp, "__INT64_C_SUFFIX__", "LL"); 1052 pp_define(pp, "__UINT64_C_SUFFIX__", "ULL"); 1053 pp_define(pp, "__INTMAX_C_SUFFIX__", "LL"); 1054 pp_define(pp, "__UINTMAX_C_SUFFIX__", "ULL"); 1055 } 1056 1057 pp_define(pp, "__WCHAR_MAX__", wchar16 ? "65535" : "2147483647"); 1058 pp_define(pp, "__WCHAR_MIN__", wchar16 ? "0" : "(-__WCHAR_MAX__ - 1)"); 1059 pp_define(pp, "__WINT_MAX__", "2147483647"); 1060 pp_define(pp, "__WINT_MIN__", "(-__WINT_MAX__ - 1)"); 1061 pp_define(pp, "__SIG_ATOMIC_MAX__", "2147483647"); 1062 pp_define(pp, "__SIG_ATOMIC_MIN__", "(-__SIG_ATOMIC_MAX__ - 1)"); 1063 1064 /* C11 <stdatomic.h> lock-free macros. The currently supported primary 1065 * targets have naturally lock-free scalar and pointer atomics through the 1066 * machine-word sizes used by these typedefs. */ 1067 pp_define(pp, "__ATOMIC_BOOL_LOCK_FREE", "2"); 1068 pp_define(pp, "__ATOMIC_CHAR_LOCK_FREE", "2"); 1069 pp_define(pp, "__ATOMIC_CHAR16_T_LOCK_FREE", "2"); 1070 pp_define(pp, "__ATOMIC_CHAR32_T_LOCK_FREE", "2"); 1071 pp_define(pp, "__ATOMIC_WCHAR_T_LOCK_FREE", "2"); 1072 pp_define(pp, "__ATOMIC_SHORT_LOCK_FREE", "2"); 1073 pp_define(pp, "__ATOMIC_INT_LOCK_FREE", "2"); 1074 pp_define(pp, "__ATOMIC_LONG_LOCK_FREE", "2"); 1075 pp_define(pp, "__ATOMIC_LLONG_LOCK_FREE", "2"); 1076 pp_define(pp, "__ATOMIC_POINTER_LOCK_FREE", "2"); 1077 1078 pp_define(pp, "__FLT_EVAL_METHOD__", "0"); 1079 pp_define(pp, "__FLT_HAS_DENORM__", "1"); 1080 pp_define(pp, "__FLT_MANT_DIG__", "24"); 1081 pp_define(pp, "__FLT_DECIMAL_DIG__", "9"); 1082 pp_define(pp, "__FLT_DIG__", "6"); 1083 pp_define(pp, "__FLT_MIN_EXP__", "(-125)"); 1084 pp_define(pp, "__FLT_MIN_10_EXP__", "(-37)"); 1085 pp_define(pp, "__FLT_MAX_EXP__", "128"); 1086 pp_define(pp, "__FLT_MAX_10_EXP__", "38"); 1087 pp_define(pp, "__FLT_MAX__", "0x1.fffffep+127F"); 1088 pp_define(pp, "__FLT_EPSILON__", "0x1p-23F"); 1089 pp_define(pp, "__FLT_MIN__", "0x1p-126F"); 1090 pp_define(pp, "__FLT_DENORM_MIN__", "0x1p-149F"); 1091 1092 pp_define(pp, "__DBL_HAS_DENORM__", "1"); 1093 pp_define(pp, "__DBL_MANT_DIG__", "53"); 1094 pp_define(pp, "__DBL_DECIMAL_DIG__", "17"); 1095 pp_define(pp, "__DBL_DIG__", "15"); 1096 pp_define(pp, "__DBL_MIN_EXP__", "(-1021)"); 1097 pp_define(pp, "__DBL_MIN_10_EXP__", "(-307)"); 1098 pp_define(pp, "__DBL_MAX_EXP__", "1024"); 1099 pp_define(pp, "__DBL_MAX_10_EXP__", "308"); 1100 pp_define(pp, "__DBL_MAX__", "0x1.fffffffffffffp+1023"); 1101 pp_define(pp, "__DBL_EPSILON__", "0x1p-52"); 1102 pp_define(pp, "__DBL_MIN__", "0x1p-1022"); 1103 pp_define(pp, "__DBL_DENORM_MIN__", "0x1p-1074"); 1104 1105 /* Targets that follow the IEEE-754 binary128 quad psABI for `long double` 1106 * (RISC-V, aarch64-linux, wasm32) get the 113-bit-mantissa characteristics; 1107 * everything else aliases `double`. The wasm backend still reports f128 as 1108 * unsupported when a value is actually materialized. See 1109 * kit_target_long_double_is_binary128. */ 1110 if (kit_target_long_double_is_binary128(target)) { 1111 pp_define(pp, "__LDBL_HAS_DENORM__", "1"); 1112 pp_define(pp, "__LDBL_MANT_DIG__", "113"); 1113 pp_define(pp, "__LDBL_DECIMAL_DIG__", "36"); 1114 pp_define(pp, "__LDBL_DIG__", "33"); 1115 pp_define(pp, "__LDBL_MIN_EXP__", "(-16381)"); 1116 pp_define(pp, "__LDBL_MIN_10_EXP__", "(-4931)"); 1117 pp_define(pp, "__LDBL_MAX_EXP__", "16384"); 1118 pp_define(pp, "__LDBL_MAX_10_EXP__", "4932"); 1119 pp_define(pp, "__LDBL_MAX__", "0x1.ffffffffffffffffffffffffffffp+16383L"); 1120 pp_define(pp, "__LDBL_EPSILON__", "0x1p-112L"); 1121 pp_define(pp, "__LDBL_MIN__", "0x1p-16382L"); 1122 pp_define(pp, "__LDBL_DENORM_MIN__", "0x1p-16494L"); 1123 pp_define(pp, "__DECIMAL_DIG__", "36"); 1124 } else { 1125 pp_define(pp, "__LDBL_HAS_DENORM__", "1"); 1126 pp_define(pp, "__LDBL_MANT_DIG__", "53"); 1127 pp_define(pp, "__LDBL_DECIMAL_DIG__", "17"); 1128 pp_define(pp, "__LDBL_DIG__", "15"); 1129 pp_define(pp, "__LDBL_MIN_EXP__", "(-1021)"); 1130 pp_define(pp, "__LDBL_MIN_10_EXP__", "(-307)"); 1131 pp_define(pp, "__LDBL_MAX_EXP__", "1024"); 1132 pp_define(pp, "__LDBL_MAX_10_EXP__", "308"); 1133 pp_define(pp, "__LDBL_MAX__", "0x1.fffffffffffffp+1023L"); 1134 pp_define(pp, "__LDBL_EPSILON__", "0x1p-52L"); 1135 pp_define(pp, "__LDBL_MIN__", "0x1p-1022L"); 1136 pp_define(pp, "__LDBL_DENORM_MIN__", "0x1p-1074L"); 1137 pp_define(pp, "__DECIMAL_DIG__", "17"); 1138 } 1139 } 1140 1141 Pp* pp_new(Compiler* c) { 1142 Heap* h = (Heap*)kit_compiler_context(c)->heap; 1143 Pp* pp = (Pp*)h->alloc(h, sizeof(*pp), _Alignof(Pp)); 1144 if (!pp) return NULL; 1145 memset(pp, 0, sizeof(*pp)); 1146 pp->c = c; 1147 pp->pool = c_pool_new(c); 1148 pp->arena = NULL; 1149 pp->xarena = NULL; 1150 (void)kit_arena_new(h, 64 * 1024, &pp->arena); 1151 (void)kit_arena_new(h, 64 * 1024, &pp->xarena); 1152 if (!pp->pool || !pp->arena || !pp->xarena) { 1153 c_pool_free(pp->pool); 1154 kit_arena_free(pp->arena); 1155 kit_arena_free(pp->xarena); 1156 h->free(h, pp, sizeof(*pp)); 1157 return NULL; 1158 } 1159 MacroTab_init(&pp->macros, h); 1160 pp_intern_keywords(pp); 1161 compute_date_time(pp); 1162 pp_register_static_predefined(pp); 1163 pp_register_target_predefined(pp); 1164 return pp; 1165 } 1166 1167 void pp_free(Pp* pp) { 1168 Heap* h; 1169 if (!pp) return; 1170 h = pp_heap(pp); 1171 /* Pop / close any remaining lex sources. */ 1172 while (pp->nsources) src_pop(pp); 1173 /* The reused token-paste lexer is never pushed as a source, so close it 1174 * directly here (it is lazily opened on the first `##`). */ 1175 if (pp->paste_lex) lex_close(pp->paste_lex); 1176 /* Release the SrcInfo registry: each entry's folded buffer (if PP owns it), 1177 * splice table, lazy line index, and #line overlay segments. */ 1178 if (pp->srcinfo) { 1179 u32 i; 1180 for (i = 0; i < pp->srcinfo_cap; ++i) { 1181 SrcInfo* si = &pp->srcinfo[i]; 1182 if (si->owns_buf && si->buf) pp_xfree(pp, (char*)si->buf, si->len); 1183 if (si->splices) pp_xfree(pp, si->splices, si->nsplices * sizeof(u32)); 1184 if (si->line_off) pp_xfree(pp, si->line_off, si->nlines * sizeof(u32)); 1185 if (si->segs) pp_xfree(pp, si->segs, si->segs_cap * sizeof(LineSeg)); 1186 } 1187 pp_xfree(pp, pp->srcinfo, sizeof(SrcInfo) * pp->srcinfo_cap); 1188 } 1189 pp_xfree(pp, pp->sources, sizeof(TokSrc) * pp->sources_cap); 1190 MacroTab_fini(&pp->macros); 1191 pp_xfree(pp, pp->ifstk, sizeof(IfFrame) * pp->ifstk_cap); 1192 pp_xfree(pp, pp->inc_dirs, sizeof(*pp->inc_dirs) * pp->inc_dirs_cap); 1193 c_pool_free(pp->pool); 1194 kit_arena_free(pp->arena); 1195 kit_arena_free(pp->xarena); 1196 h->free(h, pp, sizeof(*pp)); 1197 } 1198 1199 void pp_push_source(Pp* pp, const SourceSpec* spec) { 1200 TokSrc s; 1201 Lexer* lex = lex_open(pp->c, spec); 1202 if (!lex) compiler_panic(pp->c, (SrcLoc){0, 0, 0}, "pp: out of memory"); 1203 if (spec->flags & SRC_PRIMARY) lex_skip_shebang(lex); 1204 /* Remember parser-feed mode so #include'd lexers inherit it (they build their 1205 * own SourceSpec in do_include and OR in SRC_PARSER_FEED from this flag). */ 1206 if (spec->flags & SRC_PARSER_FEED) pp->parser_feed = 1; 1207 /* Adopt the source buffer + splice table for lazy loc/text materialization. 1208 */ 1209 pp_register_srcinfo(pp, lex); 1210 memset(&s, 0, sizeof(s)); 1211 s.kind = SRC_LEX; 1212 s.lex = lex; 1213 src_push(pp, s); 1214 } 1215 1216 void pp_add_include_dir(Pp* pp, const char* dir, int system) { 1217 if (pp->ninc_dirs == pp->inc_dirs_cap) { 1218 u32 nc = pp->inc_dirs_cap ? pp->inc_dirs_cap * 2 : 4; 1219 pp->inc_dirs = 1220 pp_xrealloc(pp, pp->inc_dirs, sizeof(*pp->inc_dirs) * pp->inc_dirs_cap, 1221 sizeof(*pp->inc_dirs) * nc, _Alignof(void*)); 1222 pp->inc_dirs_cap = nc; 1223 } 1224 pp->inc_dirs[pp->ninc_dirs].path = dir; 1225 pp->inc_dirs[pp->ninc_dirs].system = (u8)(system ? 1 : 0); 1226 ++pp->ninc_dirs; 1227 } 1228 1229 void pp_define(Pp* pp, const char* name, const char* body) { 1230 /* Build a synthetic source line "name body\n" and run it through the lexer + 1231 * define machinery so command-line -D matches the normal #define path. The 1232 * buffer is allocated in pp->arena (retained to pp_free) because the 1233 * resulting macro-body tokens carry TEXT_SRC spans into it. */ 1234 size_t nlen = name ? kit_slice_cstr(name).len : 0; 1235 size_t blen = body ? kit_slice_cstr(body).len : 0; 1236 char* buf; 1237 size_t pos = 0; 1238 SourceSpec spec; 1239 TokSrc s; 1240 Lexer* lex; 1241 Tok* line; 1242 u32 lineN; 1243 1244 if (!name || !*name) return; 1245 /* "name" + " " + "body" + "\n" */ 1246 buf = (char*)arena_alloc(pp->arena, nlen + 1 + blen + 1, 1); 1247 memcpy(buf + pos, name, nlen); 1248 pos += nlen; 1249 buf[pos++] = ' '; 1250 if (blen) { 1251 memcpy(buf + pos, body, blen); 1252 pos += blen; 1253 } 1254 buf[pos++] = '\n'; 1255 1256 memset(&spec, 0, sizeof(spec)); 1257 spec.name = KIT_SLICE_LIT("<command-line>"); 1258 spec.bytes = buf; 1259 spec.len = (u32)pos; 1260 lex = lex_open(pp->c, &spec); 1261 pp_register_srcinfo(pp, lex); 1262 memset(&s, 0, sizeof(s)); 1263 s.kind = SRC_LEX; 1264 s.lex = lex; 1265 src_push(pp, s); 1266 read_directive_line(pp, &line, &lineN); 1267 do_define(pp, line, lineN); 1268 /* Drain anything trailing (shouldn't be any) and pop the lexer. */ 1269 src_pop(pp); 1270 } 1271 1272 void pp_undef(Pp* pp, const char* name) { 1273 Sym s; 1274 if (!name || !*name) return; 1275 s = kit_sym_intern(pp->pool->c, kit_slice_cstr(name)); 1276 mt_del(pp, s); 1277 } 1278 1279 uint32_t pp_pack_alignment(const Pp* pp) { return pp ? pp->pack_align : 0; } 1280 1281 void pp_add_include_edge(Pp* pp, u32 includer, u32 included, LocRef include_loc, 1282 int system) { 1283 /* This generic edge-recording entry point has no resolved-dir context, so it 1284 * can only fall back to the spelling form for the resolved-system flag. */ 1285 kit_source_add_include(pp->c, includer, included, 1286 pp_materialize_loc(pp, include_loc), system, system); 1287 }