kit

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

commit cd546d874cb9961292d244f2f39c167e01e9b305
parent f45825f5e6457c58c4e880ed4e53062ea0c2c248
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Mon, 15 Jun 2026 14:42:16 -0700

cg: reorder and split cg.h into clearer sections

Pure reorganization of the public header — no declaration content changes
(verified: the sorted set of non-banner content lines is identical before
and after, modulo the new section banners and one moved comment).

- Lifecycle now precedes Declarations: you create a session before you
  declare into it, so the header reads in that order.
- The overloaded "Types, ABI, and Target Capabilities" section is split
  into four focused sections: ABI Descriptors (call conv + ABI attrs +
  func param/result/sig), Type System (operational type lattice +
  constructors + queries), Debug Type Information (the type/debug-split
  debug builders + encoding), and Target Facts (backend features,
  va_list, label prefix, pointer size).
- KitCgSymbolFeature and its capability query move into Declarations and
  Symbols, next to the symbol attrs they describe — mirroring how
  kit_cg_target_supports_intrinsic sits with the Intrinsics section.
- kit_cg_target_supports_call_conv moves next to KitCgCallConv and carries
  the shared capability-query contract comment.
- Memory Access moves down next to its consumers (the value-stack
  load/store ops), instead of sitting up among the ABI descriptors.

Builds clean across the tree; cg_api 274/0 and the CG API suites pass.

Diffstat:
Minclude/kit/cg.h | 323+++++++++++++++++++++++++++++++++++++++++--------------------------------------
1 file changed, 169 insertions(+), 154 deletions(-)

diff --git a/include/kit/cg.h b/include/kit/cg.h @@ -29,49 +29,55 @@ typedef uint32_t KitCgDebugType; #define KIT_CG_DEBUG_TYPE_NONE 0u /* ============================================================ - * Types, ABI, and Target Capabilities + * Lifecycle and Source Locations * ============================================================ */ -typedef enum KitCgBuiltinType { - KIT_CG_BUILTIN_VOID, - KIT_CG_BUILTIN_BOOL, /* i1: compare result and branch condition */ - KIT_CG_BUILTIN_I8, - KIT_CG_BUILTIN_I16, - KIT_CG_BUILTIN_I32, - KIT_CG_BUILTIN_I64, - KIT_CG_BUILTIN_I128, - KIT_CG_BUILTIN_F32, - KIT_CG_BUILTIN_F64, - KIT_CG_BUILTIN_F128, - KIT_CG_BUILTIN_VARARG_STATE, - KIT_CG_BUILTIN_COUNT, -} KitCgBuiltinType; +KIT_API KitStatus kit_cg_new(KitCompiler*, KitCg** cg_out); -typedef enum KitCgTypeKind { - KIT_CG_TYPE_VOID, - KIT_CG_TYPE_BOOL, - KIT_CG_TYPE_INT, - KIT_CG_TYPE_FLOAT, - KIT_CG_TYPE_PTR, - KIT_CG_TYPE_ARRAY, - KIT_CG_TYPE_FUNC, - KIT_CG_TYPE_RECORD, - KIT_CG_TYPE_ENUM, - KIT_CG_TYPE_VARARG_STATE, -} KitCgTypeKind; +typedef struct KitCgUnitOptions { + KitSlice source_name; /* diagnostic/provenance label; may be empty */ + uint32_t source_id; /* 0 means "unspecified" */ + uint32_t flags; /* reserved; must be 0 */ +} KitCgUnitOptions; -/* Debug base-type encoding. Mirrors the producer's DEBUG_BE_* set so frontends - * can round-trip source signedness into debug info without storage carrying it. - */ -typedef enum KitCgDebugEncoding { - KIT_CG_DEBUG_ENC_NONE, - KIT_CG_DEBUG_ENC_BOOL, - KIT_CG_DEBUG_ENC_SIGNED, - KIT_CG_DEBUG_ENC_UNSIGNED, - KIT_CG_DEBUG_ENC_SIGNED_CHAR, - KIT_CG_DEBUG_ENC_UNSIGNED_CHAR, - KIT_CG_DEBUG_ENC_FLOAT, -} KitCgDebugEncoding; +typedef enum KitCgOutputKind { + KIT_CG_OUTPUT_RELOCATABLE = 0, + KIT_CG_OUTPUT_EXECUTABLE = 1, + KIT_CG_OUTPUT_SHARED = 2, + KIT_CG_OUTPUT_ARCHIVE_MEMBER = 3, +} KitCgOutputKind; + +typedef enum KitCgInterpositionPolicy { + KIT_CG_INTERPOSITION_DEFAULT = 0, + KIT_CG_INTERPOSITION_NONE = 1, + KIT_CG_INTERPOSITION_DEFAULT_VISIBILITY = 2, +} KitCgInterpositionPolicy; + +typedef struct KitCgFinishOptions { + uint8_t output_kind; /* KitCgOutputKind */ + uint8_t interposition_policy; /* KitCgInterpositionPolicy */ + uint8_t pad[2]; + const KitCgSym* preserved_symbols; + uint32_t npreserved_symbols; +} KitCgFinishOptions; + +KIT_API KitStatus kit_cg_begin(KitCg*, KitObjBuilder* out, + const KitCodeOptions*); +KIT_API KitStatus kit_cg_begin_unit(KitCg*, const KitCgUnitOptions*); +KIT_API KitStatus kit_cg_end_unit(KitCg*); +KIT_API KitStatus kit_cg_finish(KitCg*, const KitCgFinishOptions*); +/* Release the session, abandoning any in-progress object/unit state. Used on + * both the success-detach and error-abort paths. */ +KIT_API KitStatus kit_cg_detach(KitCg*); +KIT_API void kit_cg_free(KitCg*); + +/* Sticky source location. Function, scope, local, param, instruction, and + * data-definition debug records use the current location. */ +KIT_API void kit_cg_set_loc(KitCg*, KitSrcLoc); + +/* ============================================================ + * ABI Descriptors + * ============================================================ */ /* 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 @@ -128,6 +134,44 @@ typedef struct KitCgFuncSig { bool abi_variadic; } KitCgFuncSig; +/* Capability queries answer whether the selected target/API can lower the + * requested feature correctly, not whether it is fast. These are target + * facts, not knobs: frontends use them to choose a legal lowering or to emit + * an unsupported-feature diagnostic before asking CG to produce output. */ +KIT_API int kit_cg_target_supports_call_conv(KitCompiler*, KitCgCallConv); + +/* ============================================================ + * Type System + * ============================================================ */ + +typedef enum KitCgBuiltinType { + KIT_CG_BUILTIN_VOID, + KIT_CG_BUILTIN_BOOL, /* i1: compare result and branch condition */ + KIT_CG_BUILTIN_I8, + KIT_CG_BUILTIN_I16, + KIT_CG_BUILTIN_I32, + KIT_CG_BUILTIN_I64, + KIT_CG_BUILTIN_I128, + KIT_CG_BUILTIN_F32, + KIT_CG_BUILTIN_F64, + KIT_CG_BUILTIN_F128, + KIT_CG_BUILTIN_VARARG_STATE, + KIT_CG_BUILTIN_COUNT, +} KitCgBuiltinType; + +typedef enum KitCgTypeKind { + KIT_CG_TYPE_VOID, + KIT_CG_TYPE_BOOL, + KIT_CG_TYPE_INT, + KIT_CG_TYPE_FLOAT, + KIT_CG_TYPE_PTR, + KIT_CG_TYPE_ARRAY, + KIT_CG_TYPE_FUNC, + KIT_CG_TYPE_RECORD, + KIT_CG_TYPE_ENUM, + KIT_CG_TYPE_VARARG_STATE, +} KitCgTypeKind; + /* Field descriptor for record completion (INPUT). Carries the field's source * shape and layout *policy* — alignment knobs and bit-field width — never its * position: CG computes byte/bit offsets from these and the target ABI. Query @@ -261,24 +305,6 @@ static inline KitCgTypeId kit_cg_type_record(KitCompiler* c, return record; } -/* Debug type builders. These return KIT_CG_DEBUG_TYPE_NONE when debug emission - * is not active on the KitCg session. The resulting handles are owned by that - * session and are valid only for declaration attributes passed to the same - * session. */ -KIT_API KitCgDebugType kit_cg_debug_base(KitCg*, KitSym name, - KitCgDebugEncoding, uint32_t bytes); -KIT_API KitCgDebugType kit_cg_debug_typedef(KitCg*, KitSym name, - KitCgDebugType base); -KIT_API KitCgDebugType kit_cg_debug_ptr(KitCg*, KitCgDebugType pointee); -KIT_API KitCgDebugType kit_cg_debug_array(KitCg*, KitCgDebugType elem, - uint64_t count); -KIT_API KitCgDebugType kit_cg_debug_func(KitCg*, KitCgDebugType ret, - const KitCgDebugType* params, - uint32_t nparams, int variadic); -KIT_API KitCgDebugType kit_cg_debug_enum(KitCg*, KitCgTypeId enum_type, - KitCgDebugType base); -KIT_API KitCgDebugType kit_cg_debug_of_type(KitCg*, KitCgTypeId); - /* Type queries. * * Layout and width queries report ABI/storage facts. Shape-specific queries are @@ -355,20 +381,44 @@ KIT_API uint32_t kit_cg_type_enum_nvalues(KitCompiler*, KitCgTypeId); KIT_API KitStatus kit_cg_type_enum_value(KitCompiler*, KitCgTypeId, uint32_t index, KitCgEnumValue* out); -typedef enum KitCgSymbolFeature { - KIT_CG_SYMFEAT_WEAK, - KIT_CG_SYMFEAT_PROTECTED_VISIBILITY, - KIT_CG_SYMFEAT_DLLIMPORT, - KIT_CG_SYMFEAT_DLLEXPORT, - KIT_CG_SYMFEAT_COMDAT, - KIT_CG_SYMFEAT_COMMON, - KIT_CG_SYMFEAT_MERGE_SECTIONS, - KIT_CG_SYMFEAT_CONSTRUCTOR_PRIORITY, - KIT_CG_SYMFEAT_TLS_LOCAL_EXEC, - KIT_CG_SYMFEAT_TLS_INITIAL_EXEC, - KIT_CG_SYMFEAT_TLS_LOCAL_DYNAMIC, - KIT_CG_SYMFEAT_TLS_GENERAL_DYNAMIC, -} KitCgSymbolFeature; +/* ============================================================ + * Debug Type Information + * ============================================================ */ + +/* Debug base-type encoding. Mirrors the producer's DEBUG_BE_* set so frontends + * can round-trip source signedness into debug info without storage carrying it. + */ +typedef enum KitCgDebugEncoding { + KIT_CG_DEBUG_ENC_NONE, + KIT_CG_DEBUG_ENC_BOOL, + KIT_CG_DEBUG_ENC_SIGNED, + KIT_CG_DEBUG_ENC_UNSIGNED, + KIT_CG_DEBUG_ENC_SIGNED_CHAR, + KIT_CG_DEBUG_ENC_UNSIGNED_CHAR, + KIT_CG_DEBUG_ENC_FLOAT, +} KitCgDebugEncoding; + +/* Debug type builders. These return KIT_CG_DEBUG_TYPE_NONE when debug emission + * is not active on the KitCg session. The resulting handles are owned by that + * session and are valid only for declaration attributes passed to the same + * session. */ +KIT_API KitCgDebugType kit_cg_debug_base(KitCg*, KitSym name, + KitCgDebugEncoding, uint32_t bytes); +KIT_API KitCgDebugType kit_cg_debug_typedef(KitCg*, KitSym name, + KitCgDebugType base); +KIT_API KitCgDebugType kit_cg_debug_ptr(KitCg*, KitCgDebugType pointee); +KIT_API KitCgDebugType kit_cg_debug_array(KitCg*, KitCgDebugType elem, + uint64_t count); +KIT_API KitCgDebugType kit_cg_debug_func(KitCg*, KitCgDebugType ret, + const KitCgDebugType* params, + uint32_t nparams, int variadic); +KIT_API KitCgDebugType kit_cg_debug_enum(KitCg*, KitCgTypeId enum_type, + KitCgDebugType base); +KIT_API KitCgDebugType kit_cg_debug_of_type(KitCg*, KitCgTypeId); + +/* ============================================================ + * Target Facts + * ============================================================ */ typedef enum KitCgBackendFeatureFlag { KIT_CG_BACKEND_UNALIGNED_MEMORY = 1ull << 0, @@ -386,14 +436,6 @@ typedef enum KitCgBackendFeatureFlag { KIT_CG_BACKEND_ICACHE_COHERENT = 1ull << 6, } KitCgBackendFeatureFlag; -/* Capability queries answer whether the selected target/API can lower the - * requested feature correctly, not whether it is fast. These are target - * facts, not knobs: frontends use them to choose a legal lowering or to emit - * an unsupported-feature diagnostic before asking CG to produce output. */ -KIT_API int kit_cg_target_supports_call_conv(KitCompiler*, KitCgCallConv); -KIT_API int kit_cg_target_supports_symbol_feature(KitCompiler*, - KitCgSymbolFeature); -/* kit_cg_target_supports_intrinsic is declared after KitCgIntrinsic. */ KIT_API uint64_t kit_cg_target_backend_features(KitCompiler*); /* Shape of the target's `va_list` object, as an ABI fact. Frontends that @@ -440,34 +482,6 @@ static inline uint8_t kit_arch_ptr_size(KitArchKind arch) { } /* ============================================================ - * Memory Access - * ============================================================ */ - -typedef enum KitCgMemAccessFlag { - KIT_CG_MEM_NONE = 0, - /* Access is an externally observable side effect and must not be merged, - * removed, or reordered across other volatile accesses. */ - KIT_CG_MEM_VOLATILE = 1u << 0, - /* Backend hint (loads only): emit a sign-extending narrow load when - * supported. Frontends normally set KIT_CG_MEM_SOURCE_SIGNED and let - * kit_cg_load derive this for byte/half integer loads; direct callers may - * still set it when they already know the following use is sign-extension. - * Ignored on stores and bit-fields. */ - KIT_CG_MEM_SEXT_LOAD = 1u << 1, - /* The source-language object being accessed is a signed integer. KitCgTypeId - * intentionally carries width/category, not C signedness, so this keeps the - * source semantic fact separate from the backend SEXT-load hint above. */ - KIT_CG_MEM_SOURCE_SIGNED = 1u << 2, -} KitCgMemAccessFlag; - -typedef struct KitCgMemAccess { - KitCgTypeId type; /* value type loaded/stored, or element type */ - uint32_t align; /* 0 = natural for type */ - uint32_t address_space; /* normally inherited from pointer type */ - uint32_t flags; /* KitCgMemAccessFlag */ -} KitCgMemAccess; - -/* ============================================================ * Declarations and Symbols * ============================================================ */ @@ -494,6 +508,26 @@ typedef struct KitCgSymbolAttrs { uint32_t flags; /* KitCgSymbolFlag */ } KitCgSymbolAttrs; +typedef enum KitCgSymbolFeature { + KIT_CG_SYMFEAT_WEAK, + KIT_CG_SYMFEAT_PROTECTED_VISIBILITY, + KIT_CG_SYMFEAT_DLLIMPORT, + KIT_CG_SYMFEAT_DLLEXPORT, + KIT_CG_SYMFEAT_COMDAT, + KIT_CG_SYMFEAT_COMMON, + KIT_CG_SYMFEAT_MERGE_SECTIONS, + KIT_CG_SYMFEAT_CONSTRUCTOR_PRIORITY, + KIT_CG_SYMFEAT_TLS_LOCAL_EXEC, + KIT_CG_SYMFEAT_TLS_INITIAL_EXEC, + KIT_CG_SYMFEAT_TLS_LOCAL_DYNAMIC, + KIT_CG_SYMFEAT_TLS_GENERAL_DYNAMIC, +} KitCgSymbolFeature; + +/* Whether the selected target supports a symbol feature; see + * kit_cg_target_supports_call_conv for the capability-query contract. */ +KIT_API int kit_cg_target_supports_symbol_feature(KitCompiler*, + KitCgSymbolFeature); + typedef enum KitCgFuncFlag { KIT_CG_FUNC_NONE = 0, KIT_CG_FUNC_NORETURN = 1u << 0, @@ -601,53 +635,6 @@ KIT_API KitCgSym kit_cg_alias(KitCg*, KitCgAlias alias); KIT_API KitSym kit_cg_c_linkage_name(KitCompiler*, KitSym source_name); /* ============================================================ - * Lifecycle and Source Locations - * ============================================================ */ - -KIT_API KitStatus kit_cg_new(KitCompiler*, KitCg** cg_out); - -typedef struct KitCgUnitOptions { - KitSlice source_name; /* diagnostic/provenance label; may be empty */ - uint32_t source_id; /* 0 means "unspecified" */ - uint32_t flags; /* reserved; must be 0 */ -} KitCgUnitOptions; - -typedef enum KitCgOutputKind { - KIT_CG_OUTPUT_RELOCATABLE = 0, - KIT_CG_OUTPUT_EXECUTABLE = 1, - KIT_CG_OUTPUT_SHARED = 2, - KIT_CG_OUTPUT_ARCHIVE_MEMBER = 3, -} KitCgOutputKind; - -typedef enum KitCgInterpositionPolicy { - KIT_CG_INTERPOSITION_DEFAULT = 0, - KIT_CG_INTERPOSITION_NONE = 1, - KIT_CG_INTERPOSITION_DEFAULT_VISIBILITY = 2, -} KitCgInterpositionPolicy; - -typedef struct KitCgFinishOptions { - uint8_t output_kind; /* KitCgOutputKind */ - uint8_t interposition_policy; /* KitCgInterpositionPolicy */ - uint8_t pad[2]; - const KitCgSym* preserved_symbols; - uint32_t npreserved_symbols; -} KitCgFinishOptions; - -KIT_API KitStatus kit_cg_begin(KitCg*, KitObjBuilder* out, - const KitCodeOptions*); -KIT_API KitStatus kit_cg_begin_unit(KitCg*, const KitCgUnitOptions*); -KIT_API KitStatus kit_cg_end_unit(KitCg*); -KIT_API KitStatus kit_cg_finish(KitCg*, const KitCgFinishOptions*); -/* Release the session, abandoning any in-progress object/unit state. Used on - * both the success-detach and error-abort paths. */ -KIT_API KitStatus kit_cg_detach(KitCg*); -KIT_API void kit_cg_free(KitCg*); - -/* Sticky source location. Function, scope, local, param, instruction, and - * data-definition debug records use the current location. */ -KIT_API void kit_cg_set_loc(KitCg*, KitSrcLoc); - -/* ============================================================ * Function Bodies and Locals * ============================================================ */ @@ -830,6 +817,34 @@ KIT_API void kit_cg_computed_goto(KitCg*, const KitCgLabel* valid_targets, KIT_API void kit_cg_unreachable(KitCg*); /* ============================================================ + * Memory Access + * ============================================================ */ + +typedef enum KitCgMemAccessFlag { + KIT_CG_MEM_NONE = 0, + /* Access is an externally observable side effect and must not be merged, + * removed, or reordered across other volatile accesses. */ + KIT_CG_MEM_VOLATILE = 1u << 0, + /* Backend hint (loads only): emit a sign-extending narrow load when + * supported. Frontends normally set KIT_CG_MEM_SOURCE_SIGNED and let + * kit_cg_load derive this for byte/half integer loads; direct callers may + * still set it when they already know the following use is sign-extension. + * Ignored on stores and bit-fields. */ + KIT_CG_MEM_SEXT_LOAD = 1u << 1, + /* The source-language object being accessed is a signed integer. KitCgTypeId + * intentionally carries width/category, not C signedness, so this keeps the + * source semantic fact separate from the backend SEXT-load hint above. */ + KIT_CG_MEM_SOURCE_SIGNED = 1u << 2, +} KitCgMemAccessFlag; + +typedef struct KitCgMemAccess { + KitCgTypeId type; /* value type loaded/stored, or element type */ + uint32_t align; /* 0 = natural for type */ + uint32_t address_space; /* normally inherited from pointer type */ + uint32_t flags; /* KitCgMemAccessFlag */ +} KitCgMemAccess; + +/* ============================================================ * Value stack: PLACES and VALUES * ============================================================ *