zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 9aa97b3dcd18c0549b6c04169290abb68d77f338 (tree)
parent 70eb2ab984f7a4654b9dc3654c0c88240ccbed26
Author: Motiejus <motiejus@jakstys.lt>
Date:   Sun,  8 Mar 2026 06:04:29 +0000

sema: port callconv(.c) support, resolveTypeFullyC for func/error_union (num_passing=104)

Add handling for builtin_value kinds 13-14 (calling_convention_c/inline)
in zirExtended, matching Sema.zig's zirBuiltinValue. This looks up "c"
or "inline" in the CallingConvention namespace.

Add func_type and error_union_type handlers to resolveTypeFullyC,
matching Type.resolveFully's recursive resolution for .fn and
.error_union types.

Add ptr_type + ptr_nav creation in ensureFullMemoizedStateC for
main-phase builtins (15-35), matching Zig's analyzeNavRefInner.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Mstage0/corpus.zig | 3++-
Mstage0/sema.c | 46++++++++++++++++++++++++++++++++++++++++++++--
Astage0/sema_tests/callconv_c.zig | 3+++
Mstage0/zcu_per_thread.c | 7+++++++
4 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/stage0/corpus.zig b/stage0/corpus.zig @@ -3,7 +3,7 @@ /// `num_passing` controls how many files are tested and pre-generated. /// Both build.zig and stages_test.zig import this file. /// To enable more tests: just increment `num_passing`. -pub const num_passing: usize = 103; +pub const num_passing: usize = 104; pub const files = [_][]const u8{ "stage0/sema_tests/empty.zig", @@ -109,6 +109,7 @@ pub const files = [_][]const u8{ "lib/std/os/uefi/tables/table_header.zig", "lib/std/zig/llvm.zig", "stage0/sema_tests/export_builtin.zig", + "stage0/sema_tests/callconv_c.zig", "lib/compiler_rt/neghf2.zig", "lib/compiler_rt/negxf2.zig", "lib/compiler_rt/absvdi2.zig", diff --git a/stage0/sema.c b/stage0/sema.c @@ -4989,6 +4989,23 @@ void resolveTypeFullyC(Sema* sema, InternPoolIndex ip_idx) { // Slice wraps a pointer type; resolve the pointer's child. resolveTypeFullyC(sema, sema->ip->items[ip_idx].data.slice); break; + case IP_KEY_FUNC_TYPE: { + // Zig's resolveFully for .fn: recurse on params and return type. + const FuncType* ft = &sema->ip->items[ip_idx].data.func_type; + if (ft->is_generic) + break; + for (uint32_t i = 0; i < ft->param_count && i < FUNC_TYPE_MAX_PARAMS; + i++) { + resolveTypeFullyC(sema, ft->param_types[i]); + } + resolveTypeFullyC(sema, ft->return_type); + break; + } + case IP_KEY_ERROR_UNION_TYPE: + // Zig's resolveFully for .error_union: recurse on payload. + resolveTypeFullyC( + sema, sema->ip->items[ip_idx].data.error_union_type.payload); + break; default: break; } @@ -11279,8 +11296,33 @@ static AirInstRef zirExtended(Sema* sema, SemaBlock* block, uint32_t inst) { } } } - UNIMPLEMENTED("zirExtended: builtin_value kind not found"); - return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); // unreachable + // Kinds 13-14: calling_convention_c / calling_convention_inline. + // Ported from Sema.zig zirBuiltinValue: these return VALUES + // (not types) by looking up "c" or "inline" in the + // CallingConvention namespace. + if (bv_kind == ZIR_BUILTIN_VALUE_CALLING_CONVENTION_C + || bv_kind == ZIR_BUILTIN_VALUE_CALLING_CONVENTION_INLINE) { + const char* field_name + = (bv_kind == ZIR_BUILTIN_VALUE_CALLING_CONVENTION_C) + ? "c" + : "inline"; + InternPoolIndex cc_type = getBuiltinTypeC(sema, 2); + if (cc_type != IP_INDEX_NONE) { + uint32_t cc_ns = findNamespaceForType(sema, cc_type); + if (cc_ns != UINT32_MAX) { + uint32_t c_nav + = findNavInNamespace(sema, cc_ns, field_name); + if (c_nav != UINT32_MAX) { + InternPoolIndex val + = ensureNavValUpToDate(sema, c_nav); + if (val != IP_INDEX_NONE && val != IP_INDEX_VOID_VALUE) + return AIR_REF_FROM_IP(val); + } + } + } + } + // TODO: implement remaining builtin_value kinds + return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); } UNIMPLEMENTED("zirExtended: unimplemented extended opcode"); return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE); // unreachable diff --git a/stage0/sema_tests/callconv_c.zig b/stage0/sema_tests/callconv_c.zig @@ -0,0 +1,3 @@ +export fn identity(a: u16) callconv(.c) u16 { + return a; +} diff --git a/stage0/zcu_per_thread.c b/stage0/zcu_per_thread.c @@ -1333,6 +1333,13 @@ void ensureFullMemoizedStateC(Sema* sema) { if (val == IP_INDEX_NONE) continue; + // Create ptr_type + ptr_nav matching Zig's analyzeNavRefInner. + { + InternPoolIndex child = entry->is_type ? IP_INDEX_TYPE_TYPE : val; + InternPoolIndex ptr_ty = internPtrConst(sema, child); + (void)internNavPtr(sema, ptr_ty, nav); + } + sema->zcu->builtin_decl_values[i] = val; // Immediately resolveFully for type builtins, matching Zig's