commit eb9194365b806f918ea225520271669c9137f379
parent 3faa02c28b1de79212bfe7cc50b0525c22040002
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Wed, 20 May 2026 21:41:49 -0700
Improve emit-c source readability
Diffstat:
2 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/src/arch/c_target/emit.c b/src/arch/c_target/emit.c
@@ -703,7 +703,11 @@ static void c_emit_operand_as(CTarget* t, Operand op, CfreeCgTypeId target_ty) {
static void c_emit_operand_arith(CTarget* t, Operand op) {
if (c_operand_is_ptr_typed(t, op)) {
cbuf_puts(&t->body, "((uintptr_t)");
- c_emit_operand(t, op);
+ if (op.kind == OPK_IMM) {
+ c_emit_imm_literal(t, op.v.imm);
+ } else {
+ c_emit_operand(t, op);
+ }
cbuf_puts(&t->body, ")");
return;
}
@@ -716,7 +720,11 @@ static void c_emit_operand_arith(CTarget* t, Operand op) {
static void c_emit_operand_arith_signed(CTarget* t, Operand op, int signed_) {
if (c_operand_is_ptr_typed(t, op)) {
cbuf_puts(&t->body, "((uintptr_t)");
- c_emit_operand(t, op);
+ if (op.kind == OPK_IMM) {
+ c_emit_imm_literal(t, op.v.imm);
+ } else {
+ c_emit_operand(t, op);
+ }
cbuf_puts(&t->body, ")");
return;
}
@@ -974,6 +982,8 @@ void c_func_begin(CGTarget* T, const CGFuncDesc* fd) {
t->next_tmp = 0;
t->nscopes = 0;
t->last_was_terminator = 0;
+ t->have_emitted_loc = 0;
+ t->emitted_loc = (SrcLoc){0, 0, 0};
const char* name = c_sym_name(t, fd->sym);
@@ -3094,9 +3104,56 @@ void c_fence(CGTarget* T, MemOrder o) {
/* === set_loc === */
+static void cbuf_put_line_filename(CBuf* b, const char* s) {
+ cbuf_putc(b, '"');
+ if (s) {
+ while (*s) {
+ unsigned char ch = (unsigned char)*s++;
+ switch (ch) {
+ case '\\':
+ case '"':
+ cbuf_putc(b, '\\');
+ cbuf_putc(b, (char)ch);
+ break;
+ case '\n':
+ cbuf_puts(b, "\\n");
+ break;
+ case '\r':
+ cbuf_puts(b, "\\r");
+ break;
+ case '\t':
+ cbuf_puts(b, "\\t");
+ break;
+ default:
+ cbuf_putc(b, (char)ch);
+ break;
+ }
+ }
+ }
+ cbuf_putc(b, '"');
+}
+
void c_set_loc(CGTarget* T, SrcLoc l) {
- (void)T;
- (void)l;
+ CTarget* t = (CTarget*)T;
+ const char* file;
+
+ if (!t->cur_fn || l.file_id == 0 || l.line == 0) return;
+ if (t->have_emitted_loc && t->emitted_loc.file_id == l.file_id &&
+ t->emitted_loc.line == l.line) {
+ return;
+ }
+
+ file = cfree_compiler_file_name(t->c, l.file_id);
+ if (!file) return;
+
+ cbuf_puts(&t->body, "#line ");
+ cbuf_put_u64(&t->body, (u64)l.line);
+ cbuf_putc(&t->body, ' ');
+ cbuf_put_line_filename(&t->body, file);
+ cbuf_putc(&t->body, '\n');
+
+ t->emitted_loc = l;
+ t->have_emitted_loc = 1;
}
/* === data emission ===
diff --git a/src/arch/c_target/internal.h b/src/arch/c_target/internal.h
@@ -125,6 +125,13 @@ typedef struct CTarget {
const CGFuncDesc* cur_fn;
+ /* Most recent source line directive emitted into the current function body.
+ * Reset on func_begin; used by c_set_loc to avoid noisy duplicate #line
+ * directives. */
+ SrcLoc emitted_loc;
+ u8 have_emitted_loc;
+ u8 pad_cur_loc[3];
+
/* Label minting: ids 1..next_label. 0 is reserved as LABEL_NONE. */
u32 next_label;