kit

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

commit 78dd6876acf34875b49ae2aad972ddeb0a2b38e6
parent 5c3b6c310fe5a6c29007deca89a659d4a6f73438
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 19 May 2026 14:45:15 -0700

Support #warning directive

Diffstat:
Mlang/c/pp/pp.c | 1+
Mlang/c/pp/pp_directive.c | 36+++++++++++++++++++++++++++++-------
Mlang/c/pp/pp_priv.h | 1+
Atest/pp/cases/b3_warning_directive.c | 2++
Atest/pp/cases/b3_warning_directive.expected | 1+
5 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/lang/c/pp/pp.c b/lang/c/pp/pp.c @@ -206,6 +206,7 @@ static void pp_intern_keywords(Pp* pp) { pp->sym_pragma = pool_intern_cstr(p, "pragma"); pp->sym_pragma_kw = pp->sym_pragma; pp->sym_error = pool_intern_cstr(p, "error"); + pp->sym_warning = pool_intern_cstr(p, "warning"); pp->sym_embed = pool_intern_cstr(p, "embed"); pp->sym_defined = pool_intern_cstr(p, "defined"); pp->sym_va_args = pool_intern_cstr(p, "__VA_ARGS__"); diff --git a/lang/c/pp/pp_directive.c b/lang/c/pp/pp_directive.c @@ -1014,24 +1014,44 @@ int try_expand_pragma_op(Pp* pp, const Tok* invoke) { } /* ============================================================ - * #error + * #error / #warning * ============================================================ */ -static void do_error(Pp* pp, const Tok* line, u32 n, SrcLoc loc) { - /* Concatenate token spellings into a single message. */ - CharBuf cb = {0}; +static void directive_message(Pp* pp, const Tok* line, u32 n, CharBuf* cb) { u32 i; for (i = 0; i < n; ++i) { size_t sl = 0; const char* s = line[i].spelling ? pool_str(pp->pool, line[i].spelling, &sl) : NULL; - if (i > 0) cb_putc(pp, &cb, ' '); - if (s && sl) cb_append(pp, &cb, s, (u32)sl); + if (i > 0) cb_putc(pp, cb, ' '); + if (s && sl) cb_append(pp, cb, s, (u32)sl); + } + cb_putc(pp, cb, 0); +} + +static void pp_warn(Pp* pp, SrcLoc loc, const char* fmt, ...) { + CfreeDiagSink* sink = cfree_compiler_diag_sink(pp->c); + va_list ap; + if (sink && sink->emit) { + va_start(ap, fmt); + sink->emit(sink, CFREE_DIAG_WARN, loc, fmt, ap); + va_end(ap); } - cb_putc(pp, &cb, 0); + if (sink) sink->warnings++; +} + +static void do_error(Pp* pp, const Tok* line, u32 n, SrcLoc loc) { + CharBuf cb = {0}; + directive_message(pp, line, n, &cb); compiler_panic(pp->c, loc, "#error: %s", cb.data ? cb.data : ""); } +static void do_warning(Pp* pp, const Tok* line, u32 n, SrcLoc loc) { + CharBuf cb = {0}; + directive_message(pp, line, n, &cb); + pp_warn(pp, loc, "#warning: %s", cb.data ? cb.data : ""); +} + /* ============================================================ * #embed (C23, ยง6.10.* per N3033) * ============================================================ */ @@ -1244,6 +1264,8 @@ void process_directive(Pp* pp, SrcLoc hash_loc) { do_pragma(pp, line + 1, n - 1, hash_loc); else if (name == pp->sym_error) do_error(pp, line + 1, n - 1, hash_loc); + else if (name == pp->sym_warning) + do_warning(pp, line + 1, n - 1, hash_loc); else if (name == pp->sym_embed) do_embed(pp, line + 1, n - 1, hash_loc); else { diff --git a/lang/c/pp/pp_priv.h b/lang/c/pp/pp_priv.h @@ -138,6 +138,7 @@ struct Pp { Sym sym_line; Sym sym_pragma; Sym sym_error; + Sym sym_warning; Sym sym_embed; Sym sym_defined; Sym sym_va_args; diff --git a/test/pp/cases/b3_warning_directive.c b/test/pp/cases/b3_warning_directive.c @@ -0,0 +1,2 @@ +#warning "non-fatal diagnostic" +int after_warning; diff --git a/test/pp/cases/b3_warning_directive.expected b/test/pp/cases/b3_warning_directive.expected @@ -0,0 +1 @@ +int after_warning;