zig

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

commit a5017bd6d050280d36ad86918a69fe10724ed2e0 (tree)
parent 0d07cad830b0dfef31516cf042ad5192ab30263f
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date:   Thu, 26 Feb 2026 18:50:45 +0000

sema: prep work for cc body evaluation

- Add file_idx to Sema struct (tracks which loaded module the sema
  operates on, needed by builtin_value resolution and cc body evaluation)
- Save cc body position/length in FuncZirInfo (needed to evaluate
  calling convention bodies)
- Add builtin_value handler skeleton in zirExtended (returns void type
  for now, will resolve CallingConvention/ExportOptions from std.builtin)
- Set mini_sema.file_idx in analyzeNavValC
- Add !fi.is_inline guard in zirFunc cc detection

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

Diffstat:
Mstage0/sema.c | 29++++++++++++++++++++---------
Mstage0/sema.h | 3+++
2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -91,6 +91,7 @@ void semaInit(Sema* sema, InternPool* ip, Zir code) { sema->air_extra = ARR_INIT(uint32_t, SEMA_AIR_EXTRA_INITIAL_CAP); sema->air_extra_cap = SEMA_AIR_EXTRA_INITIAL_CAP; sema->func_index = IP_INDEX_NONE; + sema->file_idx = UINT32_MAX; sema->fn_ret_ty = TYPE_NONE; sema->branch_quota = SEMA_DEFAULT_BRANCH_QUOTA; sema->allow_memoize = true; @@ -1714,6 +1715,8 @@ typedef struct { uint32_t ret_ty_body_len; uint32_t ret_ty_ref_pos; uint32_t param_block_pi; // offset from payload_index for param_block + uint32_t cc_body_pos; // position in code.extra of cc body instructions + uint32_t cc_body_len; // number of instructions in cc body bool is_fancy; bool has_cc_body; // for func_fancy: whether cc body is present bool is_inline; // calling convention == .@"inline" @@ -1738,12 +1741,13 @@ static FuncZirInfo parseFuncZir(Sema* sema, uint32_t inst) { bool has_ret_ty_ref = (bits & (1u << 5)) != 0; bool has_any_noalias = (bits & (1u << 7)) != 0; if (info.has_cc_body) { - uint32_t cc_body_len = sema->code.extra[extra_index]; + info.cc_body_len = sema->code.extra[extra_index]; + info.cc_body_pos = extra_index + 1; // Check if CC body is calling_convention_inline. // Inline functions have a cc body of [extended(builtin_value, // CALLING_CONVENTION_INLINE), break_inline]. - if (cc_body_len >= 1) { - uint32_t cc_inst = sema->code.extra[extra_index + 1]; + if (info.cc_body_len >= 1) { + uint32_t cc_inst = sema->code.extra[info.cc_body_pos]; if (sema->code.inst_tags[cc_inst] == ZIR_INST_EXTENDED && sema->code.inst_datas[cc_inst].extended.opcode == ZIR_EXT_BUILTIN_VALUE @@ -1752,7 +1756,7 @@ static FuncZirInfo parseFuncZir(Sema* sema, uint32_t inst) { info.is_inline = true; } } - extra_index += 1 + cc_body_len; + extra_index += 1 + info.cc_body_len; } else if (has_cc_ref) { extra_index += 1; } @@ -4291,6 +4295,7 @@ static InternPoolIndex analyzeNavValC(uint32_t nav_idx) { // cross-module declarations (e.g. @import("builtin").target). Sema mini_sema; semaInit(&mini_sema, s_module_ip, *zir); + mini_sema.file_idx = file_idx; mini_sema.source_dir = s_loaded_modules[file_idx].source_dir; mini_sema.module_root = s_global_module_root; @@ -8903,9 +8908,8 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) { // Detect calling convention from func_fancy cc body. uint8_t cc = 0; // default = .auto - if (fi.is_fancy && fi.has_cc_body) { - // C calling convention = 1 in the Zig enum - cc = 1; // .c — simplified, will need proper resolution later + if (fi.is_fancy && fi.has_cc_body && !fi.is_inline) { + cc = 1; // .c — simplified for now } // Create function type IP entry. @@ -10228,6 +10232,12 @@ static AirInstRef zirExtended(Sema* sema, SemaBlock* block, uint32_t inst) { TypeIndex lhs_ty = semaTypeOf(sema, lhs); return AIR_REF_FROM_IP(lhs_ty); } + // builtin_value: return the type from std.builtin. + // Ported from src/Sema.zig builtinValue. + // TODO: resolve CallingConvention/ExportOptions from namespace + if (opcode == ZIR_EXT_BUILTIN_VALUE) { + return AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); + } return AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE); } @@ -11365,8 +11375,7 @@ static bool analyzeBodyInner( continue; // decl_val / decl_ref: reference to a module-level declaration. - // Maps to void for now; the actual resolution happens in zirCall - // when the callee is a decl_val/decl_ref. + // Returns the Nav's resolved value when available, void otherwise. // When the declaration is an @import, lazily create a struct // type for the imported module and recursively process its // imports (matching Zig's ensureFileAnalyzed / scanNamespace). @@ -12036,6 +12045,7 @@ SemaFuncAirList semaAnalyze(Sema* sema) { root_mod->has_zir = true; root_mod->analyzed = true; s_root_file_idx = root_file_idx; + sema->file_idx = root_file_idx; (void)createFileRootStructC(root_file_idx, &sema->code); // Create ptr_nav for "root" in start.zig ($136), @@ -12061,6 +12071,7 @@ SemaFuncAirList semaAnalyze(Sema* sema) { s_loaded_modules[0].has_zir = true; s_loaded_modules[0].analyzed = true; s_root_file_idx = 0; + sema->file_idx = 0; (void)createFileRootStructC(0, &sema->code); resolveModuleDeclImports(0, 2); } diff --git a/stage0/sema.h b/stage0/sema.h @@ -284,6 +284,9 @@ typedef struct Sema { // When true, test declarations are analyzed (test blocks become // analyzeable functions). Set by the caller before semaAnalyze. bool is_test; + // File index into s_loaded_modules[] for this sema's module. + // Set by analyzeNavValC / semaAnalyze. UINT32_MAX = unknown. + uint32_t file_idx; } Sema; #define SEMA_DEFAULT_BRANCH_QUOTA 1000