commit 75ba470e205bb1f666c1160cae5461a4bc4d8859
parent ac1e312614a908ba4f64f796ebb3fb3a37684ec9
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Mon, 15 Jun 2026 13:44:37 -0700
cg: prune CallConv, alias FuncResult, drop dead ZERO_WIDTH field flag
Three CG API cleanups ahead of the header rewrite:
- KitCgCallConv: drop SYSV/WIN64/AAPCS/WASM (these are the target's ABI
identity, fixed by the triple, not a per-compilation choice) and
INTERRUPT (a duplicate of the KIT_CG_FUNC_INTERRUPT function flag).
Only KIT_CG_CC_TARGET_C — the target's own C ABI — remains; it is the
sole convention any backend lowered. The four arch supports_call_conv
hooks collapse to a single TARGET_C check, and the toy callconv name
table loses the removed spellings.
- KitCgFuncResult is now a typedef of KitCgFuncParam: identical shape
(type + ABI attrs); the differing legal-attr subsets were never
enforced by the distinct struct anyway.
- Remove KIT_CG_FIELD_ZERO_WIDTH: it had no consumer. Zero-width
bit-field layout barriers are already carried by BITFIELD + bit_width
== 0, which the CG and ABI layout paths key off of; the C frontend
stops setting the dead flag.
No behavior change. cg_api 291/0, toy 1392/0, parse 3928/0.
Diffstat:
8 files changed, 26 insertions(+), 70 deletions(-)
diff --git a/include/kit/cg.h b/include/kit/cg.h
@@ -74,17 +74,17 @@ typedef enum KitCgDebugEncoding {
KIT_CG_DEBUG_ENC_FLOAT,
} KitCgDebugEncoding;
+/* Source-selectable calling convention: the convention axis a frontend can vary
+ * *within one compilation*, not the target's ABI identity (that is fixed by the
+ * triple). KIT_CG_CC_TARGET_C selects the target's own C ABI — whichever of
+ * SysV / Win64 / AAPCS64 / wasm the triple implies — and is the only convention
+ * kit lowers today. A real variant that repartitions the call (e.g. an x86
+ * vectorcall/regparm, preserve_most) would be added here and gated by
+ * kit_cg_target_supports_call_conv. Definition-side conventions that change the
+ * prologue but not the call ABI (naked, interrupt) are function attributes —
+ * KIT_CG_FUNC_NAKED / KIT_CG_FUNC_INTERRUPT — not values here. */
typedef enum KitCgCallConv {
- /* Backend-selected C ABI for the target triple. Frontends should use this
- * unless source semantics or ABI interop explicitly require another
- * convention. Non-default values are requests that must be supported by the
- * selected backend or diagnosed. */
KIT_CG_CC_TARGET_C,
- KIT_CG_CC_SYSV,
- KIT_CG_CC_WIN64,
- KIT_CG_CC_AAPCS,
- KIT_CG_CC_WASM,
- KIT_CG_CC_INTERRUPT,
} KitCgCallConv;
typedef enum KitCgAbiAttrFlag {
@@ -113,13 +113,13 @@ typedef struct KitCgFuncParam {
KitCgAbiAttrs attrs;
} KitCgFuncParam;
-/* Symmetric with KitCgFuncParam. result.type is always a valid type id; use
+/* A function result is described exactly like a parameter: a type plus ABI
+ * attrs. The legal attribute subsets differ (SRET on results; BYVAL/NEST on
+ * params), but the descriptor shape is identical, so KitCgFuncResult is an
+ * alias of KitCgFuncParam. result.type is always a valid type id; use
* kit_cg_type_builtin(c, KIT_CG_BUILTIN_VOID) for a function that returns no
* value. */
-typedef struct KitCgFuncResult {
- KitCgTypeId type;
- KitCgAbiAttrs attrs;
-} KitCgFuncResult;
+typedef KitCgFuncParam KitCgFuncResult;
typedef struct KitCgFuncSig {
KitCgFuncResult result; /* void builtin means no value */
@@ -135,7 +135,7 @@ typedef struct KitCgField {
uint32_t align_override; /* 0 = natural, 1 = packed, >1 explicit align */
uint32_t max_align; /* 0 = natural, otherwise cap field alignment */
uint32_t flags; /* KitCgFieldFlag */
- uint16_t bit_width; /* valid for bit-fields, may be 0 for barriers */
+ uint16_t bit_width; /* bit-field width; 0 w/ BITFIELD = layout barrier */
uint16_t bit_offset; /* filled by record-field queries */
uint32_t bit_storage_size; /* bytes, filled by record-field queries */
int bit_signed; /* signed extraction for bit-field loads */
@@ -143,7 +143,6 @@ typedef struct KitCgField {
typedef enum KitCgFieldFlag {
KIT_CG_FIELD_BITFIELD = 1u << 0,
- KIT_CG_FIELD_ZERO_WIDTH = 1u << 1,
} KitCgFieldFlag;
typedef struct KitCgEnumValue {
diff --git a/lang/c/type/type.c b/lang/c/type/type.c
@@ -888,11 +888,10 @@ static KitCgTypeId type_cg_record_layout(TypeCgLower* l, const Type* t) {
fields[i].max_align = t->rec.max_align;
if (t->rec.fields[i].flags & FIELD_BITFIELD) {
fields[i].flags |= KIT_CG_FIELD_BITFIELD;
+ /* A zero-width bit-field is carried to CG as bit_width 0 (the layout
+ * barrier); CG keys off BITFIELD && bit_width==0, no separate flag. */
fields[i].bit_width = t->rec.fields[i].bitfield_width;
fields[i].bit_signed = type_is_signed_integer(t->rec.fields[i].type);
- if (t->rec.fields[i].flags & FIELD_ZERO_WIDTH) {
- fields[i].flags |= KIT_CG_FIELD_ZERO_WIDTH;
- }
}
if (t->rec.fields[i].packed && fields[i].align_override == 0) {
fields[i].align_override = 1;
diff --git a/lang/toy/attrs.c b/lang/toy/attrs.c
@@ -52,9 +52,7 @@ static int toy_parse_attr_string_arg(ToyParser* p, KitSym* out) {
int toy_parse_callconv_const(ToyParser* p, KitCgCallConv* out) {
static const ToyConstRow rows[] = {
- {"target_c", KIT_CG_CC_TARGET_C}, {"sysv", KIT_CG_CC_SYSV},
- {"win64", KIT_CG_CC_WIN64}, {"aapcs", KIT_CG_CC_AAPCS},
- {"wasm", KIT_CG_CC_WASM}, {"interrupt", KIT_CG_CC_INTERRUPT},
+ {"target_c", KIT_CG_CC_TARGET_C},
};
uint64_t v;
if (!toy_parse_dot_const(p, rows, sizeof rows / sizeof rows[0], 1,
diff --git a/src/arch/aa64/arch.c b/src/arch/aa64/arch.c
@@ -152,17 +152,7 @@ static KitStatus aa64_target_feature_apply_isa(const Target* target,
* no SysV/Win64/WASM variant. */
static int aa64_supports_call_conv(const Compiler* c, KitCgCallConv cc) {
(void)c;
- switch (cc) {
- case KIT_CG_CC_TARGET_C:
- case KIT_CG_CC_AAPCS:
- return 1;
- case KIT_CG_CC_SYSV:
- case KIT_CG_CC_WIN64:
- case KIT_CG_CC_WASM:
- case KIT_CG_CC_INTERRUPT:
- return 0;
- }
- return 0;
+ return cc == KIT_CG_CC_TARGET_C;
}
/* Capability twin of aa_intrinsic (src/arch/aa64/native.c); keep the two in
diff --git a/src/arch/arch.h b/src/arch/arch.h
@@ -325,8 +325,9 @@ typedef struct ArchImpl {
u32 atomic_lock_free_max;
/* 1 if call convention `cc` is selectable for this compiler's (arch, os).
- * KIT_CG_CC_TARGET_C is handled generically (always 1); INTERRUPT is 0. May
- * read c->target.os (a property, not arch identity). Read via
+ * Today the only convention is KIT_CG_CC_TARGET_C (the target's C ABI); a
+ * backend that grows a real variant convention reports it here. May read
+ * c->target.os (a property, not arch identity). Read via
* kit_cg_target_supports_call_conv. */
int (*supports_call_conv)(const Compiler* c, KitCgCallConv cc);
diff --git a/src/arch/riscv/arch.c b/src/arch/riscv/arch.c
@@ -329,17 +329,7 @@ static CgTarget* rv64_semantic_target_new(Compiler* c, ObjBuilder* o,
* variant. Shared by rv64 and rv32 (one backend, one answer). */
static int rv64_supports_call_conv(const Compiler* c, KitCgCallConv cc) {
(void)c;
- switch (cc) {
- case KIT_CG_CC_TARGET_C:
- return 1;
- case KIT_CG_CC_SYSV:
- case KIT_CG_CC_WIN64:
- case KIT_CG_CC_AAPCS:
- case KIT_CG_CC_WASM:
- case KIT_CG_CC_INTERRUPT:
- return 0;
- }
- return 0;
+ return cc == KIT_CG_CC_TARGET_C;
}
/* Capability twin of rv_intrinsic (src/arch/riscv/native.c); keep the two in
diff --git a/src/arch/wasm/arch.c b/src/arch/wasm/arch.c
@@ -75,17 +75,7 @@ static CGTarget* wasm_backend_make(Compiler* c, ObjBuilder* o,
* SysV/Win64/AAPCS. */
static int wasm_supports_call_conv(const Compiler* c, KitCgCallConv cc) {
(void)c;
- switch (cc) {
- case KIT_CG_CC_TARGET_C:
- case KIT_CG_CC_WASM:
- return 1;
- case KIT_CG_CC_SYSV:
- case KIT_CG_CC_WIN64:
- case KIT_CG_CC_AAPCS:
- case KIT_CG_CC_INTERRUPT:
- return 0;
- }
- return 0;
+ return cc == KIT_CG_CC_TARGET_C;
}
/* Capability twin of wasm_intrinsic (src/arch/wasm/emit.c); keep the two in
diff --git a/src/arch/x64/arch.c b/src/arch/x64/arch.c
@@ -120,19 +120,8 @@ static CgTarget* x64_semantic_target_new(Compiler* c, ObjBuilder* o,
/* Which explicit calling conventions x86-64 can emit. SysV and Win64 split on
* the OS (a property, not arch identity); TARGET_C is always available. */
static int x64_supports_call_conv(const Compiler* c, KitCgCallConv cc) {
- switch (cc) {
- case KIT_CG_CC_TARGET_C:
- return 1;
- case KIT_CG_CC_SYSV:
- return c->target.os != KIT_OS_WINDOWS;
- case KIT_CG_CC_WIN64:
- return c->target.os == KIT_OS_WINDOWS;
- case KIT_CG_CC_AAPCS:
- case KIT_CG_CC_WASM:
- case KIT_CG_CC_INTERRUPT:
- return 0;
- }
- return 0;
+ (void)c;
+ return cc == KIT_CG_CC_TARGET_C;
}
/* Capability twin of x64_intrinsic (src/arch/x64/native.c); keep the two in