commit 9cd2e0ff77dd01a77fc4b7d22cf5f49932b46151 (tree)
parent ba547674f8f5cf31f983f13443eda4850a9fff91
Author: Motiejus <motiejus@jakstys.lt>
Date: Mon, 2 Mar 2026 16:44:27 +0000
stage0: refactor globals into structs matching Zig architecture
Eliminates all 39 mutable static globals across sema.c (37) and
intern_pool.c (2). State is now held in properly-typed structs passed
as parameters, mirroring the Zig reference implementation layout.
New files matching Zig src/ layout:
- compilation.h: CompilationConfig + Compilation (matches Compilation.zig)
- zcu.h/zcu.c: ZcuFile, ZcuNamespace, Zcu, zcuInit/zcuDeinit (matches Zcu.zig)
- zcu_per_thread.h: forward declarations for PerThread-style functions
Key changes:
- InternPool gains navs[] (dynamically allocated) + nav_count/nav_cap;
Nav functions now take InternPool* (was implicit via globals)
- Sema gains Zcu* zcu; semaInit now takes Zcu* instead of InternPool*
- All module-level state (files, namespaces, memoized state, config)
moved from static globals into Zcu struct
- zig0.c creates Compilation + Zcu before semaInit
- Test files updated to use zcuInit/zcuDeinit API
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Diffstat:
12 files changed, 1172 insertions(+), 927 deletions(-)
diff --git a/build.zig b/build.zig
@@ -16,6 +16,7 @@ const zig0_headers = &[_][]const u8{
"ast.h",
"astgen.h",
"common.h",
+ "compilation.h",
"intern_pool.h",
"parser.h",
"sema.h",
@@ -24,6 +25,8 @@ const zig0_headers = &[_][]const u8{
"verbose_air.h",
"verbose_intern_pool.h",
"wyhash.h",
+ "zcu.h",
+ "zcu_per_thread.h",
"zir.h",
};
const zig0_c_lib_files = &[_][]const u8{
@@ -40,6 +43,7 @@ const zig0_c_lib_files = &[_][]const u8{
"verbose_intern_pool.c",
"wyhash.c",
"zig0.c",
+ "zcu.c",
"zir.c",
};
const zig0_all_c_files = zig0_c_lib_files ++ &[_][]const u8{"main.c"};
diff --git a/stage0/compilation.h b/stage0/compilation.h
@@ -0,0 +1,20 @@
+// compilation.h — ported from src/Compilation.zig (Config subset we use)
+#ifndef _ZIG0_COMPILATION_H__
+#define _ZIG0_COMPILATION_H__
+#include <stdbool.h>
+
+// Matches Compilation.Config (the fields relevant to stage0).
+typedef struct {
+ const char* module_root; // was: s_global_module_root
+ const char* target_cpu_arch; // was: s_target_cpu_arch_name ("wasm32")
+ const char* target_cpu_model; // was: s_target_cpu_model_name ("lime1")
+ const char* object_format; // was: s_config_object_format ("wasm")
+ const char* link_mode; // was: s_config_link_mode ("static")
+ bool is_test; // was: s_config_is_test
+} CompilationConfig;
+
+// Matches Compilation struct (minimal subset).
+typedef struct Compilation {
+ CompilationConfig config;
+} Compilation;
+#endif
diff --git a/stage0/intern_pool.c b/stage0/intern_pool.c
@@ -443,6 +443,8 @@ InternPool ipInit(void) {
ip.string_bytes_cap = IP_STRING_INITIAL_CAP;
ip.extra = ARR_INIT(uint32_t, IP_EXTRA_INITIAL_CAP);
ip.extra_cap = IP_EXTRA_INITIAL_CAP;
+ ip.navs = ARR_INIT(Nav, 64);
+ ip.nav_cap = 64;
// Index 0: u0_type
ipAppendItem(&ip, ipMakeIntType(0, 0));
@@ -685,10 +687,12 @@ void ipDeinit(InternPool* ip) {
free(ip->hash_table);
free(ip->string_bytes);
free(ip->extra);
+ free(ip->navs);
ip->items = NULL;
ip->hash_table = NULL;
ip->string_bytes = NULL;
ip->extra = NULL;
+ ip->navs = NULL;
ip->items_len = 0;
ip->items_cap = 0;
ip->hash_cap = 0;
@@ -696,6 +700,8 @@ void ipDeinit(InternPool* ip) {
ip->string_bytes_cap = 0;
ip->extra_len = 0;
ip->extra_cap = 0;
+ ip->nav_count = 0;
+ ip->nav_cap = 0;
}
InternPoolIndex ipIntern(InternPool* ip, InternPoolKey key) {
@@ -1008,14 +1014,19 @@ InternPoolIndex ipTypeOf(const InternPool* ip, InternPoolIndex index) {
// --- Nav management ---
// Ported from InternPool.createDeclNav / InternPool.getNav.
-static Nav s_navs[IP_MAX_NAVS];
-static uint32_t s_num_navs;
-
-uint32_t ipCreateDeclNav(uint32_t name, uint32_t fqn, uint32_t zir_index,
- uint32_t namespace_idx, bool is_pub, bool is_const) {
- assert(s_num_navs < IP_MAX_NAVS);
- uint32_t idx = s_num_navs++;
- Nav* nav = &s_navs[idx];
+uint32_t ipCreateDeclNav(InternPool* ip, uint32_t name, uint32_t fqn,
+ uint32_t zir_index, uint32_t namespace_idx, bool is_pub, bool is_const) {
+ assert(ip->nav_count < IP_MAX_NAVS);
+ if (ip->nav_count >= ip->nav_cap) {
+ uint32_t new_cap = ip->nav_cap * 2;
+ Nav* new_navs = realloc(ip->navs, new_cap * sizeof(Nav));
+ if (!new_navs)
+ exit(1);
+ ip->navs = new_navs;
+ ip->nav_cap = new_cap;
+ }
+ uint32_t idx = ip->nav_count++;
+ Nav* nav = &ip->navs[idx];
memset(nav, 0, sizeof(*nav));
nav->name = name;
nav->fqn = fqn;
@@ -1028,14 +1039,14 @@ uint32_t ipCreateDeclNav(uint32_t name, uint32_t fqn, uint32_t zir_index,
return idx;
}
-Nav* ipGetNav(uint32_t nav_index) {
- assert(nav_index < s_num_navs);
- return &s_navs[nav_index];
+Nav* ipGetNav(InternPool* ip, uint32_t nav_index) {
+ assert(nav_index < ip->nav_count);
+ return &ip->navs[nav_index];
}
-void ipResetNavs(void) { s_num_navs = 0; }
+void ipResetNavs(InternPool* ip) { ip->nav_count = 0; }
-uint32_t ipNavCount(void) { return s_num_navs; }
+uint32_t ipNavCount(const InternPool* ip) { return ip->nav_count; }
// --- String interning ---
// Add a null-terminated string to the IP string table. Returns the
diff --git a/stage0/intern_pool.h b/stage0/intern_pool.h
@@ -423,6 +423,24 @@ typedef struct {
} data;
} InternPoolKey;
+// --- Nav (declaration entry) ---
+// Ported from InternPool.Nav. Navs are stored in a separate list from
+// IP items — they do NOT consume IP indices. However, ptr_nav entries
+// (pointers TO Navs) DO consume IP indices.
+
+typedef struct {
+ uint32_t name; // NullTerminatedString index into IP string_bytes
+ uint32_t fqn; // fully qualified name string index
+ uint32_t zir_index; // ZIR instruction index of declaration
+ uint32_t namespace_idx; // owning namespace index
+ InternPoolIndex resolved_type; // IP_INDEX_NONE if unresolved
+ InternPoolIndex resolved_val; // IP_INDEX_NONE if unresolved
+ bool is_pub;
+ bool is_const;
+} Nav;
+
+#define IP_MAX_NAVS 16384
+
// --- InternPool struct ---
typedef struct {
@@ -449,26 +467,14 @@ typedef struct {
uint32_t skip_dedup_end;
uint32_t cc_keep_start;
uint32_t cc_keep_end;
+ // Nav storage (ported from InternPool.zig Nav storage).
+ // Navs do NOT consume IP indices; ptr_nav entries (pointers to navs)
+ // do consume IP indices. Dynamically allocated (like items/extra).
+ Nav* navs;
+ uint32_t nav_count;
+ uint32_t nav_cap;
} InternPool;
-// --- Nav (declaration entry) ---
-// Ported from InternPool.Nav. Navs are stored in a separate list from
-// IP items — they do NOT consume IP indices. However, ptr_nav entries
-// (pointers TO Navs) DO consume IP indices.
-
-typedef struct {
- uint32_t name; // NullTerminatedString index into IP string_bytes
- uint32_t fqn; // fully qualified name string index
- uint32_t zir_index; // ZIR instruction index of declaration
- uint32_t namespace_idx; // owning namespace index
- InternPoolIndex resolved_type; // IP_INDEX_NONE if unresolved
- InternPoolIndex resolved_val; // IP_INDEX_NONE if unresolved
- bool is_pub;
- bool is_const;
-} Nav;
-
-#define IP_MAX_NAVS 16384
-
// --- Function declarations ---
InternPool ipInit(void);
@@ -479,11 +485,11 @@ InternPoolKey ipIndexToKey(const InternPool* ip, InternPoolIndex index);
InternPoolIndex ipTypeOf(const InternPool* ip, InternPoolIndex index);
// Nav management (ported from InternPool.createDeclNav)
-uint32_t ipCreateDeclNav(uint32_t name, uint32_t fqn, uint32_t zir_index,
- uint32_t namespace_idx, bool is_pub, bool is_const);
-Nav* ipGetNav(uint32_t nav_index);
-void ipResetNavs(void);
-uint32_t ipNavCount(void);
+uint32_t ipCreateDeclNav(InternPool* ip, uint32_t name, uint32_t fqn,
+ uint32_t zir_index, uint32_t namespace_idx, bool is_pub, bool is_const);
+Nav* ipGetNav(InternPool* ip, uint32_t nav_index);
+void ipResetNavs(InternPool* ip);
+uint32_t ipNavCount(const InternPool* ip);
// String interning: add a null-terminated string to the IP string table.
// Returns the NullTerminatedString index (offset into string_bytes).
diff --git a/stage0/sema.c b/stage0/sema.c
@@ -1,5 +1,6 @@
#include "sema.h"
#include "astgen.h"
+#include "zcu.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -34,16 +35,10 @@ static uint32_t simpleStringHash(const char* s) {
#define CC_TAG_AUTO 0
#define CC_TAG_INLINE 3
-// Exported declaration names collected by ZIR_INST_EXPORT handler.
-// Module-level state shared between analyzeBodyInner and zirFunc.
-#define MAX_EXPORTED_DECL_NAMES 16
-static uint32_t s_exported_decl_names[MAX_EXPORTED_DECL_NAMES];
-
// --- Memoized state (BuiltinDecl resolution) ---
// Ported from Zcu.BuiltinDecl + PerThread.analyzeMemoizedState.
// Resolves std.builtin type declarations (ExportOptions, Type, etc.)
// on first @export, creating IP entries as side effects.
-#define NUM_BUILTIN_DECL_MAIN 36
typedef struct {
const char* lookup_name; // name to find in namespace
int parent_idx; // -1=direct (std.builtin ns), >=0=index into table
@@ -87,95 +82,11 @@ static const BuiltinDeclEntry s_builtin_decl_entries[NUM_BUILTIN_DECL_MAIN] = {
{ "Opaque", 15, true }, /* 34 Type.Opaque */
{ "Declaration", 15, true }, /* 35 Type.Declaration */
};
-static bool s_memoized_main_resolved;
-static bool s_full_memoized_resolved;
-static InternPoolIndex s_builtin_decl_values[NUM_BUILTIN_DECL_MAIN];
-// IP range created by analyzeMemoizedStateC during preamble.
-// Used by ensureFullMemoizedStateC to skip dedup with preamble entries,
-// matching upstream Zig's sharded IP behavior.
-static uint32_t s_preamble_memoized_start;
-static uint32_t s_preamble_memoized_end;
-// Sub-range within preamble memoized range for CC tag entries.
-// These entries are in Zig's local shard and SHOULD dedup during main
-// analysis, so they're excluded from skip_dedup.
-static uint32_t s_preamble_cc_start;
-static uint32_t s_preamble_cc_end;
-// Nav IDs for builtins 0-4, stored during preamble for later clearing.
-static uint32_t s_preamble_builtin_navs[5];
-static uint32_t s_preamble_builtin_nav_count;
-
-// --- Module-level IP entry tracking ---
-// Tracks loaded modules to create struct type IP entries matching the
-// Zig compiler's module-level analysis. Each imported file module gets
-// a type_struct IP entry, created lazily when the module is first
-// accessed during semantic analysis.
-#define MAX_LOADED_MODULES 512
-typedef struct {
- char path[1024]; // canonical file path
- char source_dir[1024]; // directory containing this file
- Zir zir; // parsed ZIR (inst_len>0 if loaded)
- Ast ast; // AST (kept alive to own source memory)
- bool has_zir; // true if zir/ast are populated
- bool analyzed; // true if createFileRootStructC has been called
-} LoadedModule;
-
-// Global module_root for import resolution (set by semaAnalyze).
-static const char* s_global_module_root;
-
-static LoadedModule s_loaded_modules[MAX_LOADED_MODULES];
-static uint32_t s_num_loaded_modules;
-static uint32_t s_next_struct_hash; // unique hash counter for struct types
-static InternPool* s_module_ip; // IP for struct type creation
-static uint32_t
- s_root_file_idx; // file_idx of root module (ZIR owned by caller)
-static uint32_t s_cg_builtin_ns_idx
- = UINT32_MAX; // compiler-generated builtin namespace
-static uint32_t s_cg_builtin_nav
- = UINT32_MAX; // nav for `const builtin = @import("builtin")` in
- // std/builtin.zig — ptr_nav deferred to $488
-static uint32_t s_builtin_file_idx
- = UINT32_MAX; // file index of std/builtin.zig
-static uint32_t s_std_file_idx = UINT32_MAX; // file index of std.zig
-static const char* s_target_cpu_arch_name = NULL; // e.g. "wasm32"
-static const char* s_target_cpu_model_name = NULL; // e.g. "lime1"
-// Compilation config — ported from Compilation.Config.
-// These are derived from the target and set during semaAnalyze init.
-static const char* s_config_object_format = "wasm"; // ObjectFormat name
-static const char* s_config_link_mode = "static"; // LinkMode name
-static bool s_config_is_test = false;
-// Flag: true during main sema analysis (semaAnalyze), false during
-// preamble. When true, DECL_VAL for local navs in comptime context
-// calls ensureNavValUpToDate for lazy evaluation.
-static bool s_in_main_analysis;
-
-// Enum field value force-intern threshold.
-// During memoized resolution, AddressSpace enum field values (comptime_int)
-// go into the same single IP as main analysis. In Zig's sharded IP,
-// AddressSpace is in a different shard, so its values don't participate
-// in dedup during main analysis. CC tag enum values (0..N-1) ARE in
-// Zig's local shard and DO dedup. AddressSpace comptime_int values
-// below N (the CC field count) correctly substitute for CC entries when
-// dedup happens. Values >= N must NOT be findable via dedup, so they
-// use ipForceIntern. Set to 0 to disable (all values use ipIntern).
-static uint32_t s_enum_force_intern_threshold;
-
-// --- Namespace storage ---
-// Ported from Zcu.Namespace.
-#define MAX_NAMESPACES 512
-
-static SemaNamespace s_namespaces[MAX_NAMESPACES];
-static uint32_t s_num_namespaces;
-
-// File→root_type mapping: tracks which IP index is the root struct
-// type for each loaded module.
-static InternPoolIndex s_file_root_type[MAX_LOADED_MODULES];
-// File→namespace mapping: tracks which namespace index corresponds
-// to each loaded module's root struct.
-static uint32_t s_file_namespace[MAX_LOADED_MODULES];
-void semaInit(Sema* sema, InternPool* ip, Zir code) {
+void semaInit(Sema* sema, Zcu* zcu, Zir code) {
memset(sema, 0, sizeof(*sema));
- sema->ip = ip;
+ sema->zcu = zcu;
+ sema->ip = &zcu->ip;
sema->code = code;
sema->air_inst_tags = ARR_INIT(uint8_t, SEMA_AIR_INITIAL_CAP);
sema->air_inst_cap = SEMA_AIR_INITIAL_CAP;
@@ -425,10 +336,11 @@ static TypeIndex semaTypeOf(Sema* sema, AirInstRef ref);
static uint32_t findEnumFieldByName(
const Zir* zir, uint32_t enum_inst, const char* name);
static InternPoolIndex getEnumFieldIntVal(
- const Zir* zir, uint32_t enum_inst, uint32_t field_idx);
-static uint32_t findEnumDeclForNav(uint32_t nav_idx, const Zir** out_zir);
+ Sema* sema, const Zir* zir, uint32_t enum_inst, uint32_t field_idx);
+static uint32_t findEnumDeclForNav(
+ Sema* sema, uint32_t nav_idx, const Zir** out_zir);
static InternPoolIndex internEnumTag(
- InternPoolIndex enum_ty, InternPoolIndex int_val);
+ Sema* sema, InternPoolIndex enum_ty, InternPoolIndex int_val);
// --- ZIR instruction handlers ---
// Ported from src/Sema.zig instruction handlers.
@@ -932,24 +844,24 @@ static AirInstRef semaCoerce(
const char* lit_name = (const char*)&sema->ip->string_bytes[lit_str];
// Find the nav whose resolved_type matches the enum type.
uint32_t enum_nav = UINT32_MAX;
- for (uint32_t ni = 0; ni < ipNavCount(); ni++) {
- if (ipGetNav(ni)->resolved_type == target_ty) {
+ for (uint32_t ni = 0; ni < ipNavCount(sema->ip); ni++) {
+ if (ipGetNav(sema->ip, ni)->resolved_type == target_ty) {
enum_nav = ni;
break;
}
}
if (enum_nav != UINT32_MAX) {
const Zir* enum_zir = NULL;
- uint32_t enum_inst = findEnumDeclForNav(enum_nav, &enum_zir);
+ uint32_t enum_inst = findEnumDeclForNav(sema, enum_nav, &enum_zir);
if (enum_inst != UINT32_MAX && enum_zir != NULL) {
uint32_t fidx
= findEnumFieldByName(enum_zir, enum_inst, lit_name);
if (fidx != UINT32_MAX) {
InternPoolIndex int_val
- = getEnumFieldIntVal(enum_zir, enum_inst, fidx);
+ = getEnumFieldIntVal(sema, enum_zir, enum_inst, fidx);
if (int_val != IP_INDEX_NONE) {
return AIR_REF_FROM_IP(
- internEnumTag(target_ty, int_val));
+ internEnumTag(sema, target_ty, int_val));
}
}
}
@@ -1950,7 +1862,7 @@ static FuncZirInfo parseFuncZir(Sema* sema, uint32_t inst) {
// Forward declaration (defined later, used by findDeclImportPath et al).
static uint32_t findDeclInstByNameInZir(const Zir* zir, const char* decl_name);
// Forward declaration (defined after createFileRootStructC).
-static uint32_t ensureFileAnalyzedC(const char* full_path);
+static uint32_t ensureFileAnalyzedC(Sema* sema, const char* full_path);
// findDeclImportPath: given a declaration name index, check if the
// declaration's value body contains a ZIR_INST_IMPORT. If so, return
@@ -2051,7 +1963,8 @@ static bool findDeclImportFieldVal(Sema* sema, uint32_t name_idx,
// loadImportZirFromPath: load, parse, and AstGen a file at the given path.
// Returns a Zir with inst_len > 0 on success; inst_len == 0 on failure.
-static Zir loadImportZirFromPath(const char* full_path, Ast* out_ast) {
+static Zir loadImportZirFromPath(
+ Sema* sema, const char* full_path, Ast* out_ast) {
Zir empty_zir;
memset(&empty_zir, 0, sizeof(empty_zir));
FILE* f = fopen(full_path, "rb");
@@ -2074,7 +1987,7 @@ static Zir loadImportZirFromPath(const char* full_path, Ast* out_ast) {
src[read_len] = '\0';
// Ensure the module is analyzed (creates type_struct + namespace).
- (void)ensureFileAnalyzedC(full_path);
+ (void)ensureFileAnalyzedC(sema, full_path);
// Parse.
*out_ast = astParse(src, (uint32_t)read_len);
@@ -2090,8 +2003,8 @@ static Zir loadImportZirFromPath(const char* full_path, Ast* out_ast) {
// (like "std") via module_root.
// Returns a Zir with inst_len > 0 on success; inst_len == 0 on failure.
// The caller must call zirDeinit and astDeinit on the returned structures.
-static Zir loadImportZir(
- const char* source_dir, const char* import_path, Ast* out_ast) {
+static Zir loadImportZir(Sema* sema, const char* source_dir,
+ const char* import_path, Ast* out_ast) {
Zir empty_zir;
memset(&empty_zir, 0, sizeof(empty_zir));
@@ -2112,7 +2025,7 @@ static Zir loadImportZir(
if (n < 0 || (size_t)n >= sizeof(full_path))
return empty_zir;
- return loadImportZirFromPath(full_path, out_ast);
+ return loadImportZirFromPath(sema, full_path, out_ast);
}
// findDeclImportPathInZir: find a declaration by name in a ZIR module and
@@ -2361,10 +2274,10 @@ static void computeSourceDir(const char* module_root, const char* source_dir,
// loadStdImportZir: load a non-relative import via the module root.
// For @import("std"), resolves to <module_root>/lib/std/std.zig.
// For @import("math.zig") from std dir, uses source_dir as usual.
-static Zir loadStdImportZir(const char* module_root, const char* source_dir,
- const char* import_path, Ast* out_ast) {
+static Zir loadStdImportZir(Sema* sema, const char* module_root,
+ const char* source_dir, const char* import_path, Ast* out_ast) {
// First try relative to source_dir (normal case).
- Zir zir = loadImportZir(source_dir, import_path, out_ast);
+ Zir zir = loadImportZir(sema, source_dir, import_path, out_ast);
if (zir.inst_len > 0)
return zir;
@@ -2378,7 +2291,7 @@ static Zir loadStdImportZir(const char* module_root, const char* source_dir,
int n = snprintf(full_path, sizeof(full_path), "%s/lib/%s/%s.zig",
module_root, import_path, import_path);
if (n >= 0 && (size_t)n < sizeof(full_path)) {
- zir = loadImportZirFromPath(full_path, out_ast);
+ zir = loadImportZirFromPath(sema, full_path, out_ast);
if (zir.inst_len > 0)
return zir;
}
@@ -2393,40 +2306,41 @@ static Zir loadStdImportZir(const char* module_root, const char* source_dir,
// Create a struct type IP entry for a new module.
// Each module gets a unique struct type in the InternPool.
-static InternPoolIndex createModuleStructType(void) {
+static InternPoolIndex createModuleStructType(Sema* sema) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_STRUCT_TYPE;
- key.data.struct_type = s_next_struct_hash++;
- return ipIntern(s_module_ip, key);
+ key.data.struct_type = sema->zcu->next_struct_hash++;
+ return ipIntern(sema->ip, key);
}
// Forward declaration for createNamespace (defined below).
-static uint32_t createNamespace(InternPoolIndex owner_type, uint32_t file_idx);
+static uint32_t createNamespace(
+ Sema* sema, InternPoolIndex owner_type, uint32_t file_idx);
// ensureCgBuiltinModule: create the compiler-generated builtin module
// on demand, the first time @import("builtin") is encountered.
// Ported from Compilation.zig updateBuiltinModule: creates a virtual
// module with no ZIR, storing navs for is_test, object_format, etc.
// Returns the CG builtin struct type, or IP_INDEX_NONE on failure.
-static InternPoolIndex ensureCgBuiltinModule(void) {
+static InternPoolIndex ensureCgBuiltinModule(Sema* sema) {
// Already created — return cached type.
- if (s_cg_builtin_ns_idx != UINT32_MAX)
- return s_namespaces[s_cg_builtin_ns_idx].owner_type;
+ if (sema->zcu->cg_builtin_ns_idx != UINT32_MAX)
+ return sema->zcu->namespaces[sema->zcu->cg_builtin_ns_idx].owner_type;
- if (!s_module_ip || s_num_loaded_modules >= MAX_LOADED_MODULES)
+ if (!sema->ip || sema->zcu->num_files >= ZCU_MAX_FILES)
return IP_INDEX_NONE;
- InternPoolIndex cg_struct = createModuleStructType();
- uint32_t cg_file_idx = s_num_loaded_modules++;
- LoadedModule* cg_mod = &s_loaded_modules[cg_file_idx];
+ InternPoolIndex cg_struct = createModuleStructType(sema);
+ uint32_t cg_file_idx = sema->zcu->num_files++;
+ ZcuFile* cg_mod = &sema->zcu->files[cg_file_idx];
memset(cg_mod, 0, sizeof(*cg_mod));
snprintf(cg_mod->path, sizeof(cg_mod->path), "<builtin>");
cg_mod->analyzed = true;
- s_file_root_type[cg_file_idx] = cg_struct;
- uint32_t cg_ns_idx = createNamespace(cg_struct, cg_file_idx);
- s_file_namespace[cg_file_idx] = cg_ns_idx;
- s_cg_builtin_ns_idx = cg_ns_idx;
+ sema->zcu->file_root_types[cg_file_idx] = cg_struct;
+ uint32_t cg_ns_idx = createNamespace(sema, cg_struct, cg_file_idx);
+ sema->zcu->file_namespaces[cg_file_idx] = cg_ns_idx;
+ sema->zcu->cg_builtin_ns_idx = cg_ns_idx;
return cg_struct;
}
@@ -2436,10 +2350,10 @@ static InternPoolIndex ensureCgBuiltinModule(void) {
// Create a new Namespace. Returns the namespace index.
static uint32_t createNamespace(
- InternPoolIndex owner_type, uint32_t file_idx) {
- assert(s_num_namespaces < MAX_NAMESPACES);
- uint32_t idx = s_num_namespaces++;
- SemaNamespace* ns = &s_namespaces[idx];
+ Sema* sema, InternPoolIndex owner_type, uint32_t file_idx) {
+ assert(sema->zcu->num_namespaces < ZCU_MAX_NAMESPACES);
+ uint32_t idx = sema->zcu->num_namespaces++;
+ ZcuNamespace* ns = &sema->zcu->namespaces[idx];
memset(ns, 0, sizeof(*ns));
ns->owner_type = owner_type;
ns->file_idx = file_idx;
@@ -2453,9 +2367,9 @@ static uint32_t createNamespace(
// it in the namespace's pub/priv lists. Comptime declarations are
// recorded in the namespace's comptime list.
-static void scanNamespaceC(uint32_t ns_idx, const uint32_t* decl_insts,
- uint32_t decls_len, const Zir* zir) {
- SemaNamespace* ns = &s_namespaces[ns_idx];
+static void scanNamespaceC(Sema* sema, uint32_t ns_idx,
+ const uint32_t* decl_insts, uint32_t decls_len, const Zir* zir) {
+ ZcuNamespace* ns = &sema->zcu->namespaces[ns_idx];
// Pass 1: named declarations (const/var)
for (uint32_t d = 0; d < decls_len; d++) {
@@ -2479,14 +2393,14 @@ static void scanNamespaceC(uint32_t ns_idx, const uint32_t* decl_insts,
// Create Nav (does NOT consume IP index)
uint32_t nav_idx = ipCreateDeclNav(
- name_idx, name_idx, decl_inst, ns_idx, is_pub, is_const);
+ sema->ip, name_idx, name_idx, decl_inst, ns_idx, is_pub, is_const);
// Add to pub or priv list
if (is_pub) {
- assert(ns->pub_nav_count < SEMA_NS_MAX_NAVS);
+ assert(ns->pub_nav_count < ZCU_NS_MAX_NAVS);
ns->pub_navs[ns->pub_nav_count++] = nav_idx;
} else {
- assert(ns->priv_nav_count < SEMA_NS_MAX_NAVS);
+ assert(ns->priv_nav_count < ZCU_NS_MAX_NAVS);
ns->priv_navs[ns->priv_nav_count++] = nav_idx;
}
}
@@ -2506,7 +2420,7 @@ static void scanNamespaceC(uint32_t ns_idx, const uint32_t* decl_insts,
// Record comptime declarations
if (id == 3) { // comptime
- assert(ns->comptime_decl_count < SEMA_NS_MAX_COMPTIME);
+ assert(ns->comptime_decl_count < ZCU_NS_MAX_COMPTIME);
ns->comptime_decls[ns->comptime_decl_count++] = decl_inst;
}
}
@@ -2519,7 +2433,7 @@ static void scanNamespaceC(uint32_t ns_idx, const uint32_t* decl_insts,
// Returns the IP index of the struct type.
static InternPoolIndex createFileRootStructC(
- uint32_t file_idx, const Zir* zir) {
+ Sema* sema, uint32_t file_idx, const Zir* zir) {
// Parse struct_decl at instruction 0
assert(zir->inst_tags[0] == ZIR_INST_EXTENDED);
assert(zir->inst_datas[0].extended.opcode == ZIR_EXT_STRUCT_DECL);
@@ -2555,17 +2469,17 @@ static InternPoolIndex createFileRootStructC(
const uint32_t* decl_insts = &zir->extra[extra_index];
// Create type_struct IP entry
- InternPoolIndex struct_type = createModuleStructType();
+ InternPoolIndex struct_type = createModuleStructType(sema);
// Create namespace for this file
- uint32_t ns_idx = createNamespace(struct_type, file_idx);
+ uint32_t ns_idx = createNamespace(sema, struct_type, file_idx);
// Scan namespace declarations
- scanNamespaceC(ns_idx, decl_insts, decls_len, zir);
+ scanNamespaceC(sema, ns_idx, decl_insts, decls_len, zir);
// Record file→type and file→namespace mappings
- s_file_root_type[file_idx] = struct_type;
- s_file_namespace[file_idx] = ns_idx;
+ sema->zcu->file_root_types[file_idx] = struct_type;
+ sema->zcu->file_namespaces[file_idx] = ns_idx;
return struct_type;
}
@@ -2575,7 +2489,7 @@ static InternPoolIndex createFileRootStructC(
// Returns the IP index of the pointer type.
// Ported from Sema.zig analyzeNavRefInner → pt.ptrType call.
-static InternPoolIndex internPtrConst(InternPoolIndex child_type) {
+static InternPoolIndex internPtrConst(Sema* sema, InternPoolIndex child_type) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_PTR_TYPE;
@@ -2583,7 +2497,7 @@ static InternPoolIndex internPtrConst(InternPoolIndex child_type) {
key.data.ptr_type.sentinel = IP_INDEX_NONE;
key.data.ptr_type.flags = PTR_FLAGS_SIZE_ONE | PTR_FLAGS_IS_CONST;
key.data.ptr_type.packed_offset = 0;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internNavPtr ---
@@ -2592,19 +2506,20 @@ static InternPoolIndex internPtrConst(InternPoolIndex child_type) {
// Each ptr_nav is unique per (ty, nav) pair.
static InternPoolIndex internNavPtr(
- InternPoolIndex ptr_type, uint32_t nav_idx) {
+ Sema* sema, InternPoolIndex ptr_type, uint32_t nav_idx) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_PTR_NAV;
key.data.ptr_nav.ty = ptr_type;
key.data.ptr_nav.nav = nav_idx;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internPtrMutable ---
// Create a single-item mutable pointer type: *child_type.
// Like internPtrConst but without the IS_CONST flag.
-static InternPoolIndex internPtrMutable(InternPoolIndex child_type) {
+static InternPoolIndex internPtrMutable(
+ Sema* sema, InternPoolIndex child_type) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_PTR_TYPE;
@@ -2612,54 +2527,54 @@ static InternPoolIndex internPtrMutable(InternPoolIndex child_type) {
key.data.ptr_type.sentinel = IP_INDEX_NONE;
key.data.ptr_type.flags = PTR_FLAGS_SIZE_ONE;
key.data.ptr_type.packed_offset = 0;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internUndef ---
// Create an undef value for the given type.
-static InternPoolIndex internUndef(InternPoolIndex type_idx) {
+static InternPoolIndex internUndef(Sema* sema, InternPoolIndex type_idx) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_UNDEF;
key.data.undef = type_idx;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internPtrComptimeAlloc ---
// Create a ptr_comptime_alloc entry (comptime return value slot).
static InternPoolIndex internPtrComptimeAlloc(
- InternPoolIndex ptr_type, uint32_t alloc_index) {
+ Sema* sema, InternPoolIndex ptr_type, uint32_t alloc_index) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_PTR_COMPTIME_ALLOC;
key.data.ptr_comptime_alloc.ty = ptr_type;
key.data.ptr_comptime_alloc.alloc_index = alloc_index;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internPtrUav ---
// Create a ptr_uav entry (unique addressable value).
static InternPoolIndex internPtrUav(
- InternPoolIndex ptr_type, InternPoolIndex val) {
+ Sema* sema, InternPoolIndex ptr_type, InternPoolIndex val) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_PTR_UAV;
key.data.ptr_uav.ty = ptr_type;
key.data.ptr_uav.val = val;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internPtrField ---
// Create a ptr_field entry (field access on a pointer).
-static InternPoolIndex internPtrField(
- InternPoolIndex ptr_type, InternPoolIndex base, uint32_t field_index) {
+static InternPoolIndex internPtrField(Sema* sema, InternPoolIndex ptr_type,
+ InternPoolIndex base, uint32_t field_index) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_PTR_FIELD;
key.data.ptr_field.ty = ptr_type;
key.data.ptr_field.base = base;
key.data.ptr_field.field_index = field_index;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- findNavInNamespace ---
@@ -2667,27 +2582,28 @@ static InternPoolIndex internPtrField(
// the Nav's name string from the owning ZIR's string_bytes.
// Returns the Nav index, or UINT32_MAX if not found.
-static uint32_t findNavInNamespace(uint32_t ns_idx, const char* name) {
- const SemaNamespace* ns = &s_namespaces[ns_idx];
+static uint32_t findNavInNamespace(
+ Sema* sema, uint32_t ns_idx, const char* name) {
+ const ZcuNamespace* ns = &sema->zcu->namespaces[ns_idx];
// Nav names come from ZIR string_bytes (normal modules) or IP
// string_bytes (compiler-generated builtin module without ZIR).
const uint8_t* string_bytes;
- if (s_loaded_modules[ns->file_idx].has_zir) {
- string_bytes = s_loaded_modules[ns->file_idx].zir.string_bytes;
- } else if (s_module_ip) {
- string_bytes = s_module_ip->string_bytes;
+ if (sema->zcu->files[ns->file_idx].has_zir) {
+ string_bytes = sema->zcu->files[ns->file_idx].zir.string_bytes;
+ } else if (sema->ip) {
+ string_bytes = sema->ip->string_bytes;
} else {
return UINT32_MAX;
}
for (uint32_t i = 0; i < ns->pub_nav_count; i++) {
- const Nav* nav = ipGetNav(ns->pub_navs[i]);
+ const Nav* nav = ipGetNav(sema->ip, ns->pub_navs[i]);
const char* nav_name = (const char*)&string_bytes[nav->name];
if (strcmp(nav_name, name) == 0)
return ns->pub_navs[i];
}
for (uint32_t i = 0; i < ns->priv_nav_count; i++) {
- const Nav* nav = ipGetNav(ns->priv_navs[i]);
+ const Nav* nav = ipGetNav(sema->ip, ns->priv_navs[i]);
const char* nav_name = (const char*)&string_bytes[nav->name];
if (strcmp(nav_name, name) == 0)
return ns->priv_navs[i];
@@ -2696,19 +2612,21 @@ static uint32_t findNavInNamespace(uint32_t ns_idx, const char* name) {
}
// Forward declarations.
-static void resolveModuleDeclImports(uint32_t file_idx, uint32_t depth);
-static uint32_t doImport(const char* source_dir, const char* import_string);
+static void resolveModuleDeclImports(
+ Sema* sema, uint32_t file_idx, uint32_t depth);
+static uint32_t doImport(
+ Sema* sema, const char* source_dir, const char* import_string);
// Forward declarations for import resolution functions.
static const char* findDeclImportPathFromZir(
const Zir* zir, uint32_t decl_inst);
-static bool resolveImportPath(const char* source_dir, const char* import_path,
- char* out_full, size_t out_size);
+static bool resolveImportPath(const Sema* sema, const char* source_dir,
+ const char* import_path, char* out_full, size_t out_size);
// Forward declaration (defined later).
-static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx);
-static void analyzeMemoizedStateC(void);
-static InternPoolIndex getBuiltinTypeC(int builtin_idx);
+static InternPoolIndex ensureNavValUpToDate(Sema* sema, uint32_t nav_idx);
+static void analyzeMemoizedStateC(Sema* sema);
+static InternPoolIndex getBuiltinTypeC(Sema* sema, int builtin_idx);
// Forward declaration for getValueBodyFromZir (defined later at ~line 7032).
static void getValueBodyFromZir(const Zir* zir, uint32_t decl_inst,
@@ -2722,7 +2640,8 @@ static void getTypeBodyFromZir(const Zir* zir, uint32_t decl_inst,
// For instruction refs, resolves ZIR_INST_INT and ZIR_INST_AS_NODE to
// comptime_int. Returns IP_INDEX_NONE on failure.
// Ported from Sema.zig resolveInst for the limited case of comptime ints.
-static InternPoolIndex resolveZirRefValue(const Zir* zir, uint32_t ref) {
+static InternPoolIndex resolveZirRefValue(
+ Sema* sema, const Zir* zir, uint32_t ref) {
if (ref < ZIR_REF_START_INDEX)
return ref; // pre-interned: maps directly to IP index
@@ -2739,7 +2658,7 @@ static InternPoolIndex resolveZirRefValue(const Zir* zir, uint32_t ref) {
key.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE;
key.data.int_val.value_lo = val;
key.data.int_val.is_negative = false;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
if (tag == ZIR_INST_AS_NODE) {
// as_node uses pl_node data: { src_node, payload_index }.
@@ -2747,7 +2666,7 @@ static InternPoolIndex resolveZirRefValue(const Zir* zir, uint32_t ref) {
// We ignore dest_type and recursively resolve the operand.
uint32_t payload_index = zir->inst_datas[inst].pl_node.payload_index;
uint32_t operand_ref = zir->extra[payload_index + 1];
- return resolveZirRefValue(zir, operand_ref);
+ return resolveZirRefValue(sema, zir, operand_ref);
}
return IP_INDEX_NONE;
}
@@ -2757,9 +2676,9 @@ static InternPoolIndex resolveZirRefValue(const Zir* zir, uint32_t ref) {
// Returns the interned int_small IP index.
// Ported from PerThread.zig getCoerced for integer coercion.
static InternPoolIndex coerceIntToTagType(
- InternPoolIndex comptime_int_ip, InternPoolIndex tag_type) {
+ Sema* sema, InternPoolIndex comptime_int_ip, InternPoolIndex tag_type) {
// Get the value from the comptime_int entry.
- InternPoolKey src = ipIndexToKey(s_module_ip, comptime_int_ip);
+ InternPoolKey src = ipIndexToKey(sema->ip, comptime_int_ip);
uint64_t val = src.data.int_val.value_lo;
bool neg = src.data.int_val.is_negative;
@@ -2770,18 +2689,19 @@ static InternPoolIndex coerceIntToTagType(
key.data.int_val.ty = tag_type;
key.data.int_val.value_lo = val;
key.data.int_val.is_negative = neg;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// Forward declarations for mutually recursive type resolvers.
-static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx);
+static InternPoolIndex ensureNavValUpToDate(Sema* sema, uint32_t nav_idx);
static InternPoolIndex resolveCgBuiltinField(
- uint32_t field_nav, const char* field_name);
-static InternPoolIndex internTypedInt(InternPoolIndex tag_type, uint64_t val);
-static InternPoolIndex internFuncType(InternPoolIndex return_type,
+ Sema* sema, uint32_t field_nav, const char* field_name);
+static InternPoolIndex internTypedInt(
+ Sema* sema, InternPoolIndex tag_type, uint64_t val);
+static InternPoolIndex internFuncType(Sema* sema, InternPoolIndex return_type,
uint32_t param_count, uint8_t cc, bool is_noinline);
static InternPoolIndex internFuncDecl(
- uint32_t owner_nav, InternPoolIndex func_type);
+ Sema* sema, uint32_t owner_nav, InternPoolIndex func_type);
// --- resolveEnumDeclFromZir ---
// Parse an enum_decl extended ZIR instruction and create IP entries.
@@ -2789,7 +2709,7 @@ static InternPoolIndex internFuncDecl(
// Returns the IP index of the enum type, or IP_INDEX_NONE on failure.
// Ported from Sema.zig zirEnumDecl + resolveDeclaredEnumInner.
static InternPoolIndex resolveEnumDeclFromZir(
- const Zir* zir, uint32_t enum_inst, uint32_t nav_idx) {
+ Sema* sema, const Zir* zir, uint32_t enum_inst, uint32_t nav_idx) {
if (zir->inst_tags[enum_inst] != ZIR_INST_EXTENDED)
return IP_INDEX_NONE;
if (zir->inst_datas[enum_inst].extended.opcode != ZIR_EXT_ENUM_DECL)
@@ -2838,17 +2758,18 @@ static InternPoolIndex resolveEnumDeclFromZir(
InternPoolKey ek;
memset(&ek, 0, sizeof(ek));
ek.tag = IP_KEY_ENUM_TYPE;
- ek.data.enum_type = s_next_struct_hash++;
- InternPoolIndex enum_ip = ipIntern(s_module_ip, ek);
+ ek.data.enum_type = sema->zcu->next_struct_hash++;
+ InternPoolIndex enum_ip = ipIntern(sema->ip, ek);
// Create namespace and scan declarations (e.g. WindowsVersion.Range).
// Matches Zig compiler's getEnumType which creates namespace before
// resolveDeclaredEnumInner processes field values.
if (decls_len > 0 && nav_idx != UINT32_MAX) {
uint32_t enum_file_idx
- = s_namespaces[ipGetNav(nav_idx)->namespace_idx].file_idx;
- uint32_t ens = createNamespace(enum_ip, enum_file_idx);
- scanNamespaceC(ens, decl_insts, decls_len, zir);
+ = sema->zcu->namespaces[ipGetNav(sema->ip, nav_idx)->namespace_idx]
+ .file_idx;
+ uint32_t ens = createNamespace(sema, enum_ip, enum_file_idx);
+ scanNamespaceC(sema, ens, decl_insts, decls_len, zir);
}
// Resolve the integer tag type (runs AFTER enum_type creation,
@@ -2875,7 +2796,7 @@ static InternPoolIndex resolveEnumDeclFromZir(
itk.tag = IP_KEY_INT_TYPE;
itk.data.int_type.bits = bits;
itk.data.int_type.signedness = ip_sign;
- int_tag_type = ipIntern(s_module_ip, itk);
+ int_tag_type = ipIntern(sema->ip, itk);
}
}
}
@@ -2898,7 +2819,7 @@ static InternPoolIndex resolveEnumDeclFromZir(
itk.tag = IP_KEY_INT_TYPE;
itk.data.int_type.bits = (uint16_t)bits;
itk.data.int_type.signedness = 0;
- int_tag_type = ipIntern(s_module_ip, itk);
+ int_tag_type = ipIntern(sema->ip, itk);
}
// Read bit bags to determine which fields have explicit values.
@@ -2924,43 +2845,44 @@ static InternPoolIndex resolveEnumDeclFromZir(
uint32_t val_ref = zir->extra[extra_index++];
// Step 1: resolve to comptime_int.
- InternPoolIndex comptime_ip = resolveZirRefValue(zir, val_ref);
+ InternPoolIndex comptime_ip
+ = resolveZirRefValue(sema, zir, val_ref);
if (comptime_ip == IP_INDEX_NONE) {
auto_val++;
continue;
}
// Get the actual integer value for auto_val tracking.
- InternPoolKey ct_key = ipIndexToKey(s_module_ip, comptime_ip);
+ InternPoolKey ct_key = ipIndexToKey(sema->ip, comptime_ip);
auto_val = ct_key.data.int_val.value_lo + 1;
// Step 2: coerce to tag type.
if (int_tag_type != IP_INDEX_NONE)
- (void)coerceIntToTagType(comptime_ip, int_tag_type);
+ (void)coerceIntToTagType(sema, comptime_ip, int_tag_type);
} else {
// Auto-increment: intern as typed int directly.
if (int_tag_type != IP_INDEX_NONE && auto_val > 0) {
// First intern comptime_int (if not pre-interned).
// Use ipForceIntern for values >= threshold to keep
// them out of the hash table (see
- // s_enum_force_intern_threshold).
+ // sema->zcu->enum_force_intern_threshold).
InternPoolKey ct;
memset(&ct, 0, sizeof(ct));
ct.tag = IP_KEY_INT;
ct.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE;
ct.data.int_val.value_lo = auto_val;
InternPoolIndex ct_ip;
- if (s_enum_force_intern_threshold > 0
- && auto_val >= s_enum_force_intern_threshold) {
- ct_ip = ipForceIntern(s_module_ip, ct);
+ if (sema->zcu->enum_force_intern_threshold > 0
+ && auto_val >= sema->zcu->enum_force_intern_threshold) {
+ ct_ip = ipForceIntern(sema->ip, ct);
} else {
- ct_ip = ipIntern(s_module_ip, ct);
+ ct_ip = ipIntern(sema->ip, ct);
}
// Then coerce to tag type.
- (void)coerceIntToTagType(ct_ip, int_tag_type);
+ (void)coerceIntToTagType(sema, ct_ip, int_tag_type);
} else if (int_tag_type != IP_INDEX_NONE) {
// Value 0: comptime_int(0) is pre-interned.
- (void)coerceIntToTagType(IP_INDEX_ZERO, int_tag_type);
+ (void)coerceIntToTagType(sema, IP_INDEX_ZERO, int_tag_type);
}
auto_val++;
}
@@ -2968,10 +2890,10 @@ static InternPoolIndex resolveEnumDeclFromZir(
// Set the Nav's resolved type and create ptr_nav.
if (nav_idx != UINT32_MAX) {
- Nav* nav = ipGetNav(nav_idx);
+ Nav* nav = ipGetNav(sema->ip, nav_idx);
nav->resolved_type = enum_ip;
- InternPoolIndex ptr_type = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(ptr_type, nav_idx);
+ InternPoolIndex ptr_type = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, ptr_type, nav_idx);
}
return enum_ip;
@@ -3045,8 +2967,8 @@ static uint32_t findEnumFieldByName(
// Parses the enum_decl ZIR to find the tag type and computes the value.
// For auto-enums, values are 0, 1, 2, ... For explicit enums, reads the
// explicit values from ZIR. Returns IP_INDEX_NONE on failure.
-static InternPoolIndex getEnumFieldIntVal(
- const Zir* zir, uint32_t enum_inst, uint32_t target_field_idx) {
+static InternPoolIndex getEnumFieldIntVal(Sema* sema, const Zir* zir,
+ uint32_t enum_inst, uint32_t target_field_idx) {
uint16_t small = zir->inst_datas[enum_inst].extended.small;
uint32_t operand = zir->inst_datas[enum_inst].extended.operand;
@@ -3094,7 +3016,7 @@ static InternPoolIndex getEnumFieldIntVal(
itk.tag = IP_KEY_INT_TYPE;
itk.data.int_type.bits = bits;
itk.data.int_type.signedness = ip_sign;
- int_tag_type = ipIntern(s_module_ip, itk);
+ int_tag_type = ipIntern(sema->ip, itk);
}
}
}
@@ -3116,7 +3038,7 @@ static InternPoolIndex getEnumFieldIntVal(
itk.tag = IP_KEY_INT_TYPE;
itk.data.int_type.bits = (uint16_t)bits;
itk.data.int_type.signedness = 0;
- int_tag_type = ipIntern(s_module_ip, itk);
+ int_tag_type = ipIntern(sema->ip, itk);
}
if (int_tag_type == IP_INDEX_NONE)
@@ -3124,18 +3046,18 @@ static InternPoolIndex getEnumFieldIntVal(
// Compute the field's integer value (auto-increment, skipping
// explicit values). Simple case: auto-enum field_idx maps to value.
- return internTypedInt(int_tag_type, target_field_idx);
+ return internTypedInt(sema, int_tag_type, target_field_idx);
}
// Forward declaration: resolves a ZIR instruction to an IP type index.
-static InternPoolIndex resolveZirTypeInst(
- const Zir* zir, uint32_t inst, uint32_t struct_ns, uint32_t file_idx);
+static InternPoolIndex resolveZirTypeInst(Sema* sema, const Zir* zir,
+ uint32_t inst, uint32_t struct_ns, uint32_t file_idx);
// Forward declarations for mutual recursion.
-static InternPoolIndex resolveZirTypeInst(
- const Zir* zir, uint32_t inst, uint32_t struct_ns, uint32_t file_idx);
-static InternPoolIndex resolveZirTypeRef(
- const Zir* zir, ZirInstRef ref, uint32_t struct_ns, uint32_t file_idx);
+static InternPoolIndex resolveZirTypeInst(Sema* sema, const Zir* zir,
+ uint32_t inst, uint32_t struct_ns, uint32_t file_idx);
+static InternPoolIndex resolveZirTypeRef(Sema* sema, const Zir* zir,
+ ZirInstRef ref, uint32_t struct_ns, uint32_t file_idx);
// --- resolveZirPtrTypeInst ---
// Resolve a ZIR ptr_type instruction to create IP pointer/slice type entries.
@@ -3143,8 +3065,8 @@ static InternPoolIndex resolveZirTypeRef(
// For single/many/c pointers: creates a pointer type.
// Returns the final IP index for the type.
// Ported from Sema.zig zirPtrType.
-static InternPoolIndex resolveZirPtrTypeInst(
- const Zir* zir, uint32_t inst, uint32_t struct_ns, uint32_t file_idx) {
+static InternPoolIndex resolveZirPtrTypeInst(Sema* sema, const Zir* zir,
+ uint32_t inst, uint32_t struct_ns, uint32_t file_idx) {
uint8_t flags = zir->inst_datas[inst].ptr_type.flags;
uint8_t size = zir->inst_datas[inst].ptr_type.size;
uint32_t pi = zir->inst_datas[inst].ptr_type.payload_index;
@@ -3177,7 +3099,8 @@ static InternPoolIndex resolveZirPtrTypeInst(
} else {
// Instruction ref — use resolveZirTypeInst for full resolution.
uint32_t child_inst = elem_ref - ZIR_REF_START_INDEX;
- child_ip = resolveZirTypeInst(zir, child_inst, struct_ns, file_idx);
+ child_ip
+ = resolveZirTypeInst(sema, zir, child_inst, struct_ns, file_idx);
}
if (child_ip == IP_INDEX_NONE)
return IP_INDEX_NONE;
@@ -3201,7 +3124,7 @@ static InternPoolIndex resolveZirPtrTypeInst(
ptr_key.data.ptr_type.sentinel = sentinel_ip;
ptr_key.data.ptr_type.flags = ptr_flags;
ptr_key.data.ptr_type.packed_offset = 0;
- InternPoolIndex ptr_ip = ipIntern(s_module_ip, ptr_key);
+ InternPoolIndex ptr_ip = ipIntern(sema->ip, ptr_key);
if (size == 2) {
// Slice type wrapping the many-pointer.
@@ -3209,13 +3132,14 @@ static InternPoolIndex resolveZirPtrTypeInst(
memset(&slice_key, 0, sizeof(slice_key));
slice_key.tag = IP_KEY_SLICE;
slice_key.data.slice = ptr_ip;
- return ipIntern(s_module_ip, slice_key);
+ return ipIntern(sema->ip, slice_key);
}
return ptr_ip;
}
// Forward declaration for findNamespaceForType (used by field_val handler).
-static uint32_t findNamespaceForType(InternPoolIndex type_ip);
+static uint32_t findNamespaceForType(
+ const Sema* sema, InternPoolIndex type_ip);
// --- resolveZirTypeInst ---
// Resolve a ZIR instruction to an IP type index.
@@ -3223,26 +3147,26 @@ static uint32_t findNamespaceForType(InternPoolIndex type_ip);
// For decl_val, searches struct_ns then file root namespace.
// For field_val, resolves base type then looks up member in its namespace.
// Ported from Sema.zig resolveInst dispatch for type instructions.
-static InternPoolIndex resolveZirTypeInst(
- const Zir* zir, uint32_t inst, uint32_t struct_ns, uint32_t file_idx) {
+static InternPoolIndex resolveZirTypeInst(Sema* sema, const Zir* zir,
+ uint32_t inst, uint32_t struct_ns, uint32_t file_idx) {
if (inst >= zir->inst_len)
return IP_INDEX_NONE;
ZirInstTag tag = zir->inst_tags[inst];
if (tag == ZIR_INST_PTR_TYPE)
- return resolveZirPtrTypeInst(zir, inst, struct_ns, file_idx);
+ return resolveZirPtrTypeInst(sema, zir, inst, struct_ns, file_idx);
if (tag == ZIR_INST_OPTIONAL_TYPE) {
ZirInstRef child_ref = zir->inst_datas[inst].un_node.operand;
InternPoolIndex child_ip
- = resolveZirTypeRef(zir, child_ref, struct_ns, file_idx);
+ = resolveZirTypeRef(sema, zir, child_ref, struct_ns, file_idx);
if (child_ip == IP_INDEX_NONE)
return IP_INDEX_NONE;
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_OPT_TYPE;
key.data.opt_type = child_ip;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
if (tag == ZIR_INST_DECL_VAL) {
@@ -3253,28 +3177,34 @@ static InternPoolIndex resolveZirTypeInst(
uint32_t nav = UINT32_MAX;
uint32_t search_ns = struct_ns;
for (uint32_t depth = 0; depth < 8 && nav == UINT32_MAX; depth++) {
- nav = findNavInNamespace(search_ns, name);
+ nav = findNavInNamespace(sema, search_ns, name);
if (nav != UINT32_MAX)
break;
// Find parent: the nav that resolves to this namespace's owner.
- InternPoolIndex owner = s_namespaces[search_ns].owner_type;
+ InternPoolIndex owner
+ = sema->zcu->namespaces[search_ns].owner_type;
if (owner == IP_INDEX_NONE)
break;
uint32_t parent_ns = UINT32_MAX;
for (uint32_t nsi = 0;
- nsi < s_num_namespaces && parent_ns == UINT32_MAX; nsi++) {
- const SemaNamespace* pns = &s_namespaces[nsi];
+ nsi < sema->zcu->num_namespaces && parent_ns == UINT32_MAX;
+ nsi++) {
+ const ZcuNamespace* pns = &sema->zcu->namespaces[nsi];
for (uint32_t k = 0; k < pns->pub_nav_count; k++) {
- if (ipGetNav(pns->pub_navs[k])->resolved_type == owner) {
- parent_ns = ipGetNav(pns->pub_navs[k])->namespace_idx;
+ if (ipGetNav(sema->ip, pns->pub_navs[k])->resolved_type
+ == owner) {
+ parent_ns = ipGetNav(sema->ip, pns->pub_navs[k])
+ ->namespace_idx;
break;
}
}
if (parent_ns != UINT32_MAX)
break;
for (uint32_t k = 0; k < pns->priv_nav_count; k++) {
- if (ipGetNav(pns->priv_navs[k])->resolved_type == owner) {
- parent_ns = ipGetNav(pns->priv_navs[k])->namespace_idx;
+ if (ipGetNav(sema->ip, pns->priv_navs[k])->resolved_type
+ == owner) {
+ parent_ns = ipGetNav(sema->ip, pns->priv_navs[k])
+ ->namespace_idx;
break;
}
}
@@ -3284,27 +3214,28 @@ static InternPoolIndex resolveZirTypeInst(
search_ns = parent_ns;
}
if (nav == UINT32_MAX) {
- uint32_t root_ns = s_file_namespace[file_idx];
- nav = findNavInNamespace(root_ns, name);
+ uint32_t root_ns = sema->zcu->file_namespaces[file_idx];
+ nav = findNavInNamespace(sema, root_ns, name);
}
if (nav != UINT32_MAX) {
- InternPoolIndex result = ensureNavValUpToDate(nav);
+ InternPoolIndex result = ensureNavValUpToDate(sema, nav);
if (result != IP_INDEX_NONE && result != IP_INDEX_VOID_TYPE) {
// Create ptr_type + ptr_nav matching analyzeNavRefInner.
// During main analysis: all navs, typeOf(val) child.
// During preamble: type decls only, type_type child.
- if (result < s_module_ip->items_len) {
- if (s_in_main_analysis) {
- InternPoolIndex val_ty = ipTypeOf(s_module_ip, result);
- InternPoolIndex dv_ptr_ty = internPtrConst(val_ty);
- (void)internNavPtr(dv_ptr_ty, nav);
+ if (result < sema->ip->items_len) {
+ if (sema->zcu->in_main_analysis) {
+ InternPoolIndex val_ty = ipTypeOf(sema->ip, result);
+ InternPoolIndex dv_ptr_ty
+ = internPtrConst(sema, val_ty);
+ (void)internNavPtr(sema, dv_ptr_ty, nav);
} else {
- InternPoolKeyTag kt = s_module_ip->items[result].tag;
+ InternPoolKeyTag kt = sema->ip->items[result].tag;
if (kt == IP_KEY_STRUCT_TYPE || kt == IP_KEY_ENUM_TYPE
|| kt == IP_KEY_UNION_TYPE) {
InternPoolIndex dv_ptr_ty
- = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(dv_ptr_ty, nav);
+ = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, dv_ptr_ty, nav);
}
}
}
@@ -3315,11 +3246,11 @@ static InternPoolIndex resolveZirTypeInst(
// Also reached when ensureNavValUpToDate returns VOID_TYPE,
// which happens when the body contains type instructions
// (optional_type, ptr_type) that analyzeNavValC can't handle.
- const Nav* tnav = ipGetNav(nav);
+ const Nav* tnav = ipGetNav(sema->ip, nav);
uint32_t tnns = tnav->namespace_idx;
- uint32_t tnfi = s_namespaces[tnns].file_idx;
- if (s_loaded_modules[tnfi].has_zir) {
- const Zir* tzir = &s_loaded_modules[tnfi].zir;
+ uint32_t tnfi = sema->zcu->namespaces[tnns].file_idx;
+ if (sema->zcu->files[tnfi].has_zir) {
+ const Zir* tzir = &sema->zcu->files[tnfi].zir;
const uint32_t* tbody = NULL;
uint32_t tbody_len = 0;
getValueBodyFromZir(tzir, tnav->zir_index, &tbody, &tbody_len);
@@ -3331,16 +3262,16 @@ static InternPoolIndex resolveZirTypeInst(
ZirInstRef op
= tzir->inst_datas[last_inst].break_data.operand;
InternPoolIndex alias_result
- = resolveZirTypeRef(tzir, op, tnns, tnfi);
+ = resolveZirTypeRef(sema, tzir, op, tnns, tnfi);
if (alias_result != IP_INDEX_NONE) {
- Nav* wnav = ipGetNav(nav);
+ Nav* wnav = ipGetNav(sema->ip, nav);
wnav->resolved_type = alias_result;
// Create ptr_nav for the alias declaration,
// matching analyzeNavRefInner which creates
// a ptr_nav for every resolved nav reference.
InternPoolIndex ptr_ty
- = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(ptr_ty, nav);
+ = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, ptr_ty, nav);
return alias_result;
}
}
@@ -3364,35 +3295,36 @@ static InternPoolIndex resolveZirTypeInst(
// Resolve the base type.
InternPoolIndex base
- = resolveZirTypeRef(zir, lhs_ref, struct_ns, file_idx);
+ = resolveZirTypeRef(sema, zir, lhs_ref, struct_ns, file_idx);
if (base == IP_INDEX_NONE)
return IP_INDEX_NONE;
// Find the namespace for the base type.
- uint32_t base_ns = findNamespaceForType(base);
+ uint32_t base_ns = findNamespaceForType(sema, base);
if (base_ns == UINT32_MAX)
return IP_INDEX_NONE;
// Look up the field name in the base type's namespace.
- uint32_t member_nav = findNavInNamespace(base_ns, fname);
+ uint32_t member_nav = findNavInNamespace(sema, base_ns, fname);
if (member_nav != UINT32_MAX) {
- InternPoolIndex result = ensureNavValUpToDate(member_nav);
+ InternPoolIndex result = ensureNavValUpToDate(sema, member_nav);
if (result != IP_INDEX_NONE) {
// Create ptr_type + ptr_nav matching analyzeNavRefInner.
// During main analysis, create for ALL navs using
// typeOf(val). During preamble, only for type decls.
- if (result < s_module_ip->items_len) {
- if (s_in_main_analysis) {
- InternPoolIndex val_ty = ipTypeOf(s_module_ip, result);
- InternPoolIndex nav_ptr_ty = internPtrConst(val_ty);
- (void)internNavPtr(nav_ptr_ty, member_nav);
+ if (result < sema->ip->items_len) {
+ if (sema->zcu->in_main_analysis) {
+ InternPoolIndex val_ty = ipTypeOf(sema->ip, result);
+ InternPoolIndex nav_ptr_ty
+ = internPtrConst(sema, val_ty);
+ (void)internNavPtr(sema, nav_ptr_ty, member_nav);
} else {
- InternPoolKeyTag kt = s_module_ip->items[result].tag;
+ InternPoolKeyTag kt = sema->ip->items[result].tag;
if (kt == IP_KEY_STRUCT_TYPE || kt == IP_KEY_ENUM_TYPE
|| kt == IP_KEY_UNION_TYPE) {
InternPoolIndex nav_ptr_ty
- = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(nav_ptr_ty, member_nav);
+ = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, nav_ptr_ty, member_nav);
}
}
}
@@ -3412,7 +3344,7 @@ static InternPoolIndex resolveZirTypeInst(
key.tag = IP_KEY_INT_TYPE;
key.data.int_type.bits = bits;
key.data.int_type.signedness = signedness;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// array_type: [N]T syntax. Payload is Bin (lhs=length, rhs=elem type).
@@ -3445,8 +3377,9 @@ static InternPoolIndex resolveZirTypeInst(
len_resolved = true;
// Intern int_comptime_int_u32(value) then int_usize(value),
// matching Sema.zig resolveInt coercion sequence.
- (void)internTypedInt(IP_INDEX_COMPTIME_INT_TYPE, arr_len);
- (void)internTypedInt(IP_INDEX_USIZE_TYPE, arr_len);
+ (void)internTypedInt(
+ sema, IP_INDEX_COMPTIME_INT_TYPE, arr_len);
+ (void)internTypedInt(sema, IP_INDEX_USIZE_TYPE, arr_len);
}
}
if (!len_resolved)
@@ -3454,7 +3387,7 @@ static InternPoolIndex resolveZirTypeInst(
// Resolve element type.
InternPoolIndex child_ip
- = resolveZirTypeRef(zir, elem_ref, struct_ns, file_idx);
+ = resolveZirTypeRef(sema, zir, elem_ref, struct_ns, file_idx);
if (child_ip == IP_INDEX_NONE)
return IP_INDEX_NONE;
@@ -3464,7 +3397,7 @@ static InternPoolIndex resolveZirTypeInst(
key.data.array_type.len = arr_len;
key.data.array_type.child = child_ip;
key.data.array_type.sentinel = sentinel_ip;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
return IP_INDEX_NONE;
@@ -3474,20 +3407,20 @@ static InternPoolIndex resolveZirTypeInst(
// Resolve a ZIR Ref to an IP type index.
// For pre-interned refs, returns the ref directly.
// For instruction refs, dispatches to resolveZirTypeInst.
-static InternPoolIndex resolveZirTypeRef(
- const Zir* zir, ZirInstRef ref, uint32_t struct_ns, uint32_t file_idx) {
+static InternPoolIndex resolveZirTypeRef(Sema* sema, const Zir* zir,
+ ZirInstRef ref, uint32_t struct_ns, uint32_t file_idx) {
if (ref < ZIR_REF_START_INDEX)
return ref;
return resolveZirTypeInst(
- zir, ref - ZIR_REF_START_INDEX, struct_ns, file_idx);
+ sema, zir, ref - ZIR_REF_START_INDEX, struct_ns, file_idx);
}
// --- resolveStructFieldTypesC ---
// Resolve struct field types from ZIR, creating any needed IP entries
// for compound types (pointers, slices, optionals, etc.).
// Ported from Sema.zig structFields + resolveStructFully.
-static void resolveStructFieldTypesC(const Zir* zir, uint32_t struct_inst,
- uint32_t struct_ns, uint32_t file_idx) {
+static void resolveStructFieldTypesC(Sema* sema, const Zir* zir,
+ uint32_t struct_inst, uint32_t struct_ns, uint32_t file_idx) {
if (zir->inst_tags[struct_inst] != ZIR_INST_EXTENDED)
return;
if (zir->inst_datas[struct_inst].extended.opcode != ZIR_EXT_STRUCT_DECL)
@@ -3583,13 +3516,13 @@ static void resolveStructFieldTypesC(const Zir* zir, uint32_t struct_inst,
if (last_zi < zir->inst_len
&& zir->inst_tags[last_zi] == ZIR_INST_BREAK_INLINE) {
ZirInstRef op = zir->inst_datas[last_zi].break_data.operand;
- (void)resolveZirTypeRef(zir, op, struct_ns, file_idx);
+ (void)resolveZirTypeRef(sema, zir, op, struct_ns, file_idx);
}
} else if (!field_info[fi].has_type_body
&& field_info[fi].type_ref >= ZIR_REF_START_INDEX) {
// Non-body field type that's an instruction ref.
(void)resolveZirTypeRef(
- zir, field_info[fi].type_ref, struct_ns, file_idx);
+ sema, zir, field_info[fi].type_ref, struct_ns, file_idx);
}
sei += field_info[fi].type_body_len;
sei += field_info[fi].align_body_len;
@@ -3602,16 +3535,17 @@ static void resolveStructFieldTypesC(const Zir* zir, uint32_t struct_inst,
// Find the ZIR enum_decl instruction for an enum type nav.
// Parses the nav's declaration value body to find the EXTENDED/ENUM_DECL.
// Sets *out_zir to the ZIR. Returns UINT32_MAX on failure.
-static uint32_t findEnumDeclForNav(uint32_t nav_idx, const Zir** out_zir) {
- const Nav* n = ipGetNav(nav_idx);
+static uint32_t findEnumDeclForNav(
+ Sema* sema, uint32_t nav_idx, const Zir** out_zir) {
+ const Nav* n = ipGetNav(sema->ip, nav_idx);
uint32_t ns_idx = n->namespace_idx;
- if (ns_idx == UINT32_MAX || ns_idx >= s_num_namespaces)
+ if (ns_idx == UINT32_MAX || ns_idx >= sema->zcu->num_namespaces)
return UINT32_MAX;
- uint32_t file_idx = s_namespaces[ns_idx].file_idx;
- if (file_idx >= s_num_loaded_modules
- || !s_loaded_modules[file_idx].has_zir)
+ uint32_t file_idx = sema->zcu->namespaces[ns_idx].file_idx;
+ if (file_idx >= sema->zcu->num_files
+ || !sema->zcu->files[file_idx].has_zir)
return UINT32_MAX;
- const Zir* zir = &s_loaded_modules[file_idx].zir;
+ const Zir* zir = &sema->zcu->files[file_idx].zir;
*out_zir = zir;
const uint32_t* vb = NULL;
@@ -3636,8 +3570,8 @@ static uint32_t findEnumDeclForNav(uint32_t nav_idx, const Zir** out_zir) {
// zir - the ZIR containing the struct_decl
// struct_inst - ZIR instruction index of the struct_decl
// struct_ns - the struct's namespace index in s_namespaces
-static void resolveStructFieldInitsC(const Zir* zir, uint32_t struct_inst,
- uint32_t struct_ns, uint32_t file_idx) {
+static void resolveStructFieldInitsC(Sema* sema, const Zir* zir,
+ uint32_t struct_inst, uint32_t struct_ns, uint32_t file_idx) {
if (zir->inst_tags[struct_inst] != ZIR_INST_EXTENDED)
return;
if (zir->inst_datas[struct_inst].extended.opcode != ZIR_EXT_STRUCT_DECL)
@@ -3766,8 +3700,8 @@ static void resolveStructFieldInitsC(const Zir* zir, uint32_t struct_inst,
&& zir->inst_tags[tb_last] == ZIR_INST_BREAK_INLINE) {
ZirInstRef type_op
= zir->inst_datas[tb_last].break_data.operand;
- opt_ty
- = resolveZirTypeRef(zir, type_op, struct_ns, file_idx);
+ opt_ty = resolveZirTypeRef(
+ sema, zir, type_op, struct_ns, file_idx);
}
}
if (opt_ty != IP_INDEX_NONE) {
@@ -3775,7 +3709,7 @@ static void resolveStructFieldInitsC(const Zir* zir, uint32_t struct_inst,
memset(&ok, 0, sizeof(ok));
ok.tag = IP_KEY_OPT;
ok.data.opt = opt_ty;
- (void)ipIntern(s_module_ip, ok);
+ (void)ipIntern(sema->ip, ok);
}
continue;
}
@@ -3804,15 +3738,16 @@ static void resolveStructFieldInitsC(const Zir* zir, uint32_t struct_inst,
// then fall back to the file root namespace.
uint32_t ns_search[2];
ns_search[0] = struct_ns;
- ns_search[1] = s_file_namespace[file_idx];
+ ns_search[1] = sema->zcu->file_namespaces[file_idx];
bool found = false;
for (uint32_t nk = 0; nk < 2 && !found; nk++) {
- const SemaNamespace* sns = &s_namespaces[ns_search[nk]];
+ const ZcuNamespace* sns
+ = &sema->zcu->namespaces[ns_search[nk]];
for (uint32_t j = 0; j < sns->pub_nav_count; j++) {
- const Nav* enav = ipGetNav(sns->pub_navs[j]);
+ const Nav* enav = ipGetNav(sema->ip, sns->pub_navs[j]);
if (enav->resolved_type == IP_INDEX_NONE)
continue;
- if (s_module_ip->items[enav->resolved_type].tag
+ if (sema->ip->items[enav->resolved_type].tag
!= IP_KEY_ENUM_TYPE)
continue;
@@ -3842,7 +3777,7 @@ static void resolveStructFieldInitsC(const Zir* zir, uint32_t struct_inst,
// Find the enum's tag type from ZIR and compute
// the int value for this field.
InternPoolIndex int_val
- = getEnumFieldIntVal(zir, ed_inst, field_idx);
+ = getEnumFieldIntVal(sema, zir, ed_inst, field_idx);
if (int_val == IP_INDEX_NONE)
break;
@@ -3851,7 +3786,7 @@ static void resolveStructFieldInitsC(const Zir* zir, uint32_t struct_inst,
etk.tag = IP_KEY_ENUM_TAG;
etk.data.enum_tag.ty = enum_ip;
etk.data.enum_tag.int_val = int_val;
- (void)ipIntern(s_module_ip, etk);
+ (void)ipIntern(sema->ip, etk);
found = true;
break;
}
@@ -3894,14 +3829,14 @@ static void resolveStructFieldInitsC(const Zir* zir, uint32_t struct_inst,
itk.tag = IP_KEY_INT_TYPE;
itk.data.int_type.bits = bits;
itk.data.int_type.signedness = ip_sign;
- field_ty = ipIntern(s_module_ip, itk);
+ field_ty = ipIntern(sema->ip, itk);
}
}
}
}
if (field_ty != IP_INDEX_NONE)
- (void)internTypedInt(field_ty, val);
+ (void)internTypedInt(sema, field_ty, val);
}
}
}
@@ -3912,7 +3847,7 @@ static void resolveStructFieldInitsC(const Zir* zir, uint32_t struct_inst,
// Returns the IP index of the struct type, or IP_INDEX_NONE on failure.
// Ported from Sema.zig zirStructDecl (minimal: type + namespace only).
static InternPoolIndex resolveStructDeclFromZir(
- const Zir* zir, uint32_t struct_inst, uint32_t nav_idx) {
+ Sema* sema, const Zir* zir, uint32_t struct_inst, uint32_t nav_idx) {
if (zir->inst_tags[struct_inst] != ZIR_INST_EXTENDED)
return IP_INDEX_NONE;
if (zir->inst_datas[struct_inst].extended.opcode != ZIR_EXT_STRUCT_DECL)
@@ -3958,24 +3893,24 @@ static InternPoolIndex resolveStructDeclFromZir(
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_STRUCT_TYPE;
- key.data.struct_type = s_next_struct_hash++;
- InternPoolIndex struct_ip = ipIntern(s_module_ip, key);
+ key.data.struct_type = sema->zcu->next_struct_hash++;
+ InternPoolIndex struct_ip = ipIntern(sema->ip, key);
// Create namespace for the struct.
- const Nav* nav = ipGetNav(nav_idx);
+ const Nav* nav = ipGetNav(sema->ip, nav_idx);
uint32_t ns_idx = createNamespace(
- struct_ip, s_namespaces[nav->namespace_idx].file_idx);
+ sema, struct_ip, sema->zcu->namespaces[nav->namespace_idx].file_idx);
// Scan namespace declarations.
const uint32_t* decl_insts = &zir->extra[extra_index];
- scanNamespaceC(ns_idx, decl_insts, decls_len, zir);
+ scanNamespaceC(sema, ns_idx, decl_insts, decls_len, zir);
// Set the Nav's resolved type and create ptr_nav.
{
- Nav* wnav = ipGetNav(nav_idx);
+ Nav* wnav = ipGetNav(sema->ip, nav_idx);
wnav->resolved_type = struct_ip;
- InternPoolIndex ptr_type = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(ptr_type, nav_idx);
+ InternPoolIndex ptr_type = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, ptr_type, nav_idx);
}
return struct_ip;
@@ -3983,32 +3918,33 @@ static InternPoolIndex resolveStructDeclFromZir(
// --- findNamespaceForType ---
// Find the namespace owned by a given type IP index.
-static uint32_t findNamespaceForType(InternPoolIndex type_ip) {
- for (uint32_t i = 0; i < s_num_namespaces; i++) {
- if (s_namespaces[i].owner_type == type_ip)
+static uint32_t findNamespaceForType(
+ const Sema* sema, InternPoolIndex type_ip) {
+ for (uint32_t i = 0; i < sema->zcu->num_namespaces; i++) {
+ if (sema->zcu->namespaces[i].owner_type == type_ip)
return i;
}
return UINT32_MAX;
}
// Forward declarations for mutually recursive resolution.
-static bool resolveStructLayoutC(uint32_t nav_idx);
-static void resolveTypeFullyC(InternPoolIndex ip_idx);
-static void resolveStructFullyC(uint32_t nav_idx);
-static void resolveUnionFullyC(uint32_t nav_idx);
+static bool resolveStructLayoutC(Sema* sema, uint32_t nav_idx);
+static void resolveTypeFullyC(Sema* sema, InternPoolIndex ip_idx);
+static void resolveStructFullyC(Sema* sema, uint32_t nav_idx);
+static void resolveUnionFullyC(Sema* sema, uint32_t nav_idx);
// --- findNavForIPIndex ---
// Search all namespaces for a nav whose resolved_type matches ip_idx.
// Returns the nav index, or UINT32_MAX if not found.
-static uint32_t findNavForIPIndex(InternPoolIndex ip_idx) {
- for (uint32_t nsi = 0; nsi < s_num_namespaces; nsi++) {
- const SemaNamespace* ns = &s_namespaces[nsi];
+static uint32_t findNavForIPIndex(Sema* sema, InternPoolIndex ip_idx) {
+ for (uint32_t nsi = 0; nsi < sema->zcu->num_namespaces; nsi++) {
+ const ZcuNamespace* ns = &sema->zcu->namespaces[nsi];
for (uint32_t k = 0; k < ns->pub_nav_count; k++) {
- if (ipGetNav(ns->pub_navs[k])->resolved_type == ip_idx)
+ if (ipGetNav(sema->ip, ns->pub_navs[k])->resolved_type == ip_idx)
return ns->pub_navs[k];
}
for (uint32_t k = 0; k < ns->priv_nav_count; k++) {
- if (ipGetNav(ns->priv_navs[k])->resolved_type == ip_idx)
+ if (ipGetNav(sema->ip, ns->priv_navs[k])->resolved_type == ip_idx)
return ns->priv_navs[k];
}
}
@@ -4020,35 +3956,35 @@ static uint32_t findNavForIPIndex(InternPoolIndex ip_idx) {
// For struct/union types: calls resolveStructFullyC/resolveUnionFullyC.
// For compound types (pointer, optional, array, slice): recurses on child.
// For simple types (int, float, bool, void, etc.): no-op.
-static void resolveTypeFullyC(InternPoolIndex ip_idx) {
- if (ip_idx == IP_INDEX_NONE || ip_idx >= s_module_ip->items_len)
+static void resolveTypeFullyC(Sema* sema, InternPoolIndex ip_idx) {
+ if (ip_idx == IP_INDEX_NONE || ip_idx >= sema->ip->items_len)
return;
- InternPoolKeyTag tag = s_module_ip->items[ip_idx].tag;
+ InternPoolKeyTag tag = sema->ip->items[ip_idx].tag;
switch (tag) {
case IP_KEY_STRUCT_TYPE: {
- uint32_t nav = findNavForIPIndex(ip_idx);
+ uint32_t nav = findNavForIPIndex(sema, ip_idx);
if (nav != UINT32_MAX)
- resolveStructFullyC(nav);
+ resolveStructFullyC(sema, nav);
break;
}
case IP_KEY_UNION_TYPE: {
- uint32_t nav = findNavForIPIndex(ip_idx);
+ uint32_t nav = findNavForIPIndex(sema, ip_idx);
if (nav != UINT32_MAX)
- resolveUnionFullyC(nav);
+ resolveUnionFullyC(sema, nav);
break;
}
case IP_KEY_PTR_TYPE:
- resolveTypeFullyC(s_module_ip->items[ip_idx].data.ptr_type.child);
+ resolveTypeFullyC(sema, sema->ip->items[ip_idx].data.ptr_type.child);
break;
case IP_KEY_OPT_TYPE:
- resolveTypeFullyC(s_module_ip->items[ip_idx].data.opt_type);
+ resolveTypeFullyC(sema, sema->ip->items[ip_idx].data.opt_type);
break;
case IP_KEY_ARRAY_TYPE:
- resolveTypeFullyC(s_module_ip->items[ip_idx].data.array_type.child);
+ resolveTypeFullyC(sema, sema->ip->items[ip_idx].data.array_type.child);
break;
case IP_KEY_SLICE:
// Slice wraps a pointer type; resolve the pointer's child.
- resolveTypeFullyC(s_module_ip->items[ip_idx].data.slice);
+ resolveTypeFullyC(sema, sema->ip->items[ip_idx].data.slice);
break;
default:
break;
@@ -4062,8 +3998,8 @@ static void resolveTypeFullyC(InternPoolIndex ip_idx) {
// field_ty.resolveFully(pt);
// Re-parses the struct's ZIR fields to get the resolved type refs, then
// calls resolveTypeFullyC on each.
-static void resolveStructFieldTypesFully(const Zir* zir, uint32_t struct_inst,
- uint32_t struct_ns, uint32_t file_idx) {
+static void resolveStructFieldTypesFully(Sema* sema, const Zir* zir,
+ uint32_t struct_inst, uint32_t struct_ns, uint32_t file_idx) {
if (zir->inst_tags[struct_inst] != ZIR_INST_EXTENDED)
return;
if (zir->inst_datas[struct_inst].extended.opcode != ZIR_EXT_STRUCT_DECL)
@@ -4158,19 +4094,20 @@ static void resolveStructFieldTypesFully(const Zir* zir, uint32_t struct_inst,
if (last_zi < zir->inst_len
&& zir->inst_tags[last_zi] == ZIR_INST_BREAK_INLINE) {
ZirInstRef op = zir->inst_datas[last_zi].break_data.operand;
- resolved = resolveZirTypeRef(zir, op, struct_ns, file_idx);
+ resolved
+ = resolveZirTypeRef(sema, zir, op, struct_ns, file_idx);
}
} else if (!finfo[fi].has_type_body
&& finfo[fi].type_ref >= ZIR_REF_START_INDEX) {
resolved = resolveZirTypeRef(
- zir, finfo[fi].type_ref, struct_ns, file_idx);
+ sema, zir, finfo[fi].type_ref, struct_ns, file_idx);
}
sei += finfo[fi].type_body_len;
sei += finfo[fi].align_body_len;
sei += finfo[fi].init_body_len;
if (resolved != IP_INDEX_NONE)
- resolveTypeFullyC(resolved);
+ resolveTypeFullyC(sema, resolved);
}
}
@@ -4180,28 +4117,27 @@ static void resolveStructFieldTypesFully(const Zir* zir, uint32_t struct_inst,
// This creates type entries (like ?u64) during union layout resolution,
// before field init values (like opt_null) are created later in
// resolveStructFullyC.
-static bool s_struct_layout_resolved[4096];
-static bool resolveStructLayoutC(uint32_t nav_idx) {
- const Nav* nav = ipGetNav(nav_idx);
+static bool resolveStructLayoutC(Sema* sema, uint32_t nav_idx) {
+ const Nav* nav = ipGetNav(sema->ip, nav_idx);
if (nav->resolved_type == IP_INDEX_NONE)
return false;
- if (s_module_ip->items[nav->resolved_type].tag != IP_KEY_STRUCT_TYPE)
+ if (sema->ip->items[nav->resolved_type].tag != IP_KEY_STRUCT_TYPE)
return false;
- if (nav_idx < 4096 && s_struct_layout_resolved[nav_idx])
+ if (nav_idx < 4096 && sema->zcu->struct_layout_resolved[nav_idx])
return true;
if (nav_idx < 4096)
- s_struct_layout_resolved[nav_idx] = true;
+ sema->zcu->struct_layout_resolved[nav_idx] = true;
// Find the struct's namespace.
- uint32_t ns_idx = findNamespaceForType(nav->resolved_type);
+ uint32_t ns_idx = findNamespaceForType(sema, nav->resolved_type);
if (ns_idx == UINT32_MAX)
return false;
// Find the struct_decl ZIR instruction.
- uint32_t file_idx = s_namespaces[ns_idx].file_idx;
- if (!s_loaded_modules[file_idx].has_zir)
+ uint32_t file_idx = sema->zcu->namespaces[ns_idx].file_idx;
+ if (!sema->zcu->files[file_idx].has_zir)
return false;
- const Zir* zir = &s_loaded_modules[file_idx].zir;
+ const Zir* zir = &sema->zcu->files[file_idx].zir;
const uint32_t* vbody = NULL;
uint32_t vbody_len = 0;
@@ -4222,7 +4158,7 @@ static bool resolveStructLayoutC(uint32_t nav_idx) {
return false;
// Resolve field types (creates pointer/slice/optional IP entries).
- resolveStructFieldTypesC(zir, struct_inst, ns_idx, file_idx);
+ resolveStructFieldTypesC(sema, zir, struct_inst, ns_idx, file_idx);
return true;
}
@@ -4231,31 +4167,30 @@ static bool resolveStructLayoutC(uint32_t nav_idx) {
// and recursively resolve field types fully. Ported from Sema.zig
// resolveStructFully (called after all BuiltinDecl types are created).
// Assumes resolveStructLayoutC has already been called (field types resolved).
-static bool s_struct_fully_resolved[4096];
-static void resolveStructFullyC(uint32_t nav_idx) {
- const Nav* nav = ipGetNav(nav_idx);
+static void resolveStructFullyC(Sema* sema, uint32_t nav_idx) {
+ const Nav* nav = ipGetNav(sema->ip, nav_idx);
if (nav->resolved_type == IP_INDEX_NONE)
return;
- if (s_module_ip->items[nav->resolved_type].tag != IP_KEY_STRUCT_TYPE)
+ if (sema->ip->items[nav->resolved_type].tag != IP_KEY_STRUCT_TYPE)
return;
- if (nav_idx < 4096 && s_struct_fully_resolved[nav_idx])
+ if (nav_idx < 4096 && sema->zcu->struct_fully_resolved[nav_idx])
return;
if (nav_idx < 4096)
- s_struct_fully_resolved[nav_idx] = true;
+ sema->zcu->struct_fully_resolved[nav_idx] = true;
// Ensure layout is resolved first (idempotent).
- resolveStructLayoutC(nav_idx);
+ resolveStructLayoutC(sema, nav_idx);
// Find the struct's namespace.
- uint32_t ns_idx = findNamespaceForType(nav->resolved_type);
+ uint32_t ns_idx = findNamespaceForType(sema, nav->resolved_type);
if (ns_idx == UINT32_MAX)
return;
// Find the struct_decl ZIR instruction.
- uint32_t file_idx = s_namespaces[ns_idx].file_idx;
- if (!s_loaded_modules[file_idx].has_zir)
+ uint32_t file_idx = sema->zcu->namespaces[ns_idx].file_idx;
+ if (!sema->zcu->files[file_idx].has_zir)
return;
- const Zir* zir = &s_loaded_modules[file_idx].zir;
+ const Zir* zir = &sema->zcu->files[file_idx].zir;
const uint32_t* vbody = NULL;
uint32_t vbody_len = 0;
@@ -4276,11 +4211,11 @@ static void resolveStructFullyC(uint32_t nav_idx) {
return;
// Resolve field default values (creates enum_tag, opt_null, etc.).
- resolveStructFieldInitsC(zir, struct_inst, ns_idx, file_idx);
+ resolveStructFieldInitsC(sema, zir, struct_inst, ns_idx, file_idx);
// Recursively resolve field types (matching Zig's resolveStructFully
// field loop that calls field_ty.resolveFully on each field).
- resolveStructFieldTypesFully(zir, struct_inst, ns_idx, file_idx);
+ resolveStructFieldTypesFully(sema, zir, struct_inst, ns_idx, file_idx);
}
// --- resolveUnionFullyC ---
@@ -4289,43 +4224,40 @@ static void resolveStructFullyC(uint32_t nav_idx) {
// separation of getUnionType (creation) and resolveUnionFully (resolution).
// This allows controlling when field type resolution happens relative to
// other type creation, important for ordering IP entries correctly.
-static bool s_union_fully_resolved[4096];
// Mapping from union type IP index → tag enum IP index.
// Set by resolveUnionFullyC when creating the tag enum.
-static InternPoolIndex s_union_tag_enums[256];
-static InternPoolIndex s_union_tag_types[256]; // corresponding union type IPs
-static uint32_t s_num_union_tag_enums;
// Look up the tag enum IP index for a union type.
-static InternPoolIndex findUnionTagEnum(InternPoolIndex union_type) {
- for (uint32_t i = 0; i < s_num_union_tag_enums; i++) {
- if (s_union_tag_types[i] == union_type)
- return s_union_tag_enums[i];
+static InternPoolIndex findUnionTagEnum(
+ Sema* sema, InternPoolIndex union_type) {
+ for (uint32_t i = 0; i < sema->zcu->num_union_tag_enums; i++) {
+ if (sema->zcu->union_tag_types[i] == union_type)
+ return sema->zcu->union_tag_enums[i];
}
return IP_INDEX_NONE;
}
-static void resolveUnionFullyC(uint32_t nav_idx) {
- const Nav* nav = ipGetNav(nav_idx);
+static void resolveUnionFullyC(Sema* sema, uint32_t nav_idx) {
+ const Nav* nav = ipGetNav(sema->ip, nav_idx);
if (nav->resolved_type == IP_INDEX_NONE)
return;
- if (s_module_ip->items[nav->resolved_type].tag != IP_KEY_UNION_TYPE)
+ if (sema->ip->items[nav->resolved_type].tag != IP_KEY_UNION_TYPE)
return;
- if (nav_idx < 4096 && s_union_fully_resolved[nav_idx])
+ if (nav_idx < 4096 && sema->zcu->union_fully_resolved[nav_idx])
return;
if (nav_idx < 4096)
- s_union_fully_resolved[nav_idx] = true;
+ sema->zcu->union_fully_resolved[nav_idx] = true;
// Find the union's namespace.
- uint32_t ns_idx = findNamespaceForType(nav->resolved_type);
+ uint32_t ns_idx = findNamespaceForType(sema, nav->resolved_type);
if (ns_idx == UINT32_MAX)
return;
// Find the union_decl ZIR instruction from the nav's declaration body.
- uint32_t file_idx = s_namespaces[ns_idx].file_idx;
- if (!s_loaded_modules[file_idx].has_zir)
+ uint32_t file_idx = sema->zcu->namespaces[ns_idx].file_idx;
+ if (!sema->zcu->files[file_idx].has_zir)
return;
- const Zir* zir = &s_loaded_modules[file_idx].zir;
+ const Zir* zir = &sema->zcu->files[file_idx].zir;
const uint32_t* vbody = NULL;
uint32_t vbody_len = 0;
@@ -4393,7 +4325,7 @@ static void resolveUnionFullyC(uint32_t nav_idx) {
if (ft_has_type) {
ZirInstRef type_ref = zir->extra[cursor++];
InternPoolIndex resolved
- = resolveZirTypeRef(zir, type_ref, ns_idx, file_idx);
+ = resolveZirTypeRef(sema, zir, type_ref, ns_idx, file_idx);
if (resolved != IP_INDEX_NONE && num_resolved_fields < 128)
resolved_field_types[num_resolved_fields++] = resolved;
}
@@ -4407,19 +4339,22 @@ static void resolveUnionFullyC(uint32_t nav_idx) {
// Phase 2: Tag values and tag enum for tagged unions.
if (auto_enum_tag || has_tag_type) {
if (fields_len > 0)
- (void)internTypedInt(IP_INDEX_COMPTIME_INT_TYPE, fields_len - 1);
+ (void)internTypedInt(
+ sema, IP_INDEX_COMPTIME_INT_TYPE, fields_len - 1);
for (uint32_t i = 2; i < fields_len; i++)
- (void)internTypedInt(IP_INDEX_U8_TYPE, i);
+ (void)internTypedInt(sema, IP_INDEX_U8_TYPE, i);
InternPoolKey ek;
memset(&ek, 0, sizeof(ek));
ek.tag = IP_KEY_ENUM_TYPE;
- ek.data.enum_type = s_next_struct_hash++;
- InternPoolIndex tag_enum = ipIntern(s_module_ip, ek);
+ ek.data.enum_type = sema->zcu->next_struct_hash++;
+ InternPoolIndex tag_enum = ipIntern(sema->ip, ek);
// Save union → tag enum mapping for comptime union init.
- if (s_num_union_tag_enums < 256) {
- s_union_tag_types[s_num_union_tag_enums] = nav->resolved_type;
- s_union_tag_enums[s_num_union_tag_enums] = tag_enum;
- s_num_union_tag_enums++;
+ if (sema->zcu->num_union_tag_enums < 256) {
+ sema->zcu->union_tag_types[sema->zcu->num_union_tag_enums]
+ = nav->resolved_type;
+ sema->zcu->union_tag_enums[sema->zcu->num_union_tag_enums]
+ = tag_enum;
+ sema->zcu->num_union_tag_enums++;
}
}
@@ -4430,8 +4365,8 @@ static void resolveUnionFullyC(uint32_t nav_idx) {
InternPoolKey ek;
memset(&ek, 0, sizeof(ek));
ek.tag = IP_KEY_ENUM_TYPE;
- ek.data.enum_type = s_next_struct_hash++;
- (void)ipIntern(s_module_ip, ek);
+ ek.data.enum_type = sema->zcu->next_struct_hash++;
+ (void)ipIntern(sema->ip, ek);
}
// Phase 2b: Resolve struct field types for each struct-typed field.
@@ -4440,12 +4375,13 @@ static void resolveUnionFullyC(uint32_t nav_idx) {
// the tag enum. This creates type entries (like ?u64) during layout
// resolution, before field init values are created in Phase 3.
for (uint32_t i = 0; i < num_resolved_fields; i++) {
- if (resolved_field_types[i] < s_module_ip->items_len
- && s_module_ip->items[resolved_field_types[i]].tag
+ if (resolved_field_types[i] < sema->ip->items_len
+ && sema->ip->items[resolved_field_types[i]].tag
== IP_KEY_STRUCT_TYPE) {
- uint32_t field_nav = findNavForIPIndex(resolved_field_types[i]);
+ uint32_t field_nav
+ = findNavForIPIndex(sema, resolved_field_types[i]);
if (field_nav != UINT32_MAX)
- resolveStructLayoutC(field_nav);
+ resolveStructLayoutC(sema, field_nav);
}
}
@@ -4454,7 +4390,7 @@ static void resolveUnionFullyC(uint32_t nav_idx) {
// for (0..union_obj.field_types.len) |field_index|
// field_ty.resolveFully(pt);
for (uint32_t i = 0; i < num_resolved_fields; i++) {
- resolveTypeFullyC(resolved_field_types[i]);
+ resolveTypeFullyC(sema, resolved_field_types[i]);
}
}
@@ -4462,26 +4398,27 @@ static void resolveUnionFullyC(uint32_t nav_idx) {
// Find a union field by name and return its type IP index and field index.
// Parses the union_decl ZIR to iterate fields. Returns IP_INDEX_NONE if
// not found. Sets *out_field_idx to the field's position in the union.
-static InternPoolIndex resolveUnionFieldByName(InternPoolIndex union_type,
- const char* field_name, uint32_t* out_field_idx) {
+static InternPoolIndex resolveUnionFieldByName(Sema* sema,
+ InternPoolIndex union_type, const char* field_name,
+ uint32_t* out_field_idx) {
if (out_field_idx)
*out_field_idx = UINT32_MAX;
// Find the nav for the union type.
- uint32_t nav_idx = findNavForIPIndex(union_type);
+ uint32_t nav_idx = findNavForIPIndex(sema, union_type);
if (nav_idx == UINT32_MAX)
return IP_INDEX_NONE;
- const Nav* nav = ipGetNav(nav_idx);
+ const Nav* nav = ipGetNav(sema->ip, nav_idx);
// Find the namespace and ZIR.
- uint32_t ns_idx = findNamespaceForType(union_type);
+ uint32_t ns_idx = findNamespaceForType(sema, union_type);
if (ns_idx == UINT32_MAX)
return IP_INDEX_NONE;
- uint32_t file_idx = s_namespaces[ns_idx].file_idx;
- if (file_idx >= s_num_loaded_modules
- || !s_loaded_modules[file_idx].has_zir)
+ uint32_t file_idx = sema->zcu->namespaces[ns_idx].file_idx;
+ if (file_idx >= sema->zcu->num_files
+ || !sema->zcu->files[file_idx].has_zir)
return IP_INDEX_NONE;
- const Zir* zir = &s_loaded_modules[file_idx].zir;
+ const Zir* zir = &sema->zcu->files[file_idx].zir;
// Find the union_decl instruction from the nav's value body.
const uint32_t* vbody = NULL;
@@ -4545,7 +4482,8 @@ static InternPoolIndex resolveUnionFieldByName(InternPoolIndex union_type,
InternPoolIndex field_type = IP_INDEX_NONE;
if (ft_has_type) {
ZirInstRef type_ref = zir->extra[cursor++];
- field_type = resolveZirTypeRef(zir, type_ref, ns_idx, file_idx);
+ field_type
+ = resolveZirTypeRef(sema, zir, type_ref, ns_idx, file_idx);
}
if (ft_has_align)
cursor++;
@@ -4567,7 +4505,7 @@ static InternPoolIndex resolveUnionFieldByName(InternPoolIndex union_type,
// Returns the IP index of the union type, or IP_INDEX_NONE on failure.
// Ported from Sema.zig zirUnionDecl (getUnionType part only).
static InternPoolIndex resolveUnionDeclFromZir(
- const Zir* zir, uint32_t union_inst, uint32_t nav_idx) {
+ Sema* sema, const Zir* zir, uint32_t union_inst, uint32_t nav_idx) {
if (zir->inst_tags[union_inst] != ZIR_INST_EXTENDED)
return IP_INDEX_NONE;
if (zir->inst_datas[union_inst].extended.opcode != ZIR_EXT_UNION_DECL)
@@ -4596,26 +4534,27 @@ static InternPoolIndex resolveUnionDeclFromZir(
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_UNION_TYPE;
- key.data.union_type = s_next_struct_hash++;
- InternPoolIndex union_ip = ipIntern(s_module_ip, key);
+ key.data.union_type = sema->zcu->next_struct_hash++;
+ InternPoolIndex union_ip = ipIntern(sema->ip, key);
// Set resolved_type and create ptr_nav for the union nav.
{
- Nav* wnav = ipGetNav(nav_idx);
+ Nav* wnav = ipGetNav(sema->ip, nav_idx);
wnav->resolved_type = union_ip;
- InternPoolIndex ptr_type = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(ptr_type, nav_idx);
+ InternPoolIndex ptr_type = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, ptr_type, nav_idx);
}
// Create namespace for the union.
uint32_t file_idx
- = s_namespaces[ipGetNav(nav_idx)->namespace_idx].file_idx;
- uint32_t ns_idx = createNamespace(union_ip, file_idx);
+ = sema->zcu->namespaces[ipGetNav(sema->ip, nav_idx)->namespace_idx]
+ .file_idx;
+ uint32_t ns_idx = createNamespace(sema, union_ip, file_idx);
// Scan namespace declarations (creates Navs for sub-types like
// CommonOptions, X86RegparmOptions, etc.).
const uint32_t* decl_insts = &zir->extra[extra_index];
- scanNamespaceC(ns_idx, decl_insts, decls_len, zir);
+ scanNamespaceC(sema, ns_idx, decl_insts, decls_len, zir);
return union_ip;
}
@@ -4624,14 +4563,14 @@ static InternPoolIndex resolveUnionDeclFromZir(
// Evaluate a Nav's const declaration value body using a mini-sema.
// Creates IP entries for the resolved type and ptr_nav.
// Ported from PerThread.zig analyzeNavVal.
-static InternPoolIndex analyzeNavValC(uint32_t nav_idx) {
- Nav* nav = ipGetNav(nav_idx);
+static InternPoolIndex analyzeNavValC(Sema* sema, uint32_t nav_idx) {
+ Nav* nav = ipGetNav(sema->ip, nav_idx);
uint32_t ns_idx = nav->namespace_idx;
- const SemaNamespace* ns = &s_namespaces[ns_idx];
+ const ZcuNamespace* ns = &sema->zcu->namespaces[ns_idx];
uint32_t file_idx = ns->file_idx;
- if (!s_loaded_modules[file_idx].has_zir)
+ if (!sema->zcu->files[file_idx].has_zir)
return IP_INDEX_NONE;
- const Zir* zir = &s_loaded_modules[file_idx].zir;
+ const Zir* zir = &sema->zcu->files[file_idx].zir;
const uint32_t* value_body = NULL;
uint32_t value_body_len = 0;
@@ -4644,10 +4583,9 @@ static InternPoolIndex analyzeNavValC(uint32_t nav_idx) {
// Enable import resolution so comptime expressions can access
// cross-module declarations (e.g. @import("builtin").target).
Sema mini_sema;
- semaInit(&mini_sema, s_module_ip, *zir);
+ semaInit(&mini_sema, sema->zcu, *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;
+ mini_sema.source_dir = sema->zcu->files[file_idx].source_dir;
// Pre-expand inst_map to cover the full ZIR range.
// Value body instructions may reference ZIR instructions outside
@@ -4712,9 +4650,9 @@ static InternPoolIndex analyzeNavValC(uint32_t nav_idx) {
&& zir->inst_tags[last_inst] == ZIR_INST_BREAK_INLINE) {
ZirInstRef op = zir->inst_datas[last_inst].break_data.operand;
InternPoolIndex type_result
- = resolveZirTypeRef(zir, op, ns_idx, file_idx);
+ = resolveZirTypeRef(sema, zir, op, ns_idx, file_idx);
if (type_result != IP_INDEX_NONE) {
- nav = ipGetNav(nav_idx);
+ nav = ipGetNav(sema->ip, nav_idx);
nav->resolved_type = type_result;
return type_result;
}
@@ -4731,7 +4669,7 @@ static InternPoolIndex analyzeNavValC(uint32_t nav_idx) {
// handled separately by analyzeNavRefInner (called from analyzeNavVal).
// Callers that need ptr_nav create it
// explicitly.
- nav = ipGetNav(nav_idx);
+ nav = ipGetNav(sema->ip, nav_idx);
nav->resolved_type = result_ip;
return result_ip;
@@ -4744,15 +4682,15 @@ static InternPoolIndex analyzeNavValC(uint32_t nav_idx) {
// For const declarations that are not type declarations, falls through
// to analyzeNavValC for general comptime evaluation.
// Ported from PerThread.zig ensureNavValUpToDate.
-static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
- const Nav* nav = ipGetNav(nav_idx);
+static InternPoolIndex ensureNavValUpToDate(Sema* sema, uint32_t nav_idx) {
+ const Nav* nav = ipGetNav(sema->ip, nav_idx);
// If already resolved, return the cached value.
if (nav->resolved_type != IP_INDEX_NONE)
return nav->resolved_type;
uint32_t ns_idx = nav->namespace_idx;
- const SemaNamespace* ns = &s_namespaces[ns_idx];
+ const ZcuNamespace* ns = &sema->zcu->namespaces[ns_idx];
uint32_t file_idx = ns->file_idx;
// CG builtin module navs have no ZIR — resolve via
@@ -4763,19 +4701,19 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
// are synthetic modules with no ZIR). std/builtin.zig shares the
// same namespace index when the CG builtin is a sub-namespace,
// but its navs have valid ZIR and should be resolved normally.
- if (s_cg_builtin_ns_idx != UINT32_MAX && ns_idx == s_cg_builtin_ns_idx
- && !s_loaded_modules[file_idx].has_zir) {
- const char* nav_name
- = (const char*)&s_module_ip->string_bytes[nav->name];
- InternPoolIndex val = resolveCgBuiltinField(nav_idx, nav_name);
+ if (sema->zcu->cg_builtin_ns_idx != UINT32_MAX
+ && ns_idx == sema->zcu->cg_builtin_ns_idx
+ && !sema->zcu->files[file_idx].has_zir) {
+ const char* nav_name = (const char*)&sema->ip->string_bytes[nav->name];
+ InternPoolIndex val = resolveCgBuiltinField(sema, nav_idx, nav_name);
if (val != IP_INDEX_NONE)
return val;
return IP_INDEX_NONE;
}
- if (!s_loaded_modules[file_idx].has_zir)
+ if (!sema->zcu->files[file_idx].has_zir)
return IP_INDEX_NONE;
- const Zir* zir = &s_loaded_modules[file_idx].zir;
+ const Zir* zir = &sema->zcu->files[file_idx].zir;
// Get the value body from the declaration.
const uint32_t* body = NULL;
@@ -4792,19 +4730,20 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
if (zir->inst_tags[inst] == ZIR_INST_EXTENDED) {
uint16_t opcode = zir->inst_datas[inst].extended.opcode;
if (opcode == ZIR_EXT_ENUM_DECL)
- return resolveEnumDeclFromZir(zir, inst, nav_idx);
+ return resolveEnumDeclFromZir(sema, zir, inst, nav_idx);
if (opcode == ZIR_EXT_STRUCT_DECL)
- return resolveStructDeclFromZir(zir, inst, nav_idx);
+ return resolveStructDeclFromZir(sema, zir, inst, nav_idx);
if (opcode == ZIR_EXT_UNION_DECL)
- return resolveUnionDeclFromZir(zir, inst, nav_idx);
+ return resolveUnionDeclFromZir(sema, zir, inst, nav_idx);
if (opcode == ZIR_EXT_THIS) {
// @This() resolves to the type that owns the namespace
// this declaration is declared in. E.g. `const V = @This();`
// inside a struct resolves V to that struct type.
- Nav* wnav = ipGetNav(nav_idx);
+ Nav* wnav = ipGetNav(sema->ip, nav_idx);
wnav->resolved_type = ns->owner_type;
- InternPoolIndex ptr_type = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(ptr_type, nav_idx);
+ InternPoolIndex ptr_type
+ = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, ptr_type, nav_idx);
return ns->owner_type;
}
}
@@ -4821,7 +4760,7 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
if (tag == ZIR_INST_FUNC || tag == ZIR_INST_FUNC_FANCY) {
// Create a temp sema to parse func info from the ZIR.
Sema tmp_sema;
- semaInit(&tmp_sema, s_module_ip, *zir);
+ semaInit(&tmp_sema, sema->zcu, *zir);
FuncZirInfo fi = parseFuncZir(&tmp_sema, inst);
semaDeinit(&tmp_sema);
@@ -4833,15 +4772,15 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
if (fi.ret_ty_body_len == 1) {
uint32_t ret_ref = zir->extra[fi.ret_ty_ref_pos];
InternPoolIndex resolved
- = resolveZirTypeRef(zir, ret_ref, ns_idx, file_idx);
+ = resolveZirTypeRef(sema, zir, ret_ref, ns_idx, file_idx);
if (resolved != IP_INDEX_NONE)
ret_ty = resolved;
} else if (fi.ret_ty_body_len == 2) {
// 2-instruction body: type instruction + break_inline.
// Resolve the first instruction as a type.
uint32_t type_inst = zir->extra[fi.ret_ty_ref_pos];
- InternPoolIndex resolved
- = resolveZirTypeInst(zir, type_inst, ns_idx, file_idx);
+ InternPoolIndex resolved = resolveZirTypeInst(
+ sema, zir, type_inst, ns_idx, file_idx);
if (resolved != IP_INDEX_NONE)
ret_ty = resolved;
}
@@ -4876,15 +4815,15 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
uint8_t cc = 0;
if (fi.is_inline) {
cc = CC_TAG_INLINE;
- (void)getBuiltinTypeC(2); // CallingConvention
+ (void)getBuiltinTypeC(sema, 2); // CallingConvention
}
InternPoolIndex ft
- = internFuncType(ret_ty, param_count, cc, false);
- InternPoolIndex fd = internFuncDecl(nav_idx, ft);
- Nav* wnav = ipGetNav(nav_idx);
+ = internFuncType(sema, ret_ty, param_count, cc, false);
+ InternPoolIndex fd = internFuncDecl(sema, nav_idx, ft);
+ Nav* wnav = ipGetNav(sema->ip, nav_idx);
wnav->resolved_type = fd;
- InternPoolIndex ptr_ty = internPtrConst(ft);
- (void)internNavPtr(ptr_ty, nav_idx);
+ InternPoolIndex ptr_ty = internPtrConst(sema, ft);
+ (void)internNavPtr(sema, ptr_ty, nav_idx);
return fd;
}
}
@@ -4904,16 +4843,17 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
// Resolve via doImport (handles "builtin", "root",
// "std", and file paths).
- uint32_t import_file_idx
- = doImport(s_loaded_modules[file_idx].source_dir, import_path);
+ uint32_t import_file_idx = doImport(
+ sema, sema->zcu->files[file_idx].source_dir, import_path);
if (import_file_idx == UINT32_MAX)
break;
- InternPoolIndex struct_type = s_file_root_type[import_file_idx];
+ InternPoolIndex struct_type
+ = sema->zcu->file_root_types[import_file_idx];
if (struct_type == 0 && import_file_idx > 0)
break;
- Nav* wnav = ipGetNav(nav_idx);
+ Nav* wnav = ipGetNav(sema->ip, nav_idx);
wnav->resolved_type = struct_type;
return struct_type;
}
@@ -4922,15 +4862,15 @@ static InternPoolIndex ensureNavValUpToDate(uint32_t nav_idx) {
// Fallback: for non-type declarations (const values), use
// analyzeNavValC to evaluate the body at comptime.
// Ported from PerThread.zig analyzeNavVal fallthrough.
- return analyzeNavValC(nav_idx);
+ return analyzeNavValC(sema, nav_idx);
}
// --- findFileByPathSuffix ---
// Find a loaded module by path suffix. Returns file index or UINT32_MAX.
-static uint32_t findFileByPathSuffix(const char* suffix) {
+static uint32_t findFileByPathSuffix(Sema* sema, const char* suffix) {
size_t slen = strlen(suffix);
- for (uint32_t i = 0; i < s_num_loaded_modules; i++) {
- const char* p = s_loaded_modules[i].path;
+ for (uint32_t i = 0; i < sema->zcu->num_files; i++) {
+ const char* p = sema->zcu->files[i].path;
size_t plen = strlen(p);
if (plen >= slen && strcmp(p + plen - slen, suffix) == 0)
return i;
@@ -4940,35 +4880,35 @@ static uint32_t findFileByPathSuffix(const char* suffix) {
// Forward declarations for functions used by resolveCgBuiltinField.
static InternPoolIndex internEnumTag(
- InternPoolIndex enum_ty, InternPoolIndex int_val);
+ Sema* sema, InternPoolIndex enum_ty, InternPoolIndex int_val);
// resolveEnumFieldInTarget: look up an enum field by name in a type
// declared in std.Target. Returns the interned enum_tag, or IP_INDEX_NONE.
// Ported from the pattern in Compilation.Config where target-derived
// enum values are resolved through the standard library's type system.
static InternPoolIndex resolveEnumFieldInTarget(
- const char* type_name, const char* field_name) {
- uint32_t tfi = findFileByPathSuffix("/std/Target.zig");
+ Sema* sema, const char* type_name, const char* field_name) {
+ uint32_t tfi = findFileByPathSuffix(sema, "/std/Target.zig");
if (tfi == UINT32_MAX)
return IP_INDEX_NONE;
- uint32_t tns = s_file_namespace[tfi];
- uint32_t nav = findNavInNamespace(tns, type_name);
+ uint32_t tns = sema->zcu->file_namespaces[tfi];
+ uint32_t nav = findNavInNamespace(sema, tns, type_name);
if (nav == UINT32_MAX)
return IP_INDEX_NONE;
- InternPoolIndex ty = ensureNavValUpToDate(nav);
+ InternPoolIndex ty = ensureNavValUpToDate(sema, nav);
if (ty == IP_INDEX_NONE)
return IP_INDEX_NONE;
const Zir* tzir = NULL;
- uint32_t enum_inst = findEnumDeclForNav(nav, &tzir);
+ uint32_t enum_inst = findEnumDeclForNav(sema, nav, &tzir);
if (enum_inst == UINT32_MAX)
return IP_INDEX_NONE;
uint32_t fidx = findEnumFieldByName(tzir, enum_inst, field_name);
if (fidx == UINT32_MAX)
return IP_INDEX_NONE;
- InternPoolIndex iv = getEnumFieldIntVal(tzir, enum_inst, fidx);
+ InternPoolIndex iv = getEnumFieldIntVal(sema, tzir, enum_inst, fidx);
if (iv == IP_INDEX_NONE)
return IP_INDEX_NONE;
- return internEnumTag(ty, iv);
+ return internEnumTag(sema, ty, iv);
}
// --- resolveCgBuiltinField ---
@@ -4981,9 +4921,9 @@ static InternPoolIndex resolveEnumFieldInTarget(
// Ported from PerThread.zig analyzeNavVal for compiler-generated
// builtin module fields.
static InternPoolIndex resolveCgBuiltinField(
- uint32_t field_nav, const char* field_name) {
+ Sema* sema, uint32_t field_nav, const char* field_name) {
// Already resolved — return cached value.
- const Nav* nav = ipGetNav(field_nav);
+ const Nav* nav = ipGetNav(sema->ip, field_nav);
if (nav->resolved_type != IP_INDEX_NONE)
return nav->resolved_type;
@@ -4991,21 +4931,23 @@ static InternPoolIndex resolveCgBuiltinField(
if (strcmp(field_name, "is_test") == 0) {
// Ported from Compilation.Config.is_test.
- result = readBool(&s_config_is_test) ? IP_INDEX_BOOL_TRUE
- : IP_INDEX_BOOL_FALSE;
+ result = readBool(&sema->zcu->comp->config.is_test)
+ ? IP_INDEX_BOOL_TRUE
+ : IP_INDEX_BOOL_FALSE;
} else if (strcmp(field_name, "object_format") == 0) {
- // Look up s_config_object_format in Target.ObjectFormat enum.
- // Ported from Compilation.Config.object_format.
- result
- = resolveEnumFieldInTarget("ObjectFormat", s_config_object_format);
+ // Look up sema->zcu->comp->config.object_format in Target.ObjectFormat
+ // enum. Ported from Compilation.Config.object_format.
+ result = resolveEnumFieldInTarget(
+ sema, "ObjectFormat", sema->zcu->comp->config.object_format);
} else if (strcmp(field_name, "link_mode") == 0) {
- // Look up s_config_link_mode in Target.LinkMode enum.
+ // Look up sema->zcu->comp->config.link_mode in Target.LinkMode enum.
// Ported from Compilation.Config.link_mode.
- result = resolveEnumFieldInTarget("LinkMode", s_config_link_mode);
+ result = resolveEnumFieldInTarget(
+ sema, "LinkMode", sema->zcu->comp->config.link_mode);
}
if (result != IP_INDEX_NONE) {
- Nav* wnav = ipGetNav(field_nav);
+ Nav* wnav = ipGetNav(sema->ip, field_nav);
wnav->resolved_type = result;
}
return result;
@@ -5015,31 +4957,32 @@ static InternPoolIndex resolveCgBuiltinField(
// Create an enum_tag IP entry for a specific value of an enum type.
// The int value must already be interned (e.g. int_small(u64, val)).
static InternPoolIndex internEnumTag(
- InternPoolIndex enum_ty, InternPoolIndex int_val) {
+ Sema* sema, InternPoolIndex enum_ty, InternPoolIndex int_val) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_ENUM_TAG;
key.data.enum_tag.ty = enum_ty;
key.data.enum_tag.int_val = int_val;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internTypedInt ---
// Intern a typed integer value. Creates int_small if small enough.
-static InternPoolIndex internTypedInt(InternPoolIndex ty, uint64_t val) {
+static InternPoolIndex internTypedInt(
+ Sema* sema, InternPoolIndex ty, uint64_t val) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_INT;
key.data.int_val.ty = ty;
key.data.int_val.value_lo = val;
key.data.int_val.is_negative = false;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internFuncType ---
// Create a function type IP entry.
// Ported from InternPool.zig getFuncType.
-static InternPoolIndex internFuncType(InternPoolIndex return_type,
+static InternPoolIndex internFuncType(Sema* sema, InternPoolIndex return_type,
uint32_t param_count, uint8_t cc, bool is_noinline) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
@@ -5048,20 +4991,20 @@ static InternPoolIndex internFuncType(InternPoolIndex return_type,
key.data.func_type.param_count = param_count;
key.data.func_type.cc = cc;
key.data.func_type.is_noinline = is_noinline;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- internFuncDecl ---
// Create a func_decl IP entry for a function declaration.
// Ported from InternPool.zig getFuncDecl.
static InternPoolIndex internFuncDecl(
- uint32_t owner_nav, InternPoolIndex func_type) {
+ Sema* sema, uint32_t owner_nav, InternPoolIndex func_type) {
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_FUNC;
key.data.func_decl.owner_nav = owner_nav;
key.data.func_decl.ty = func_type;
- return ipIntern(s_module_ip, key);
+ return ipIntern(sema->ip, key);
}
// --- findDeclImportPathFromZir ---
@@ -5166,8 +5109,8 @@ static void normalizePath(char* path) {
*out = '\0';
}
-static bool resolveImportPath(const char* source_dir, const char* import_path,
- char* out_full, size_t out_size) {
+static bool resolveImportPath(const Sema* sema, const char* source_dir,
+ const char* import_path, char* out_full, size_t out_size) {
const char* rel = import_path;
if (rel[0] == '.' && rel[1] == '/')
rel += 2;
@@ -5189,9 +5132,9 @@ static bool resolveImportPath(const char* source_dir, const char* import_path,
}
// Bare module names (e.g. "std") resolve via module_root.
- if (s_global_module_root) {
- snprintf(out_full, out_size, "%s/lib/%s/%s.zig", s_global_module_root,
- import_path, import_path);
+ if (sema->zcu->comp->config.module_root) {
+ snprintf(out_full, out_size, "%s/lib/%s/%s.zig",
+ sema->zcu->comp->config.module_root, import_path, import_path);
return true;
}
return false;
@@ -5205,14 +5148,15 @@ static bool resolveImportPath(const char* source_dir, const char* import_path,
// This matches the Zig compiler's demand-driven resolution order:
// type_struct → type_pointer → ptr_nav, then recurse.
-static void resolveModuleDeclImports(uint32_t file_idx, uint32_t depth) {
- if (depth == 0 || file_idx >= s_num_loaded_modules)
+static void resolveModuleDeclImports(
+ Sema* sema, uint32_t file_idx, uint32_t depth) {
+ if (depth == 0 || file_idx >= sema->zcu->num_files)
return;
- LoadedModule* mod = &s_loaded_modules[file_idx];
+ ZcuFile* mod = &sema->zcu->files[file_idx];
if (!mod->has_zir)
return;
- uint32_t ns_idx = s_file_namespace[file_idx];
- SemaNamespace* ns = &s_namespaces[ns_idx];
+ uint32_t ns_idx = sema->zcu->file_namespaces[file_idx];
+ ZcuNamespace* ns = &sema->zcu->namespaces[ns_idx];
const Zir* zir = &mod->zir;
// Process all named declarations (pub first, then priv — matching
@@ -5223,7 +5167,7 @@ static void resolveModuleDeclImports(uint32_t file_idx, uint32_t depth) {
for (uint32_t i = 0; i < count; i++) {
uint32_t nav_idx = navs[i];
- Nav* nav = ipGetNav(nav_idx);
+ Nav* nav = ipGetNav(sema->ip, nav_idx);
// Check if this declaration is an import.
const char* import_path
@@ -5232,10 +5176,12 @@ static void resolveModuleDeclImports(uint32_t file_idx, uint32_t depth) {
continue;
// Resolve via doImport (handles all special names).
- uint32_t import_file_idx = doImport(mod->source_dir, import_path);
+ uint32_t import_file_idx
+ = doImport(sema, mod->source_dir, import_path);
if (import_file_idx == UINT32_MAX)
continue;
- InternPoolIndex struct_type = s_file_root_type[import_file_idx];
+ InternPoolIndex struct_type
+ = sema->zcu->file_root_types[import_file_idx];
if (struct_type == 0 && import_file_idx > 0)
continue; // failed to create struct
@@ -5243,12 +5189,13 @@ static void resolveModuleDeclImports(uint32_t file_idx, uint32_t depth) {
// Import declarations have value-type `type`, so the pointer
// is `*const type` (not *const struct). This matches upstream
// analyzeNavRefInner which gets the declared type.
- InternPoolIndex ptr_type = internPtrConst(IP_INDEX_TYPE_TYPE);
+ InternPoolIndex ptr_type
+ = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
nav->resolved_type = struct_type;
- (void)internNavPtr(ptr_type, nav_idx);
+ (void)internNavPtr(sema, ptr_type, nav_idx);
// Recurse depth-first into imported file's declarations.
- resolveModuleDeclImports(import_file_idx, depth - 1);
+ resolveModuleDeclImports(sema, import_file_idx, depth - 1);
}
}
}
@@ -5261,10 +5208,11 @@ static void populateDeclTableFromZir(Sema* sema, const Zir* zir);
// Ported from src/Zcu/PerThread.zig analyzeComptimeUnit (lines 853-926).
// Side effects (IP entries from @import, field access, etc.) are the
// primary purpose — the comptime block itself produces void.
-static void analyzeComptimeUnit(uint32_t file_idx, uint32_t comptime_decl) {
- if (!s_loaded_modules[file_idx].has_zir)
+static void analyzeComptimeUnit(
+ Sema* sema, uint32_t file_idx, uint32_t comptime_decl) {
+ if (!sema->zcu->files[file_idx].has_zir)
return;
- const Zir* zir = &s_loaded_modules[file_idx].zir;
+ const Zir* zir = &sema->zcu->files[file_idx].zir;
// Get the value body from the comptime declaration.
const uint32_t* body = NULL;
@@ -5277,10 +5225,9 @@ static void analyzeComptimeUnit(uint32_t file_idx, uint32_t comptime_decl) {
// Ported from analyzeComptimeUnit: sema is created with the
// module's ZIR, fn_ret_ty = void (comptime blocks are always void).
Sema ct_sema;
- semaInit(&ct_sema, s_module_ip, *zir);
+ semaInit(&ct_sema, sema->zcu, *zir);
ct_sema.file_idx = file_idx;
- ct_sema.source_dir = s_loaded_modules[file_idx].source_dir;
- ct_sema.module_root = s_global_module_root;
+ ct_sema.source_dir = sema->zcu->files[file_idx].source_dir;
// Populate the decl table so nested imports resolve correctly.
populateDeclTableFromZir(&ct_sema, zir);
@@ -5303,28 +5250,29 @@ static void analyzeComptimeUnit(uint32_t file_idx, uint32_t comptime_decl) {
// Resolves an import string to a file index. Handles special module
// names ("builtin", "root", "std") and regular file paths.
// Returns file_idx, or UINT32_MAX if the import cannot be resolved.
-static uint32_t doImport(const char* source_dir, const char* import_string) {
+static uint32_t doImport(
+ Sema* sema, const char* source_dir, const char* import_string) {
// Special module names — ported from PerThread.zig doImport
// lines 1982-1990.
if (strcmp(import_string, "builtin") == 0) {
// @import("builtin") → compiler-generated builtin module.
- InternPoolIndex cg = ensureCgBuiltinModule();
+ InternPoolIndex cg = ensureCgBuiltinModule(sema);
if (cg == IP_INDEX_NONE)
return UINT32_MAX;
// Find the CG builtin's file_idx.
- for (uint32_t fi = 0; fi < s_num_loaded_modules; fi++) {
- if (s_file_root_type[fi] == cg)
+ for (uint32_t fi = 0; fi < sema->zcu->num_files; fi++) {
+ if (sema->zcu->file_root_types[fi] == cg)
return fi;
}
return UINT32_MAX;
}
if (strcmp(import_string, "root") == 0) {
// @import("root") → user's root module.
- return s_root_file_idx;
+ return sema->zcu->root_file_idx;
}
if (strcmp(import_string, "std") == 0) {
// @import("std") → standard library.
- return s_std_file_idx;
+ return sema->zcu->std_file_idx;
}
// Regular file import — resolve path and load.
@@ -5332,9 +5280,9 @@ static uint32_t doImport(const char* source_dir, const char* import_string) {
return UINT32_MAX;
char import_full[1024];
if (!resolveImportPath(
- source_dir, import_string, import_full, sizeof(import_full)))
+ sema, source_dir, import_string, import_full, sizeof(import_full)))
return UINT32_MAX;
- return ensureFileAnalyzedC(import_full);
+ return ensureFileAnalyzedC(sema, import_full);
}
// --- ensureFileAnalyzedC ---
@@ -5343,8 +5291,8 @@ static uint32_t doImport(const char* source_dir, const char* import_string) {
// namespace, and Nav entries matching the Zig compiler's sequence.
// Returns the file index, or UINT32_MAX on failure.
-static uint32_t ensureFileAnalyzedC(const char* full_path) {
- if (!s_module_ip)
+static uint32_t ensureFileAnalyzedC(Sema* sema, const char* full_path) {
+ if (!sema->ip)
return UINT32_MAX;
// Normalize: strip leading "./" to avoid duplicate entries for the
@@ -5353,23 +5301,23 @@ static uint32_t ensureFileAnalyzedC(const char* full_path) {
full_path += 2;
// Check if already tracked.
- for (uint32_t i = 0; i < s_num_loaded_modules; i++) {
- if (strcmp(s_loaded_modules[i].path, full_path) == 0) {
+ for (uint32_t i = 0; i < sema->zcu->num_files; i++) {
+ if (strcmp(sema->zcu->files[i].path, full_path) == 0) {
// Already loaded. Ensure it's been analyzed.
- if (!s_loaded_modules[i].analyzed && s_loaded_modules[i].has_zir) {
- s_loaded_modules[i].analyzed = true;
- (void)createFileRootStructC(i, &s_loaded_modules[i].zir);
+ if (!sema->zcu->files[i].analyzed && sema->zcu->files[i].has_zir) {
+ sema->zcu->files[i].analyzed = true;
+ (void)createFileRootStructC(sema, i, &sema->zcu->files[i].zir);
}
return i;
}
}
- if (s_num_loaded_modules >= MAX_LOADED_MODULES)
+ if (sema->zcu->num_files >= ZCU_MAX_FILES)
return UINT32_MAX;
// Register new module.
- uint32_t file_idx = s_num_loaded_modules++;
- LoadedModule* mod = &s_loaded_modules[file_idx];
+ uint32_t file_idx = sema->zcu->num_files++;
+ ZcuFile* mod = &sema->zcu->files[file_idx];
memset(mod, 0, sizeof(*mod));
snprintf(mod->path, sizeof(mod->path), "%s", full_path);
@@ -5412,48 +5360,48 @@ static uint32_t ensureFileAnalyzedC(const char* full_path) {
if (mod->has_zir) {
mod->analyzed = true;
- (void)createFileRootStructC(file_idx, &mod->zir);
+ (void)createFileRootStructC(sema, file_idx, &mod->zir);
}
return file_idx;
}
// Reset module tracking state.
-static void resetModuleTracking(void) {
+static void resetModuleTracking(Sema* sema) {
// Free ZIR/AST data from loaded modules.
- for (uint32_t i = 0; i < s_num_loaded_modules; i++) {
- if (s_loaded_modules[i].has_zir) {
- zirDeinit(&s_loaded_modules[i].zir);
- astDeinit(&s_loaded_modules[i].ast);
- }
- }
- s_num_loaded_modules = 0;
- s_next_struct_hash = 0;
- s_module_ip = NULL;
- s_root_file_idx = 0;
- s_num_namespaces = 0;
- s_std_file_idx = UINT32_MAX;
- s_builtin_file_idx = UINT32_MAX;
- s_cg_builtin_nav = UINT32_MAX;
- s_cg_builtin_ns_idx = UINT32_MAX;
- s_global_module_root = NULL;
- s_target_cpu_arch_name = NULL;
- s_target_cpu_model_name = NULL;
- ipResetNavs();
- memset(s_file_root_type, 0, sizeof(s_file_root_type));
- memset(s_file_namespace, 0, sizeof(s_file_namespace));
- memset(s_struct_layout_resolved, 0, sizeof(s_struct_layout_resolved));
- memset(s_struct_fully_resolved, 0, sizeof(s_struct_fully_resolved));
- memset(s_union_fully_resolved, 0, sizeof(s_union_fully_resolved));
- s_num_union_tag_enums = 0;
- s_memoized_main_resolved = false;
- s_full_memoized_resolved = false;
- memset(s_builtin_decl_values, 0, sizeof(s_builtin_decl_values));
- s_preamble_memoized_start = 0;
- s_preamble_memoized_end = 0;
- s_preamble_cc_start = 0;
- s_preamble_cc_end = 0;
- s_preamble_builtin_nav_count = 0;
+ for (uint32_t i = 0; i < sema->zcu->num_files; i++) {
+ if (sema->zcu->files[i].has_zir) {
+ zirDeinit(&sema->zcu->files[i].zir);
+ astDeinit(&sema->zcu->files[i].ast);
+ }
+ }
+ sema->zcu->num_files = 0;
+ sema->zcu->next_struct_hash = 0;
+ sema->zcu->root_file_idx = 0;
+ sema->zcu->num_namespaces = 0;
+ sema->zcu->std_file_idx = UINT32_MAX;
+ sema->zcu->builtin_file_idx = UINT32_MAX;
+ sema->zcu->cg_builtin_nav = UINT32_MAX;
+ sema->zcu->cg_builtin_ns_idx = UINT32_MAX;
+ ipResetNavs(sema->ip);
+ memset(sema->zcu->file_root_types, 0, sizeof(sema->zcu->file_root_types));
+ memset(sema->zcu->file_namespaces, 0, sizeof(sema->zcu->file_namespaces));
+ memset(sema->zcu->struct_layout_resolved, 0,
+ sizeof(sema->zcu->struct_layout_resolved));
+ memset(sema->zcu->struct_fully_resolved, 0,
+ sizeof(sema->zcu->struct_fully_resolved));
+ memset(sema->zcu->union_fully_resolved, 0,
+ sizeof(sema->zcu->union_fully_resolved));
+ sema->zcu->num_union_tag_enums = 0;
+ sema->zcu->memoized_main_resolved = false;
+ sema->zcu->full_memoized_resolved = false;
+ memset(sema->zcu->builtin_decl_values, 0,
+ sizeof(sema->zcu->builtin_decl_values));
+ sema->zcu->preamble_memoized_start = 0;
+ sema->zcu->preamble_memoized_end = 0;
+ sema->zcu->preamble_cc_start = 0;
+ sema->zcu->preamble_cc_end = 0;
+ sema->zcu->preamble_builtin_nav_count = 0;
}
// populateDeclTableFromZir: populate sema's decl table from a ZIR module.
@@ -6117,8 +6065,9 @@ static InternPoolIndex registerStructTypeFromZir(
// module (freeing the old ones). On failure, returns UINT32_MAX.
// If out_resolved_dir is non-NULL and a re-export was followed, writes
// the resolved target module's source directory there.
-static uint32_t findFuncInModuleZir(const char* source_dir, Zir* zir, Ast* ast,
- const char* func_name, char* out_resolved_dir, size_t resolved_dir_size) {
+static uint32_t findFuncInModuleZir(Sema* sema, const char* source_dir,
+ Zir* zir, Ast* ast, const char* func_name, char* out_resolved_dir,
+ size_t resolved_dir_size) {
uint32_t func_inst = findFuncInstInZir(zir, func_name);
if (func_inst != UINT32_MAX)
return func_inst;
@@ -6134,7 +6083,8 @@ static uint32_t findFuncInModuleZir(const char* source_dir, Zir* zir, Ast* ast,
snprintf(
reexport_import, sizeof(reexport_import), "%s", reexport_import_ptr);
Ast target_ast;
- Zir target_zir = loadImportZir(source_dir, reexport_import, &target_ast);
+ Zir target_zir
+ = loadImportZir(sema, source_dir, reexport_import, &target_ast);
if (target_zir.inst_len == 0)
return UINT32_MAX;
func_inst = findFuncInstInZir(&target_zir, reexport_field);
@@ -6237,29 +6187,29 @@ static AirInstRef comptimeFieldCall(Sema* sema, SemaBlock* block,
&& sema->ip->items[ns_type].tag == IP_KEY_PTR_TYPE) {
ns_type = sema->ip->items[ns_type].data.ptr_type.child;
}
- uint32_t ns_idx = findNamespaceForType(ns_type);
+ uint32_t ns_idx = findNamespaceForType(sema, ns_type);
if (ns_idx == UINT32_MAX)
return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
// Look up the function by field name.
const char* fn_name
= (const char*)&sema->code.string_bytes[field_name_start];
- uint32_t fn_nav_idx = findNavInNamespace(ns_idx, fn_name);
+ uint32_t fn_nav_idx = findNavInNamespace(sema, ns_idx, fn_name);
if (fn_nav_idx == UINT32_MAX)
return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
// Ensure the function nav is resolved (creates func_type +
// func_decl + ptr_type + ptr_nav entries).
- (void)ensureNavValUpToDate(fn_nav_idx);
+ (void)ensureNavValUpToDate(sema, fn_nav_idx);
// Get the function nav's ZIR.
- const Nav* fn_nav = ipGetNav(fn_nav_idx);
+ const Nav* fn_nav = ipGetNav(sema->ip, fn_nav_idx);
uint32_t fn_ns_idx = fn_nav->namespace_idx;
- const SemaNamespace* fn_ns = &s_namespaces[fn_ns_idx];
+ const ZcuNamespace* fn_ns = &sema->zcu->namespaces[fn_ns_idx];
uint32_t fn_file_idx = fn_ns->file_idx;
- if (!s_loaded_modules[fn_file_idx].has_zir)
+ if (!sema->zcu->files[fn_file_idx].has_zir)
return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
- const Zir* fn_zir = &s_loaded_modules[fn_file_idx].zir;
+ const Zir* fn_zir = &sema->zcu->files[fn_file_idx].zir;
// Get function info from the ZIR declaration.
// Parse the declaration to find the function value body.
@@ -6284,10 +6234,9 @@ static AirInstRef comptimeFieldCall(Sema* sema, SemaBlock* block,
// Create a mini-sema with the function's ZIR to parse func info.
Sema fn_sema;
- semaInit(&fn_sema, s_module_ip, *fn_zir);
+ semaInit(&fn_sema, sema->zcu, *fn_zir);
fn_sema.file_idx = fn_file_idx;
- fn_sema.source_dir = s_loaded_modules[fn_file_idx].source_dir;
- fn_sema.module_root = s_global_module_root;
+ fn_sema.source_dir = sema->zcu->files[fn_file_idx].source_dir;
// Parse function info (parameters, body).
FuncZirInfo fi = parseFuncZir(&fn_sema, func_zir_inst);
@@ -6353,7 +6302,7 @@ static AirInstRef comptimeFieldCall(Sema* sema, SemaBlock* block,
// types because they get deduped to existing entries).
{
// Get function type to extract return type.
- const Nav* fn_nav_resolved = ipGetNav(fn_nav_idx);
+ const Nav* fn_nav_resolved = ipGetNav(sema->ip, fn_nav_idx);
InternPoolIndex fn_decl_ip = fn_nav_resolved->resolved_type;
if (fn_decl_ip != IP_INDEX_NONE
&& sema->ip->items[fn_decl_ip].tag == IP_KEY_FUNC) {
@@ -6371,12 +6320,14 @@ static AirInstRef comptimeFieldCall(Sema* sema, SemaBlock* block,
// the Zig compiler creates no new IP entries for the frame.
if (obj_type >= ZIR_REF_START_INDEX
|| ret_ty >= ZIR_REF_START_INDEX) {
- InternPoolIndex param_ptr_ty = internPtrConst(obj_type);
- (void)internPtrUav(param_ptr_ty, obj_ip);
- InternPoolIndex ret_mut_ptr = internPtrMutable(ret_ty);
- (void)internUndef(ret_ty);
+ InternPoolIndex param_ptr_ty
+ = internPtrConst(sema, obj_type);
+ (void)internPtrUav(sema, param_ptr_ty, obj_ip);
+ InternPoolIndex ret_mut_ptr
+ = internPtrMutable(sema, ret_ty);
+ (void)internUndef(sema, ret_ty);
InternPoolIndex ret_alloc
- = internPtrComptimeAlloc(ret_mut_ptr, 0);
+ = internPtrComptimeAlloc(sema, ret_mut_ptr, 0);
fn_sema.comptime_ret_ptr = ret_alloc;
}
}
@@ -6422,16 +6373,16 @@ static AirInstRef comptimeFieldCall(Sema* sema, SemaBlock* block,
InternPoolIndex result_ip = AIR_REF_IS_IP(result)
? AIR_REF_TO_IP(result)
: IP_INDEX_VOID_VALUE;
- const Nav* fn_nav2 = ipGetNav(fn_nav_idx);
+ const Nav* fn_nav2 = ipGetNav(sema->ip, fn_nav_idx);
InternPoolIndex func_ip = fn_nav2->resolved_type;
if (func_ip != IP_INDEX_NONE
- && s_module_ip->items[func_ip].tag == IP_KEY_FUNC) {
+ && sema->ip->items[func_ip].tag == IP_KEY_FUNC) {
InternPoolKey mc_key;
memset(&mc_key, 0, sizeof(mc_key));
mc_key.tag = IP_KEY_MEMOIZED_CALL;
mc_key.data.memoized_call.func = func_ip;
mc_key.data.memoized_call.result = result_ip;
- (void)ipIntern(s_module_ip, mc_key);
+ (void)ipIntern(sema->ip, mc_key);
}
}
@@ -6674,13 +6625,15 @@ static AirInstRef zirCall(
// Load base import (e.g. std.zig).
Ast base_ast;
memset(&base_ast, 0, sizeof(base_ast));
- Zir base_zir = loadStdImportZir(sema->module_root,
- sema->source_dir, base_import, &base_ast);
+ Zir base_zir = loadStdImportZir(sema,
+ sema->zcu->comp->config.module_root, sema->source_dir,
+ base_import, &base_ast);
if (base_zir.inst_len > 0) {
// Follow intermediate fields (all but last).
char cur_dir[1024];
- computeSourceDir(sema->module_root, sema->source_dir,
- base_import, cur_dir, sizeof(cur_dir));
+ computeSourceDir(sema->zcu->comp->config.module_root,
+ sema->source_dir, base_import, cur_dir,
+ sizeof(cur_dir));
Zir cur_zir = base_zir;
Ast cur_ast = base_ast;
for (uint32_t fi = 0; fi + 1 < nfields; fi++) {
@@ -6707,8 +6660,8 @@ static AirInstRef zirCall(
// Load the sub-module.
Ast next_ast;
memset(&next_ast, 0, sizeof(next_ast));
- Zir next_zir
- = loadImportZir(cur_dir, sub_import, &next_ast);
+ Zir next_zir = loadImportZir(
+ sema, cur_dir, sub_import, &next_ast);
// Compute new source dir BEFORE freeing cur_zir,
// since sub_import points into cur_zir string bytes.
char new_dir[1024];
@@ -6732,8 +6685,8 @@ static AirInstRef zirCall(
if (fn_import) {
Ast fn_ast;
memset(&fn_ast, 0, sizeof(fn_ast));
- Zir fn_zir
- = loadImportZir(cur_dir, fn_import, &fn_ast);
+ Zir fn_zir = loadImportZir(
+ sema, cur_dir, fn_import, &fn_ast);
// Compute source dir BEFORE freeing cur_zir,
// since fn_import points into cur_zir string
// bytes.
@@ -6745,10 +6698,10 @@ static AirInstRef zirCall(
if (fn_zir.inst_len > 0) {
// Try direct lookup first, then follow
// re-exports (e.g. scalbn -> ldexp).
- func_inst
- = findFuncInModuleZir(fn_src_dir, &fn_zir,
- &fn_ast, fn_name, import_source_dir,
- sizeof(import_source_dir));
+ func_inst = findFuncInModuleZir(sema,
+ fn_src_dir, &fn_zir, &fn_ast, fn_name,
+ import_source_dir,
+ sizeof(import_source_dir));
if (func_inst != UINT32_MAX) {
// If findFuncInModuleZir found it
// directly (no re-export), it did
@@ -6790,8 +6743,9 @@ static AirInstRef zirCall(
// fields[0] = "panic"
Ast base_ast;
memset(&base_ast, 0, sizeof(base_ast));
- Zir base_zir = loadStdImportZir(sema->module_root,
- sema->source_dir, base_import, &base_ast);
+ Zir base_zir = loadStdImportZir(sema,
+ sema->zcu->comp->config.module_root, sema->source_dir,
+ base_import, &base_ast);
if (base_zir.inst_len > 0) {
const char* field_name = fields[0];
func_inst = findFuncInstInZir(&base_zir, field_name);
@@ -6801,8 +6755,8 @@ static AirInstRef zirCall(
import_zir = base_zir;
import_ast = base_ast;
is_cross_module = true;
- computeSourceDir(sema->module_root, sema->source_dir,
- base_import, import_source_dir,
+ computeSourceDir(sema->zcu->comp->config.module_root,
+ sema->source_dir, base_import, import_source_dir,
sizeof(import_source_dir));
} else {
zirDeinit(&base_zir);
@@ -6829,12 +6783,12 @@ static AirInstRef zirCall(
const char* field_name
= (const char*)&sema->code.string_bytes[callee_name_idx];
import_zir = loadImportZir(
- sema->source_dir, import_path, &import_ast);
+ sema, sema->source_dir, import_path, &import_ast);
if (import_zir.inst_len > 0) {
- computeSourceDir(sema->module_root, sema->source_dir,
- import_path, import_source_dir,
+ computeSourceDir(sema->zcu->comp->config.module_root,
+ sema->source_dir, import_path, import_source_dir,
sizeof(import_source_dir));
- func_inst = findFuncInModuleZir(import_source_dir,
+ func_inst = findFuncInModuleZir(sema, import_source_dir,
&import_zir, &import_ast, field_name,
import_source_dir, sizeof(import_source_dir));
if (func_inst != UINT32_MAX) {
@@ -6865,8 +6819,9 @@ static AirInstRef zirCall(
// it (which may itself be an @import).
Ast base_ast;
memset(&base_ast, 0, sizeof(base_ast));
- Zir base_zir = loadStdImportZir(sema->module_root,
- sema->source_dir, chain_import, &base_ast);
+ Zir base_zir = loadStdImportZir(sema,
+ sema->zcu->comp->config.module_root, sema->source_dir,
+ chain_import, &base_ast);
if (base_zir.inst_len > 0) {
// Find chain_field in base module; if it's
// also an @import, follow it.
@@ -6880,11 +6835,12 @@ static AirInstRef zirCall(
sub_import_ptr);
// Compute source_dir for the base import.
char base_dir[1024];
- computeSourceDir(sema->module_root,
+ computeSourceDir(
+ sema->zcu->comp->config.module_root,
sema->source_dir, chain_import, base_dir,
sizeof(base_dir));
import_zir = loadImportZir(
- base_dir, sub_import, &import_ast);
+ sema, base_dir, sub_import, &import_ast);
zirDeinit(&base_zir);
astDeinit(&base_ast);
if (import_zir.inst_len > 0) {
@@ -6894,7 +6850,7 @@ static AirInstRef zirCall(
computeSourceDir(NULL, base_dir, sub_import,
import_source_dir,
sizeof(import_source_dir));
- func_inst = findFuncInModuleZir(
+ func_inst = findFuncInModuleZir(sema,
import_source_dir, &import_zir,
&import_ast, field_name, import_source_dir,
sizeof(import_source_dir));
@@ -6917,7 +6873,8 @@ static AirInstRef zirCall(
import_zir = base_zir;
import_ast = base_ast;
is_cross_module = true;
- computeSourceDir(sema->module_root,
+ computeSourceDir(
+ sema->zcu->comp->config.module_root,
sema->source_dir, chain_import,
import_source_dir,
sizeof(import_source_dir));
@@ -6969,25 +6926,27 @@ static AirInstRef zirCall(
// Load std module, find sub-module
Ast alias_ast;
memset(&alias_ast, 0, sizeof(alias_ast));
- Zir alias_zir = loadStdImportZir(sema->module_root,
+ Zir alias_zir = loadStdImportZir(sema,
+ sema->zcu->comp->config.module_root,
sema->source_dir, alias_import, &alias_ast);
if (alias_zir.inst_len > 0) {
const char* sub_path = findDeclImportPathInZir(
&alias_zir, alias_field);
if (sub_path) {
char alias_dir[1024];
- computeSourceDir(sema->module_root,
+ computeSourceDir(
+ sema->zcu->comp->config.module_root,
sema->source_dir, alias_import,
alias_dir, sizeof(alias_dir));
- import_zir = loadImportZir(
- alias_dir, sub_path, &import_ast);
+ import_zir = loadImportZir(sema, alias_dir,
+ sub_path, &import_ast);
zirDeinit(&alias_zir);
astDeinit(&alias_ast);
if (import_zir.inst_len > 0) {
computeSourceDir(NULL, alias_dir,
sub_path, import_source_dir,
sizeof(import_source_dir));
- func_inst = findFuncInModuleZir(
+ func_inst = findFuncInModuleZir(sema,
import_source_dir, &import_zir,
&import_ast, fn_field,
import_source_dir,
@@ -7009,7 +6968,8 @@ static AirInstRef zirCall(
const char* mid_field = fn_field;
Ast base_ast;
memset(&base_ast, 0, sizeof(base_ast));
- Zir base_zir = loadStdImportZir(sema->module_root,
+ Zir base_zir = loadStdImportZir(sema,
+ sema->zcu->comp->config.module_root,
sema->source_dir, base_import, &base_ast);
if (base_zir.inst_len > 0) {
const char* sub_import_ptr
@@ -7021,11 +6981,12 @@ static AirInstRef zirCall(
snprintf(sub_import, sizeof(sub_import),
"%s", sub_import_ptr);
char base_dir[1024];
- computeSourceDir(sema->module_root,
+ computeSourceDir(
+ sema->zcu->comp->config.module_root,
sema->source_dir, base_import,
base_dir, sizeof(base_dir));
- import_zir = loadImportZir(
- base_dir, sub_import, &import_ast);
+ import_zir = loadImportZir(sema, base_dir,
+ sub_import, &import_ast);
zirDeinit(&base_zir);
astDeinit(&base_ast);
if (import_zir.inst_len > 0) {
@@ -7037,7 +6998,7 @@ static AirInstRef zirCall(
computeSourceDir(NULL, base_dir,
sub_import, import_source_dir,
sizeof(import_source_dir));
- func_inst = findFuncInModuleZir(
+ func_inst = findFuncInModuleZir(sema,
import_source_dir, &import_zir,
&import_ast, fn_name,
import_source_dir,
@@ -7085,9 +7046,9 @@ static AirInstRef zirCall(
if (base_imp) {
Ast b_ast;
memset(&b_ast, 0, sizeof(b_ast));
- Zir b_zir = loadStdImportZir(
- sema->module_root, sema->source_dir,
- base_imp, &b_ast);
+ Zir b_zir = loadStdImportZir(sema,
+ sema->zcu->comp->config.module_root,
+ sema->source_dir, base_imp, &b_ast);
if (b_zir.inst_len > 0) {
const char* sp_ptr
= findDeclImportPathInZir(
@@ -7098,11 +7059,13 @@ static AirInstRef zirCall(
snprintf(
sp, sizeof(sp), "%s", sp_ptr);
char bd[1024];
- computeSourceDir(sema->module_root,
+ computeSourceDir(
+ sema->zcu->comp->config
+ .module_root,
sema->source_dir, base_imp, bd,
sizeof(bd));
import_zir = loadImportZir(
- bd, sp, &import_ast);
+ sema, bd, sp, &import_ast);
zirDeinit(&b_zir);
astDeinit(&b_ast);
if (import_zir.inst_len > 0) {
@@ -7149,13 +7112,14 @@ static AirInstRef zirCall(
const char* field_name = NULL;
if (findDeclImportFieldVal(
sema, callee_name_idx, &import_path, &field_name)) {
- import_zir
- = loadImportZir(sema->source_dir, import_path, &import_ast);
+ import_zir = loadImportZir(
+ sema, sema->source_dir, import_path, &import_ast);
if (import_zir.inst_len > 0) {
- computeSourceDir(sema->module_root, sema->source_dir,
- import_path, import_source_dir, sizeof(import_source_dir));
- func_inst = findFuncInModuleZir(import_source_dir, &import_zir,
- &import_ast, field_name, import_source_dir,
+ computeSourceDir(sema->zcu->comp->config.module_root,
+ sema->source_dir, import_path, import_source_dir,
+ sizeof(import_source_dir));
+ func_inst = findFuncInModuleZir(sema, import_source_dir,
+ &import_zir, &import_ast, field_name, import_source_dir,
sizeof(import_source_dir));
if (func_inst != UINT32_MAX) {
saved_code = sema->code;
@@ -8482,7 +8446,7 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
// The body is NOT analyzed (inline functions get inlined at
// the call site, not compiled as standalone function bodies).
uint32_t ns_idx = (sema->file_idx != UINT32_MAX)
- ? s_file_namespace[sema->file_idx]
+ ? sema->zcu->file_namespaces[sema->file_idx]
: UINT32_MAX;
// Resolve return type.
@@ -8490,13 +8454,13 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
if (fi.ret_ty_body_len == 1) {
uint32_t ret_ref = sema->code.extra[fi.ret_ty_ref_pos];
InternPoolIndex resolved = resolveZirTypeRef(
- &sema->code, ret_ref, ns_idx, sema->file_idx);
+ sema, &sema->code, ret_ref, ns_idx, sema->file_idx);
if (resolved != IP_INDEX_NONE)
ret_ty = resolved;
} else if (fi.ret_ty_body_len == 2) {
uint32_t type_inst = sema->code.extra[fi.ret_ty_ref_pos];
InternPoolIndex resolved = resolveZirTypeInst(
- &sema->code, type_inst, ns_idx, sema->file_idx);
+ sema, &sema->code, type_inst, ns_idx, sema->file_idx);
if (resolved != IP_INDEX_NONE)
ret_ty = resolved;
}
@@ -8533,20 +8497,21 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
func_name
= (const char*)&sema->code.string_bytes[sema->cur_decl_name];
uint32_t func_nav = UINT32_MAX;
- if (func_name && s_root_file_idx != UINT32_MAX) {
- uint32_t rns = s_file_namespace[s_root_file_idx];
- func_nav = findNavInNamespace(rns, func_name);
+ if (func_name && sema->zcu->root_file_idx != UINT32_MAX) {
+ uint32_t rns
+ = sema->zcu->file_namespaces[sema->zcu->root_file_idx];
+ func_nav = findNavInNamespace(sema, rns, func_name);
}
if (func_nav != UINT32_MAX) {
- (void)internFuncDecl(func_nav, func_type_ip);
- Nav* fn = ipGetNav(func_nav);
+ (void)internFuncDecl(sema, func_nav, func_type_ip);
+ Nav* fn = ipGetNav(sema->ip, func_nav);
fn->resolved_type = func_type_ip;
}
// Ported from Sema.zig zirFuncFancy: the CC body evaluation
// calls getBuiltinType(.CallingConvention) which triggers
// ensureMemoizedStateResolved(.main), resolving all builtins.
- (void)getBuiltinTypeC(2); // 2 = CallingConvention
+ (void)getBuiltinTypeC(sema, 2); // 2 = CallingConvention
return;
}
@@ -8560,19 +8525,19 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
// types (pointers, optionals, etc.) that create IP entries.
InternPoolIndex ret_ty = IP_INDEX_VOID_TYPE;
uint32_t ns_idx = (sema->file_idx != UINT32_MAX)
- ? s_file_namespace[sema->file_idx]
+ ? sema->zcu->file_namespaces[sema->file_idx]
: UINT32_MAX;
if (fi.ret_ty_body_len == 1) {
uint32_t ret_ref = sema->code.extra[fi.ret_ty_ref_pos];
InternPoolIndex resolved = resolveZirTypeRef(
- &sema->code, ret_ref, ns_idx, sema->file_idx);
+ sema, &sema->code, ret_ref, ns_idx, sema->file_idx);
if (resolved != IP_INDEX_NONE)
ret_ty = resolved;
} else if (fi.ret_ty_body_len == 2) {
// 2-instruction body: type instruction + break_inline.
uint32_t type_inst = sema->code.extra[fi.ret_ty_ref_pos];
InternPoolIndex resolved = resolveZirTypeInst(
- &sema->code, type_inst, ns_idx, sema->file_idx);
+ sema, &sema->code, type_inst, ns_idx, sema->file_idx);
if (resolved != IP_INDEX_NONE)
ret_ty = resolved;
}
@@ -8610,12 +8575,12 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
ZirInstRef tref
= sema->code.inst_datas[bi2].break_data.operand;
(void)resolveZirTypeRef(
- &sema->code, tref, ns_idx, sema->file_idx);
+ sema, &sema->code, tref, ns_idx, sema->file_idx);
}
} else if (type_body_len == 2) {
uint32_t ti = sema->code.extra[pp + 2];
(void)resolveZirTypeInst(
- &sema->code, ti, ns_idx, sema->file_idx);
+ sema, &sema->code, ti, ns_idx, sema->file_idx);
}
}
}
@@ -8646,11 +8611,11 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
AirInstRef res = resolveInst(sema, operand);
if (AIR_REF_IS_IP(res)) {
InternPoolIndex ip_idx = AIR_REF_TO_IP(res);
- if (s_module_ip->items[ip_idx].tag
+ if (sema->ip->items[ip_idx].tag
== IP_KEY_ENUM_LITERAL) {
uint32_t str_idx
- = s_module_ip->items[ip_idx].data.enum_literal;
- cc_name = (const char*)&s_module_ip
+ = sema->ip->items[ip_idx].data.enum_literal;
+ cc_name = (const char*)&sema->ip
->string_bytes[str_idx];
}
}
@@ -8669,13 +8634,14 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
// ensureMemoizedStateResolved(.main), then coerces the
// enum literal to the CallingConvention union type.
InternPoolIndex cc_type_ip
- = getBuiltinTypeC(2); // 2 = CallingConvention
+ = getBuiltinTypeC(sema, 2); // 2 = CallingConvention
if (cc_type_ip != IP_INDEX_NONE) {
- uint32_t cc_ns = findNamespaceForType(cc_type_ip);
+ uint32_t cc_ns = findNamespaceForType(sema, cc_type_ip);
if (cc_ns != UINT32_MAX) {
- uint32_t c_nav = findNavInNamespace(cc_ns, cc_name);
+ uint32_t c_nav
+ = findNavInNamespace(sema, cc_ns, cc_name);
if (c_nav != UINT32_MAX) {
- (void)ensureNavValUpToDate(c_nav);
+ (void)ensureNavValUpToDate(sema, c_nav);
}
}
}
@@ -8705,13 +8671,14 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
= (const char*)&sema->code.string_bytes[sema->cur_decl_name];
}
uint32_t func_nav = UINT32_MAX;
- if (func_name && s_root_file_idx != UINT32_MAX) {
- uint32_t rns = s_file_namespace[s_root_file_idx];
- func_nav = findNavInNamespace(rns, func_name);
+ if (func_name && sema->zcu->root_file_idx != UINT32_MAX) {
+ uint32_t rns
+ = sema->zcu->file_namespaces[sema->zcu->root_file_idx];
+ func_nav = findNavInNamespace(sema, rns, func_name);
}
if (func_nav != UINT32_MAX) {
- (void)internFuncDecl(func_nav, func_type_ip);
- Nav* fn = ipGetNav(func_nav);
+ (void)internFuncDecl(sema, func_nav, func_type_ip);
+ Nav* fn = ipGetNav(sema->ip, func_nav);
fn->resolved_type = func_type_ip;
}
@@ -8854,7 +8821,7 @@ static void zirStructDecl(Sema* sema, SemaBlock* block, uint32_t inst) {
// Note: we do NOT call ensureFileAnalyzedC here — the imported
// module's struct_type is created later when the import is
// actually accessed (during DECL_VAL in the comptime block body).
- if (s_in_main_analysis && sema->source_dir) {
+ if (sema->zcu->in_main_analysis && sema->source_dir) {
for (uint32_t d = 0; d < decls_len; d++) {
uint32_t decl_inst = decl_list[d];
uint32_t payload
@@ -8869,8 +8836,8 @@ static void zirStructDecl(Sema* sema, SemaBlock* block, uint32_t inst) {
continue;
// Verify the import path is resolvable (without loading).
char import_full[1024];
- if (!resolveImportPath(sema->source_dir, import_path, import_full,
- sizeof(import_full)))
+ if (!resolveImportPath(sema, sema->source_dir, import_path,
+ import_full, sizeof(import_full)))
continue;
// Create ptr_type(*const type) + ptr_nav for the import nav.
// The child type is TYPE_TYPE because import declarations
@@ -8879,8 +8846,8 @@ static void zirStructDecl(Sema* sema, SemaBlock* block, uint32_t inst) {
uint32_t decl_name_idx = sema->code.extra[payload + 6];
const char* decl_name
= (const char*)&sema->code.string_bytes[decl_name_idx];
- uint32_t ns_idx = s_file_namespace[sema->file_idx];
- uint32_t nav = findNavInNamespace(ns_idx, decl_name);
+ uint32_t ns_idx = sema->zcu->file_namespaces[sema->file_idx];
+ uint32_t nav = findNavInNamespace(sema, ns_idx, decl_name);
if (nav != UINT32_MAX) {
// Force-create a new ptr_type instead of deduplicating.
// In the Zig compiler, the IP is sharded and this ptr_type
@@ -8894,8 +8861,8 @@ static void zirStructDecl(Sema* sema, SemaBlock* block, uint32_t inst) {
pt_key.data.ptr_type.flags
= PTR_FLAGS_SIZE_ONE | PTR_FLAGS_IS_CONST;
pt_key.data.ptr_type.packed_offset = 0;
- InternPoolIndex pt = ipForceIntern(s_module_ip, pt_key);
- (void)internNavPtr(pt, nav);
+ InternPoolIndex pt = ipForceIntern(sema->ip, pt_key);
+ (void)internNavPtr(sema, pt, nav);
}
}
}
@@ -8905,7 +8872,7 @@ static void zirStructDecl(Sema* sema, SemaBlock* block, uint32_t inst) {
// process function declarations in Pass 2a, zirFunc knows which
// functions are exported (even though the comptime block hasn't
// been fully evaluated yet).
- if (s_in_main_analysis) {
+ if (sema->zcu->in_main_analysis) {
for (uint32_t d = 0; d < decls_len; d++) {
uint32_t di2 = decl_list[d];
uint32_t pl2
@@ -8932,7 +8899,7 @@ static void zirStructDecl(Sema* sema, SemaBlock* block, uint32_t inst) {
continue;
uint32_t ni = sema->code.inst_datas[ei].str_tok.start;
if (sema->num_exported_decl_names < MAX_EXPORTED_DECL_NAMES) {
- s_exported_decl_names[sema->num_exported_decl_names++]
+ sema->exported_decl_names[sema->num_exported_decl_names++]
= ni;
}
}
@@ -9238,15 +9205,15 @@ static AirInstRef semaResolveSwitchComptime(
if (is_enum_operand && operand_enum_type != IP_INDEX_NONE) {
// Find the enum declaration ZIR to look up field names/values.
uint32_t enum_nav = UINT32_MAX;
- for (uint32_t ni = 0; ni < ipNavCount(); ni++) {
- if (ipGetNav(ni)->resolved_type == operand_enum_type) {
+ for (uint32_t ni = 0; ni < ipNavCount(sema->ip); ni++) {
+ if (ipGetNav(sema->ip, ni)->resolved_type == operand_enum_type) {
enum_nav = ni;
break;
}
}
if (enum_nav != UINT32_MAX) {
const Zir* enum_zir = NULL;
- uint32_t enum_inst = findEnumDeclForNav(enum_nav, &enum_zir);
+ uint32_t enum_inst = findEnumDeclForNav(sema, enum_nav, &enum_zir);
if (enum_inst != UINT32_MAX && enum_zir != NULL) {
for (uint32_t i = 0; i < total_items; i++) {
// Get the item's name from the ZIR enum_literal inst.
@@ -9270,11 +9237,11 @@ static AirInstRef semaResolveSwitchComptime(
if (fidx == UINT32_MAX)
continue;
InternPoolIndex int_val
- = getEnumFieldIntVal(enum_zir, enum_inst, fidx);
+ = getEnumFieldIntVal(sema, enum_zir, enum_inst, fidx);
if (int_val == IP_INDEX_NONE)
continue;
coerced_items[i]
- = internEnumTag(operand_enum_type, int_val);
+ = internEnumTag(sema, operand_enum_type, int_val);
}
}
}
@@ -9617,9 +9584,8 @@ static AirInstRef evalCrossModuleDeclValue(
// resolution (e.g. common.zig -> builtin.abi) from causing
// infinite recursion or expensive file I/O.
Sema mini_sema;
- semaInit(&mini_sema, parent_sema->ip, *import_zir);
+ semaInit(&mini_sema, parent_sema->zcu, *import_zir);
mini_sema.source_dir = NULL;
- mini_sema.module_root = NULL;
SemaBlock ct_block;
semaBlockInit(&ct_block, &mini_sema, NULL);
@@ -9688,20 +9654,22 @@ static AirInstRef zirFieldValComptime(
InternPoolKeyTag kt = sema->ip->items[obj_ip].tag;
if (kt == IP_KEY_STRUCT_TYPE || kt == IP_KEY_UNION_TYPE
|| kt == IP_KEY_ENUM_TYPE) {
- uint32_t base_ns = findNamespaceForType(obj_ip);
+ uint32_t base_ns = findNamespaceForType(sema, obj_ip);
if (base_ns != UINT32_MAX) {
- uint32_t member_nav = findNavInNamespace(base_ns, field_name);
+ uint32_t member_nav
+ = findNavInNamespace(sema, base_ns, field_name);
if (member_nav != UINT32_MAX) {
- InternPoolIndex val = ensureNavValUpToDate(member_nav);
+ InternPoolIndex val
+ = ensureNavValUpToDate(sema, member_nav);
if (val != IP_INDEX_NONE) {
// Create ptr_type + ptr_nav matching Zig's
// analyzeNavRefInner. In Zig, fieldVal for
// namespace lookups goes through analyzeNavRef
// which creates these entries.
- if (s_in_main_analysis) {
+ if (sema->zcu->in_main_analysis) {
InternPoolIndex ptr_ty
- = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(ptr_ty, member_nav);
+ = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, ptr_ty, member_nav);
}
return AIR_REF_FROM_IP(val);
}
@@ -9733,7 +9701,7 @@ static AirInstRef zirFieldValComptime(
if (import_path) {
Ast import_ast;
Zir import_zir = loadImportZir(
- sema->source_dir, import_path, &import_ast);
+ sema, sema->source_dir, import_path, &import_ast);
if (import_zir.inst_len > 0) {
uint32_t field_decl
= findDeclInstByNameInZir(&import_zir, field_name);
@@ -9782,17 +9750,17 @@ static AirInstRef zirFieldPtr(Sema* sema, SemaBlock* block, uint32_t inst) {
InternPoolIndex obj_ip = AIR_REF_TO_IP(obj);
InternPoolIndex obj_type = ipTypeOf(sema->ip, obj_ip);
if (obj_type == IP_INDEX_TYPE_TYPE) {
- uint32_t ns = findNamespaceForType(obj_ip);
+ uint32_t ns = findNamespaceForType(sema, obj_ip);
if (ns != UINT32_MAX) {
- uint32_t nav_idx = findNavInNamespace(ns, field_name);
+ uint32_t nav_idx = findNavInNamespace(sema, ns, field_name);
if (nav_idx != UINT32_MAX) {
- const Nav* n = ipGetNav(nav_idx);
+ const Nav* n = ipGetNav(sema->ip, nav_idx);
if (n->resolved_type != IP_INDEX_NONE) {
// Check if a ptr_nav already exists for this
// nav (created during init). If so, return it
// to match Zig's analyzeNavRef pattern.
InternPoolIndex val_ty = n->resolved_type;
- InternPoolIndex ptr_ty = internPtrConst(val_ty);
+ InternPoolIndex ptr_ty = internPtrConst(sema, val_ty);
InternPoolKey pk;
memset(&pk, 0, sizeof(pk));
pk.tag = IP_KEY_PTR_NAV;
@@ -9824,15 +9792,15 @@ static AirInstRef zirFieldPtr(Sema* sema, SemaBlock* block, uint32_t inst) {
InternPoolIndex union_ty = sema->comptime_inner_type;
uint32_t field_idx = UINT32_MAX;
InternPoolIndex field_type
- = resolveUnionFieldByName(union_ty, field_name, &field_idx);
- InternPoolIndex tag_enum = findUnionTagEnum(union_ty);
+ = resolveUnionFieldByName(sema, union_ty, field_name, &field_idx);
+ InternPoolIndex tag_enum = findUnionTagEnum(sema, union_ty);
if (field_type != IP_INDEX_NONE && tag_enum != IP_INDEX_NONE
&& field_idx != UINT32_MAX) {
// 1. Create *mut FieldType (matches upstream ptrTypeSema).
- InternPoolIndex field_ptr_ty = internPtrMutable(field_type);
+ InternPoolIndex field_ptr_ty = internPtrMutable(sema, field_type);
// 2. Create enum_tag (matches upstream enumValueFieldIndex).
InternPoolIndex int_val
- = internTypedInt(IP_INDEX_U8_TYPE, field_idx);
+ = internTypedInt(sema, IP_INDEX_U8_TYPE, field_idx);
InternPoolKey etk;
memset(&etk, 0, sizeof(etk));
etk.tag = IP_KEY_ENUM_TAG;
@@ -9840,7 +9808,7 @@ static AirInstRef zirFieldPtr(Sema* sema, SemaBlock* block, uint32_t inst) {
etk.data.enum_tag.int_val = int_val;
InternPoolIndex field_tag = ipForceIntern(sema->ip, etk);
// 3. Create undef(FieldType) (matches upstream undefValue).
- InternPoolIndex undef_val = internUndef(field_type);
+ InternPoolIndex undef_val = internUndef(sema, field_type);
// 4. Create union_value (matches upstream unionValue).
InternPoolKey uvk;
memset(&uvk, 0, sizeof(uvk));
@@ -10091,11 +10059,11 @@ static AirInstRef zirDeclLiteralComptime(Sema* sema, uint32_t inst) {
if (AIR_REF_IS_IP(lhs_result)) {
InternPoolIndex lhs_ip = AIR_REF_TO_IP(lhs_result);
// The LHS should be a type. Find its namespace.
- uint32_t ns = findNamespaceForType(lhs_ip);
+ uint32_t ns = findNamespaceForType(sema, lhs_ip);
if (ns != UINT32_MAX) {
- uint32_t nav = findNavInNamespace(ns, field_name);
+ uint32_t nav = findNavInNamespace(sema, ns, field_name);
if (nav != UINT32_MAX) {
- InternPoolIndex val = ensureNavValUpToDate(nav);
+ InternPoolIndex val = ensureNavValUpToDate(sema, nav);
if (val != IP_INDEX_NONE)
return AIR_REF_FROM_IP(val);
}
@@ -10283,8 +10251,8 @@ static AirInstRef zirExtended(Sema* sema, SemaBlock* block, uint32_t inst) {
// namespace this code is declared in).
// Ported from src/Sema.zig:16800 zirThis.
if (sema->file_idx != UINT32_MAX) {
- uint32_t ns_idx = s_file_namespace[sema->file_idx];
- return AIR_REF_FROM_IP(s_namespaces[ns_idx].owner_type);
+ uint32_t ns_idx = sema->zcu->file_namespaces[sema->file_idx];
+ return AIR_REF_FROM_IP(sema->zcu->namespaces[ns_idx].owner_type);
}
return AIR_REF_FROM_IP(IP_INDEX_VOID_TYPE);
}
@@ -10344,22 +10312,27 @@ static AirInstRef zirExtended(Sema* sema, SemaBlock* block, uint32_t inst) {
if (opcode == ZIR_EXT_BUILTIN_VALUE) {
uint16_t bv_kind = sema->code.inst_datas[inst].extended.small;
if (bv_kind == ZIR_BUILTIN_VALUE_CALLING_CONVENTION
- && s_builtin_file_idx != UINT32_MAX) {
- uint32_t builtin_ns = s_file_namespace[s_builtin_file_idx];
+ && sema->zcu->builtin_file_idx != UINT32_MAX) {
+ uint32_t builtin_ns
+ = sema->zcu->file_namespaces[sema->zcu->builtin_file_idx];
uint32_t cc_nav
- = findNavInNamespace(builtin_ns, "CallingConvention");
+ = findNavInNamespace(sema, builtin_ns, "CallingConvention");
if (cc_nav != UINT32_MAX) {
- InternPoolIndex cc_type = ipGetNav(cc_nav)->resolved_type;
+ InternPoolIndex cc_type
+ = ipGetNav(sema->ip, cc_nav)->resolved_type;
if (cc_type != IP_INDEX_NONE)
return AIR_REF_FROM_IP(cc_type);
}
}
if (bv_kind == ZIR_BUILTIN_VALUE_EXPORT_OPTIONS
- && s_builtin_file_idx != UINT32_MAX) {
- uint32_t builtin_ns = s_file_namespace[s_builtin_file_idx];
- uint32_t eo_nav = findNavInNamespace(builtin_ns, "ExportOptions");
+ && sema->zcu->builtin_file_idx != UINT32_MAX) {
+ uint32_t builtin_ns
+ = sema->zcu->file_namespaces[sema->zcu->builtin_file_idx];
+ uint32_t eo_nav
+ = findNavInNamespace(sema, builtin_ns, "ExportOptions");
if (eo_nav != UINT32_MAX) {
- InternPoolIndex eo_type = ipGetNav(eo_nav)->resolved_type;
+ InternPoolIndex eo_type
+ = ipGetNav(sema->ip, eo_nav)->resolved_type;
if (eo_type != IP_INDEX_NONE)
return AIR_REF_FROM_IP(eo_type);
}
@@ -10453,7 +10426,7 @@ static bool zirBlockInline(Sema* sema, SemaBlock* block, uint32_t inst) {
// (*const [len:0]u8), ptr_uav. Returns the ptr_uav IP index.
// Ported from src/Sema.zig addStrLit + uavRef.
static InternPoolIndex internStrLit(
- InternPool* ip, const char* str, uint32_t len) {
+ Sema* sema, InternPool* ip, const char* str, uint32_t len) {
// type_array_big: [len:0]u8.
InternPoolKey arr_key;
memset(&arr_key, 0, sizeof(arr_key));
@@ -10473,7 +10446,7 @@ static InternPoolIndex internStrLit(
InternPoolIndex bytes_val = ipIntern(ip, bytes_key);
// type_pointer: *const [len:0]u8.
- InternPoolIndex arr_ptr_type = internPtrConst(arr_type);
+ InternPoolIndex arr_ptr_type = internPtrConst(sema, arr_type);
// ptr_uav: pointer to the bytes value.
InternPoolKey uav_key;
@@ -10490,21 +10463,22 @@ static InternPoolIndex internStrLit(
// ensureMemoizedStateUpToDate. Called on first getBuiltinType or
// @export to create IP entries matching the Zig compiler's
// ensureMemoizedStateResolved(.main) chain.
-static void analyzeMemoizedStateC(void) {
- if (s_memoized_main_resolved)
+static void analyzeMemoizedStateC(Sema* sema) {
+ if (sema->zcu->memoized_main_resolved)
return;
- s_memoized_main_resolved = true;
+ sema->zcu->memoized_main_resolved = true;
- if (s_builtin_file_idx == UINT32_MAX)
+ if (sema->zcu->builtin_file_idx == UINT32_MAX)
return;
- uint32_t builtin_ns = s_file_namespace[s_builtin_file_idx];
+ uint32_t builtin_ns
+ = sema->zcu->file_namespaces[sema->zcu->builtin_file_idx];
for (int i = 0; i < NUM_BUILTIN_DECL_MAIN; i++)
- s_builtin_decl_values[i] = IP_INDEX_NONE;
+ sema->zcu->builtin_decl_values[i] = IP_INDEX_NONE;
// Record IP position before memoized resolution for shard simulation.
- s_preamble_memoized_start = s_module_ip->items_len;
- s_preamble_builtin_nav_count = 0;
+ sema->zcu->preamble_memoized_start = sema->ip->items_len;
+ sema->zcu->preamble_builtin_nav_count = 0;
// AddressSpace (builtin index 1) is enum(u5) with 24 fields (values
// 0..23). Its comptime_int entries go into C's single IP hash table.
@@ -10520,7 +10494,7 @@ static void analyzeMemoizedStateC(void) {
// The value 13 is target-specific (wasm32-wasi bootstrap constant):
// it equals the number of CC tag values the Zig compiler materializes
// during memoized state resolution for this target.
- s_enum_force_intern_threshold = 13;
+ sema->zcu->enum_force_intern_threshold = 13;
// Resolve .main-stage builtins. Ported from Sema.zig
// analyzeMemoizedState which iterates all BuiltinDecl values
@@ -10543,43 +10517,45 @@ static void analyzeMemoizedStateC(void) {
lookup_ns = builtin_ns;
} else {
InternPoolIndex parent_type
- = s_builtin_decl_values[entry->parent_idx];
+ = sema->zcu->builtin_decl_values[entry->parent_idx];
if (parent_type == IP_INDEX_NONE)
continue;
- lookup_ns = findNamespaceForType(parent_type);
+ lookup_ns = findNamespaceForType(sema, parent_type);
if (lookup_ns == UINT32_MAX)
continue;
}
- uint32_t nav = findNavInNamespace(lookup_ns, entry->lookup_name);
+ uint32_t nav = findNavInNamespace(sema, lookup_ns, entry->lookup_name);
if (nav == UINT32_MAX)
continue;
// Record nav ID for later clearing in shard simulation.
- if (s_preamble_builtin_nav_count < 5)
- s_preamble_builtin_navs[s_preamble_builtin_nav_count++] = nav;
+ if (sema->zcu->preamble_builtin_nav_count < 5)
+ sema->zcu->preamble_builtin_navs[sema->zcu
+ ->preamble_builtin_nav_count++]
+ = nav;
// Track CC (builtin 2) range: these entries are in Zig's local
// shard and should NOT be skipped during main analysis dedup.
if (i == 2)
- s_preamble_cc_start = s_module_ip->items_len;
+ sema->zcu->preamble_cc_start = sema->ip->items_len;
- InternPoolIndex val = ensureNavValUpToDate(nav);
+ InternPoolIndex val = ensureNavValUpToDate(sema, nav);
if (val == IP_INDEX_NONE)
continue;
if (i == 2)
- s_preamble_cc_end = s_module_ip->items_len;
+ sema->zcu->preamble_cc_end = sema->ip->items_len;
- s_builtin_decl_values[i] = val;
+ sema->zcu->builtin_decl_values[i] = val;
}
// Disable the threshold after memoized resolution so future
// enum resolutions during main analysis use normal ipIntern.
- s_enum_force_intern_threshold = 0;
+ sema->zcu->enum_force_intern_threshold = 0;
// Record IP position after memoized resolution.
- s_preamble_memoized_end = s_module_ip->items_len;
+ sema->zcu->preamble_memoized_end = sema->ip->items_len;
}
// --- ensureFullMemoizedStateC ---
@@ -10593,17 +10569,18 @@ static void analyzeMemoizedStateC(void) {
// evaluation or export resolution).
// Ported from upstream analyzeMemoizedState(.main): resolves ALL
// builtins 0-35 via ensureNavValUpToDate + resolveTypeFullyC.
-static void ensureFullMemoizedStateC(void) {
- if (s_full_memoized_resolved)
+static void ensureFullMemoizedStateC(Sema* sema) {
+ if (sema->zcu->full_memoized_resolved)
return;
- s_full_memoized_resolved = true;
+ sema->zcu->full_memoized_resolved = true;
// First ensure builtins 0-4 are resolved (preamble state).
- analyzeMemoizedStateC();
+ analyzeMemoizedStateC(sema);
- if (s_builtin_file_idx == UINT32_MAX)
+ if (sema->zcu->builtin_file_idx == UINT32_MAX)
return;
- uint32_t builtin_ns = s_file_namespace[s_builtin_file_idx];
+ uint32_t builtin_ns
+ = sema->zcu->file_namespaces[sema->zcu->builtin_file_idx];
// Shard simulation: clear builtins 0-4 state so they get re-resolved
// as fresh entries during main analysis. Ported from upstream: Zig's
@@ -10611,20 +10588,21 @@ static void ensureFullMemoizedStateC(void) {
// analysis creates fresh entries for builtins 0-4 types. We simulate
// this by enabling skip_dedup on the preamble memoized range and
// clearing the cached nav resolutions.
- if (s_preamble_memoized_end > s_preamble_memoized_start) {
- s_module_ip->skip_dedup_start = s_preamble_memoized_start;
- s_module_ip->skip_dedup_end = s_preamble_memoized_end;
- s_module_ip->cc_keep_start = s_preamble_cc_start;
- s_module_ip->cc_keep_end = s_preamble_cc_end;
+ if (sema->zcu->preamble_memoized_end
+ > sema->zcu->preamble_memoized_start) {
+ sema->ip->skip_dedup_start = sema->zcu->preamble_memoized_start;
+ sema->ip->skip_dedup_end = sema->zcu->preamble_memoized_end;
+ sema->ip->cc_keep_start = sema->zcu->preamble_cc_start;
+ sema->ip->cc_keep_end = sema->zcu->preamble_cc_end;
// Clear builtins 0-4 values so they're re-resolved.
for (int i = 0; i < 5 && i < NUM_BUILTIN_DECL_MAIN; i++)
- s_builtin_decl_values[i] = IP_INDEX_NONE;
+ sema->zcu->builtin_decl_values[i] = IP_INDEX_NONE;
// Clear nav resolved_type for builtins 0-4 so
// ensureNavValUpToDate re-resolves them.
- for (uint32_t n = 0; n < s_preamble_builtin_nav_count; n++) {
- Nav* nav = ipGetNav(s_preamble_builtin_navs[n]);
+ for (uint32_t n = 0; n < sema->zcu->preamble_builtin_nav_count; n++) {
+ Nav* nav = ipGetNav(sema->ip, sema->zcu->preamble_builtin_navs[n]);
nav->resolved_type = IP_INDEX_NONE;
}
}
@@ -10633,7 +10611,7 @@ static void ensureFullMemoizedStateC(void) {
// With shard simulation active, builtins 0-4 are re-resolved
// as fresh entries, matching upstream's sharded IP behavior.
for (int i = 0; i < NUM_BUILTIN_DECL_MAIN; i++) {
- if (s_builtin_decl_values[i] != IP_INDEX_NONE)
+ if (sema->zcu->builtin_decl_values[i] != IP_INDEX_NONE)
continue;
const BuiltinDeclEntry* entry = &s_builtin_decl_entries[i];
@@ -10642,30 +10620,30 @@ static void ensureFullMemoizedStateC(void) {
lookup_ns = builtin_ns;
} else {
InternPoolIndex parent_type
- = s_builtin_decl_values[entry->parent_idx];
+ = sema->zcu->builtin_decl_values[entry->parent_idx];
if (parent_type == IP_INDEX_NONE)
continue;
- lookup_ns = findNamespaceForType(parent_type);
+ lookup_ns = findNamespaceForType(sema, parent_type);
if (lookup_ns == UINT32_MAX)
continue;
}
- uint32_t nav = findNavInNamespace(lookup_ns, entry->lookup_name);
+ uint32_t nav = findNavInNamespace(sema, lookup_ns, entry->lookup_name);
if (nav == UINT32_MAX)
continue;
- InternPoolIndex val = ensureNavValUpToDate(nav);
+ InternPoolIndex val = ensureNavValUpToDate(sema, nav);
if (val == IP_INDEX_NONE)
continue;
- s_builtin_decl_values[i] = val;
+ sema->zcu->builtin_decl_values[i] = val;
}
// Disable shard simulation after Phase 1.
- s_module_ip->skip_dedup_start = 0;
- s_module_ip->skip_dedup_end = 0;
- s_module_ip->cc_keep_start = 0;
- s_module_ip->cc_keep_end = 0;
+ sema->ip->skip_dedup_start = 0;
+ sema->ip->skip_dedup_end = 0;
+ sema->ip->cc_keep_start = 0;
+ sema->ip->cc_keep_end = 0;
// Phase 2: Call resolveTypeFullyC on ALL type builtins.
// Ported from analyzeMemoizedState line 37560:
@@ -10673,9 +10651,9 @@ static void ensureFullMemoizedStateC(void) {
for (int i = 0; i < NUM_BUILTIN_DECL_MAIN; i++) {
if (!s_builtin_decl_entries[i].is_type)
continue;
- InternPoolIndex val = s_builtin_decl_values[i];
+ InternPoolIndex val = sema->zcu->builtin_decl_values[i];
if (val != IP_INDEX_NONE)
- resolveTypeFullyC(val);
+ resolveTypeFullyC(sema, val);
}
}
@@ -10683,9 +10661,9 @@ static void ensureFullMemoizedStateC(void) {
// Ported from Sema.zig getBuiltinType (line 37446).
// Calls ensureMemoizedStateResolved(.main) which resolves ALL builtins,
// then returns the requested builtin's type value.
-static InternPoolIndex getBuiltinTypeC(int builtin_idx) {
- ensureFullMemoizedStateC();
- return s_builtin_decl_values[builtin_idx];
+static InternPoolIndex getBuiltinTypeC(Sema* sema, int builtin_idx) {
+ ensureFullMemoizedStateC(sema);
+ return sema->zcu->builtin_decl_values[builtin_idx];
}
// --- zirExport ---
@@ -10694,7 +10672,7 @@ static void zirExport(Sema* sema, uint32_t inst) {
// Trigger memoized state resolution on first export.
// Ported from Sema.zig: zirExport → resolveExportOptions →
// getBuiltinType(.ExportOptions) → ensureMemoizedStateResolved(.main).
- ensureFullMemoizedStateC();
+ ensureFullMemoizedStateC(sema);
uint32_t payload_index = sema->code.inst_datas[inst].pl_node.payload_index;
uint32_t exported_ref = sema->code.extra[payload_index];
@@ -10705,7 +10683,7 @@ static void zirExport(Sema* sema, uint32_t inst) {
uint32_t name_idx
= sema->code.inst_datas[exported_inst].str_tok.start;
if (sema->num_exported_decl_names < MAX_EXPORTED_DECL_NAMES) {
- s_exported_decl_names[sema->num_exported_decl_names++]
+ sema->exported_decl_names[sema->num_exported_decl_names++]
= name_idx;
}
}
@@ -10761,13 +10739,14 @@ static void zirValidatePtrStructInit(Sema* sema, uint32_t inst) {
// Create int_usize(field_idx) — the field index as an interned value.
// Ported from Zig's ptr.ptrField which stores field index as byte_offset.
- (void)internTypedInt(IP_INDEX_USIZE_TYPE, sema->comptime_field_idx);
+ (void)internTypedInt(sema, IP_INDEX_USIZE_TYPE, sema->comptime_field_idx);
// Create ptr_field pointing to the struct field within the union.
// Ported from Sema.zig validateUnionInit reading back the field.
- InternPoolIndex field_ptr_ty = internPtrMutable(sema->comptime_field_type);
+ InternPoolIndex field_ptr_ty
+ = internPtrMutable(sema, sema->comptime_field_type);
InternPoolIndex pf = internPtrField(
- field_ptr_ty, sema->comptime_ret_ptr, sema->comptime_field_idx);
+ sema, field_ptr_ty, sema->comptime_ret_ptr, sema->comptime_field_idx);
(void)pf;
// Create repeated(field_type, opt_null) — the default value for
@@ -10811,7 +10790,7 @@ static AirInstRef zirStructInitEmptyResult(
// --- zirRetPtr ---
// Ported from src/Sema.zig zirRetPtr / retPtrComptime.
-static AirInstRef zirRetPtr(const Sema* sema, SemaBlock* block) {
+static AirInstRef zirRetPtr(Sema* sema, SemaBlock* block) {
// In comptime context with a tracked comptime alloc, return the
// comptime alloc pointer directly (no AIR ALLOC instruction).
// Ported from Sema.zig retPtrComptime.
@@ -10821,7 +10800,7 @@ static AirInstRef zirRetPtr(const Sema* sema, SemaBlock* block) {
TypeIndex ret_ty = sema->fn_ret_ty;
if (ret_ty == TYPE_NONE)
ret_ty = IP_INDEX_VOID_TYPE;
- TypeIndex ptr_ty = internPtrMutable(ret_ty);
+ TypeIndex ptr_ty = internPtrMutable(sema, ret_ty);
AirInstData d;
memset(&d, 0, sizeof(d));
d.ty.ty_ref = AIR_REF_FROM_IP(ptr_ty);
@@ -10926,7 +10905,7 @@ static AirInstRef zirRef(Sema* sema, uint32_t inst) {
return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
// Create *const T pointer type.
- InternPoolIndex ptr_ty = internPtrConst(val_ty);
+ InternPoolIndex ptr_ty = internPtrConst(sema, val_ty);
// Create ptr_uav entry (pointer to the comptime value).
InternPoolKey key;
@@ -10976,9 +10955,9 @@ static AirInstRef zirOptEuBasePtrInit(Sema* sema, uint32_t inst) {
// Save inner type for comptime union init detection.
sema->comptime_inner_type = inner_ty;
// Create *mut T pointer type → matches Zig $926.
- InternPoolIndex inner_ptr_ty = internPtrMutable(inner_ty);
+ InternPoolIndex inner_ptr_ty = internPtrMutable(sema, inner_ty);
// Create undef(T) → matches Zig $927.
- InternPoolIndex undef_inner = internUndef(inner_ty);
+ InternPoolIndex undef_inner = internUndef(sema, inner_ty);
// Create opt_payload(opt_ty, undef_inner) → matches Zig $928.
InternPoolKey opk;
memset(&opk, 0, sizeof(opk));
@@ -11917,21 +11896,23 @@ static bool analyzeBodyInner(
if (import_path) {
// Resolve via doImport (handles "builtin",
// "root", "std", and file paths).
- uint32_t fid = doImport(sema->source_dir, import_path);
+ uint32_t fid
+ = doImport(sema, sema->source_dir, import_path);
if (fid != UINT32_MAX) {
- resolved = s_file_root_type[fid];
+ resolved = sema->zcu->file_root_types[fid];
// Create ptr_nav for the import nav,
// matching Zig's analyzeNavRefInner.
// Created during both preamble and main analysis
// (the Zig compiler creates these whenever imports
// are accessed in comptime context).
if (sema->file_idx != UINT32_MAX) {
- uint32_t nav_idx2 = findNavInNamespace(
- s_file_namespace[sema->file_idx], decl_name);
+ uint32_t nav_idx2 = findNavInNamespace(sema,
+ sema->zcu->file_namespaces[sema->file_idx],
+ decl_name);
if (nav_idx2 != UINT32_MAX) {
InternPoolIndex pt
- = internPtrConst(IP_INDEX_TYPE_TYPE);
- (void)internNavPtr(pt, nav_idx2);
+ = internPtrConst(sema, IP_INDEX_TYPE_TYPE);
+ (void)internNavPtr(sema, pt, nav_idx2);
}
}
}
@@ -11942,23 +11923,24 @@ static bool analyzeBodyInner(
// ensureNavValUpToDate; during preamble, only
// return already-resolved values to avoid
// creating IP entries out of order.
- uint32_t ns_idx = s_file_namespace[sema->file_idx];
- uint32_t nav = findNavInNamespace(ns_idx, decl_name);
+ uint32_t ns_idx
+ = sema->zcu->file_namespaces[sema->file_idx];
+ uint32_t nav = findNavInNamespace(sema, ns_idx, decl_name);
if (nav != UINT32_MAX) {
- if (s_in_main_analysis) {
- InternPoolIndex val = ensureNavValUpToDate(nav);
+ if (sema->zcu->in_main_analysis) {
+ InternPoolIndex val
+ = ensureNavValUpToDate(sema, nav);
if (val != IP_INDEX_NONE) {
resolved = val;
// Create ptr_type + ptr_nav matching
// analyzeNavRefInner. Uses typeOf(val) as
// the child type (not always type_type).
- InternPoolIndex vt
- = ipTypeOf(s_module_ip, val);
- InternPoolIndex pt = internPtrConst(vt);
- (void)internNavPtr(pt, nav);
+ InternPoolIndex vt = ipTypeOf(sema->ip, val);
+ InternPoolIndex pt = internPtrConst(sema, vt);
+ (void)internNavPtr(sema, pt, nav);
}
} else {
- const Nav* n = ipGetNav(nav);
+ const Nav* n = ipGetNav(sema->ip, nav);
if (n->resolved_type != IP_INDEX_NONE)
resolved = n->resolved_type;
}
@@ -11973,20 +11955,23 @@ static bool analyzeBodyInner(
const char* import_path
= findDeclImportPath(sema, decl_name_idx);
if (import_path && sema->source_dir) {
- uint32_t fid = doImport(sema->source_dir, import_path);
+ uint32_t fid
+ = doImport(sema, sema->source_dir, import_path);
if (fid != UINT32_MAX)
- resolved = s_file_root_type[fid];
+ resolved = sema->zcu->file_root_types[fid];
} else if (!import_path) {
// Local declaration: look up in file namespace.
- uint32_t ns_idx = s_file_namespace[sema->file_idx];
- uint32_t nav = findNavInNamespace(ns_idx, decl_name);
+ uint32_t ns_idx
+ = sema->zcu->file_namespaces[sema->file_idx];
+ uint32_t nav = findNavInNamespace(sema, ns_idx, decl_name);
if (nav != UINT32_MAX) {
- if (s_in_main_analysis) {
- InternPoolIndex val = ensureNavValUpToDate(nav);
+ if (sema->zcu->in_main_analysis) {
+ InternPoolIndex val
+ = ensureNavValUpToDate(sema, nav);
if (val != IP_INDEX_NONE)
resolved = val;
} else {
- const Nav* n = ipGetNav(nav);
+ const Nav* n = ipGetNav(sema->ip, nav);
if (n->resolved_type != IP_INDEX_NONE)
resolved = n->resolved_type;
}
@@ -12008,9 +11993,9 @@ static bool analyzeBodyInner(
const char* import_path
= (const char*)&sema->code.string_bytes[path_idx];
InternPoolIndex result = IP_INDEX_VOID_VALUE;
- uint32_t fid = doImport(sema->source_dir, import_path);
+ uint32_t fid = doImport(sema, sema->source_dir, import_path);
if (fid != UINT32_MAX)
- result = s_file_root_type[fid];
+ result = sema->zcu->file_root_types[fid];
instMapPut(&sema->inst_map, inst, AIR_REF_FROM_IP(result));
i++;
continue;
@@ -12453,7 +12438,7 @@ static bool analyzeBodyInner(
// type_pointer + ptr_uav entries matching Zig's zirStr/addStrLit.
case ZIR_INST_STR: {
AirInstRef str_result = AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
- if (block->is_comptime && s_in_main_analysis) {
+ if (block->is_comptime && sema->zcu->in_main_analysis) {
uint32_t str_len = sema->code.inst_datas[inst].str.len;
// Extract the string from ZIR string_bytes.
char str_buf[256];
@@ -12463,7 +12448,7 @@ static bool analyzeBodyInner(
str_buf, &sema->code.string_bytes[str_start], str_len);
str_buf[str_len] = '\0';
InternPoolIndex uav
- = internStrLit(sema->ip, str_buf, str_len);
+ = internStrLit(sema, sema->ip, str_buf, str_len);
str_result = AIR_REF_FROM_IP(uav);
}
}
@@ -12609,7 +12594,7 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
(void)typeChildType(ip, IP_INDEX_VOID_TYPE);
(void)typeIsSlice(ip, IP_INDEX_VOID_TYPE);
(void)valueToType(valueFromInterned(IP_INDEX_VOID_VALUE));
- (void)ipNavCount();
+ (void)ipNavCount(sema->ip);
// Set up the func_air_list for collecting per-function AIR.
// Use static storage to satisfy cppcheck autoVariables
@@ -12626,11 +12611,7 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
// Initialize module tracking. Struct type IP entries are created
// lazily as imports are resolved during semantic analysis, matching
// the Zig compiler's demand-driven processing order.
- resetModuleTracking();
- s_module_ip = ip;
-
- // Set global module root for import resolution.
- s_global_module_root = sema->module_root;
+ resetModuleTracking(sema);
// Create root struct type + scan namespace for the root module
// (matches Zig's createFileRootStruct called from semaFile).
@@ -12639,7 +12620,7 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
// its imports, and only later loads the root module. We must match
// this order so that InternPool indices agree.
if (sema->code.inst_len > 0 && sema->source_dir) {
- if (sema->module_root) {
+ if (sema->zcu->comp->config.module_root) {
// Match the Zig compiler's module loading order.
// std.zig's comptime blocks force loading start.zig and
// debug.zig, then debug.assert entries are created, then
@@ -12662,8 +12643,8 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
// $137+ = std/builtin.zig chain
char std_path[1024];
snprintf(std_path, sizeof(std_path), "%s/lib/std/std.zig",
- sema->module_root);
- uint32_t std_file_idx = ensureFileAnalyzedC(std_path);
+ sema->zcu->comp->config.module_root);
+ uint32_t std_file_idx = ensureFileAnalyzedC(sema, std_path);
uint32_t start_file_idx = UINT32_MAX;
if (std_file_idx != UINT32_MAX) {
@@ -12673,27 +12654,31 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
// → loads debug.zig, creates assert entries
// Ported from upstream: comptime blocks are evaluated via
// analyzeComptimeUnit after scanning the namespace.
- uint32_t std_ns_idx = s_file_namespace[std_file_idx];
- const SemaNamespace* std_ns = &s_namespaces[std_ns_idx];
+ uint32_t std_ns_idx = sema->zcu->file_namespaces[std_file_idx];
+ const ZcuNamespace* std_ns
+ = &sema->zcu->namespaces[std_ns_idx];
for (uint32_t ci = 0; ci < std_ns->comptime_decl_count; ci++) {
analyzeComptimeUnit(
- std_file_idx, std_ns->comptime_decls[ci]);
+ sema, std_file_idx, std_ns->comptime_decls[ci]);
}
// Find start_file_idx for root module resolution below.
// Find start module by checking which file has the
// same root type as the start import. Try resolving
// the nav first; if it already has a resolved_type
// from the comptime eval, use it directly.
- uint32_t start_nav = findNavInNamespace(std_ns_idx, "start");
+ uint32_t start_nav
+ = findNavInNamespace(sema, std_ns_idx, "start");
if (start_nav != UINT32_MAX) {
// If comptime eval didn't set resolved_type,
// resolve it now.
- if (ipGetNav(start_nav)->resolved_type == IP_INDEX_NONE)
- (void)ensureNavValUpToDate(start_nav);
- const Nav* sn = ipGetNav(start_nav);
+ if (ipGetNav(sema->ip, start_nav)->resolved_type
+ == IP_INDEX_NONE)
+ (void)ensureNavValUpToDate(sema, start_nav);
+ const Nav* sn = ipGetNav(sema->ip, start_nav);
// Find which file the start nav resolved to.
- for (uint32_t fi = 0; fi < s_num_loaded_modules; fi++) {
- if (s_file_root_type[fi] == sn->resolved_type) {
+ for (uint32_t fi = 0; fi < sema->zcu->num_files; fi++) {
+ if (sema->zcu->file_root_types[fi]
+ == sn->resolved_type) {
start_file_idx = fi;
break;
}
@@ -12702,64 +12687,69 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
}
// Register the root module at the next available file_idx.
- uint32_t root_file_idx = s_num_loaded_modules++;
- LoadedModule* root_mod = &s_loaded_modules[root_file_idx];
+ uint32_t root_file_idx = sema->zcu->num_files++;
+ ZcuFile* root_mod = &sema->zcu->files[root_file_idx];
memset(root_mod, 0, sizeof(*root_mod));
snprintf(root_mod->source_dir, sizeof(root_mod->source_dir), "%s",
sema->source_dir);
root_mod->zir = sema->code;
root_mod->has_zir = true;
root_mod->analyzed = true;
- s_root_file_idx = root_file_idx;
+ sema->zcu->root_file_idx = root_file_idx;
sema->file_idx = root_file_idx;
- (void)createFileRootStructC(root_file_idx, &sema->code);
+ (void)createFileRootStructC(sema, root_file_idx, &sema->code);
// Evaluate start.zig's comptime blocks. Set
- // s_in_main_analysis so DECL_VAL resolves declarations
+ // sema->zcu->in_main_analysis so DECL_VAL resolves declarations
// lazily (matching upstream's full comptime evaluation).
if (start_file_idx != UINT32_MAX) {
- s_in_main_analysis = true;
- uint32_t start_ns = s_file_namespace[start_file_idx];
- const SemaNamespace* sns = &s_namespaces[start_ns];
+ sema->zcu->in_main_analysis = true;
+ uint32_t start_ns = sema->zcu->file_namespaces[start_file_idx];
+ const ZcuNamespace* sns = &sema->zcu->namespaces[start_ns];
for (uint32_t ci = 0; ci < sns->comptime_decl_count; ci++) {
analyzeComptimeUnit(
- start_file_idx, sns->comptime_decls[ci]);
+ sema, start_file_idx, sns->comptime_decls[ci]);
}
- s_in_main_analysis = false;
+ sema->zcu->in_main_analysis = false;
}
// Load the builtin module chain.
if (std_file_idx != UINT32_MAX) {
- s_std_file_idx = std_file_idx;
- uint32_t std_ns_idx2 = s_file_namespace[std_file_idx];
+ sema->zcu->std_file_idx = std_file_idx;
+ uint32_t std_ns_idx2
+ = sema->zcu->file_namespaces[std_file_idx];
// Resolve start.zig's "builtin" import.
if (start_file_idx != UINT32_MAX) {
- uint32_t start_ns2 = s_file_namespace[start_file_idx];
- uint32_t sbn = findNavInNamespace(start_ns2, "builtin");
+ uint32_t start_ns2
+ = sema->zcu->file_namespaces[start_file_idx];
+ uint32_t sbn
+ = findNavInNamespace(sema, start_ns2, "builtin");
if (sbn != UINT32_MAX)
- (void)ensureNavValUpToDate(sbn);
+ (void)ensureNavValUpToDate(sema, sbn);
}
// Resolve std.zig's "builtin" import → loads
// std/builtin.zig, creates ptr_nav.
uint32_t builtin_nav
- = findNavInNamespace(std_ns_idx2, "builtin");
+ = findNavInNamespace(sema, std_ns_idx2, "builtin");
if (builtin_nav != UINT32_MAX) {
- InternPoolIndex bval = ensureNavValUpToDate(builtin_nav);
+ InternPoolIndex bval
+ = ensureNavValUpToDate(sema, builtin_nav);
if (bval != IP_INDEX_NONE) {
- for (uint32_t fi = 0; fi < s_num_loaded_modules;
+ for (uint32_t fi = 0; fi < sema->zcu->num_files;
fi++) {
- if (s_file_root_type[fi] == bval) {
- s_builtin_file_idx = fi;
+ if (sema->zcu->file_root_types[fi] == bval) {
+ sema->zcu->builtin_file_idx = fi;
// Resolve std/builtin.zig's "builtin"
// import only (CG builtin module).
{
- uint32_t bns = s_file_namespace[fi];
- uint32_t bn
- = findNavInNamespace(bns, "builtin");
+ uint32_t bns
+ = sema->zcu->file_namespaces[fi];
+ uint32_t bn = findNavInNamespace(
+ sema, bns, "builtin");
if (bn != UINT32_MAX)
- (void)ensureNavValUpToDate(bn);
+ (void)ensureNavValUpToDate(sema, bn);
}
break;
}
@@ -12768,37 +12758,38 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
}
}
- analyzeMemoizedStateC();
+ analyzeMemoizedStateC(sema);
// Re-evaluate start.zig comptime after analyzeMemoizedStateC
// so that entries dedup with memoized state (matching upstream).
if (start_file_idx != UINT32_MAX) {
- s_in_main_analysis = true;
- uint32_t start_ns3 = s_file_namespace[start_file_idx];
- const SemaNamespace* sns3 = &s_namespaces[start_ns3];
+ sema->zcu->in_main_analysis = true;
+ uint32_t start_ns3
+ = sema->zcu->file_namespaces[start_file_idx];
+ const ZcuNamespace* sns3 = &sema->zcu->namespaces[start_ns3];
for (uint32_t ci = 0; ci < sns3->comptime_decl_count; ci++) {
analyzeComptimeUnit(
- start_file_idx, sns3->comptime_decls[ci]);
+ sema, start_file_idx, sns3->comptime_decls[ci]);
}
- s_in_main_analysis = false;
+ sema->zcu->in_main_analysis = false;
}
} else {
// No module root — root module is file_idx=0.
- if (s_num_loaded_modules == 0) {
- s_num_loaded_modules = 1;
- memset(&s_loaded_modules[0], 0, sizeof(s_loaded_modules[0]));
+ if (sema->zcu->num_files == 0) {
+ sema->zcu->num_files = 1;
+ memset(&sema->zcu->files[0], 0, sizeof(sema->zcu->files[0]));
}
- snprintf(s_loaded_modules[0].source_dir,
- sizeof(s_loaded_modules[0].source_dir), "%s",
+ snprintf(sema->zcu->files[0].source_dir,
+ sizeof(sema->zcu->files[0].source_dir), "%s",
sema->source_dir);
- s_loaded_modules[0].zir = sema->code;
- s_loaded_modules[0].has_zir = true;
- s_loaded_modules[0].analyzed = true;
- s_root_file_idx = 0;
+ sema->zcu->files[0].zir = sema->code;
+ sema->zcu->files[0].has_zir = true;
+ sema->zcu->files[0].analyzed = true;
+ sema->zcu->root_file_idx = 0;
sema->file_idx = 0;
- (void)createFileRootStructC(0, &sema->code);
- resolveModuleDeclImports(0, 2);
+ (void)createFileRootStructC(sema, 0, &sema->code);
+ resolveModuleDeclImports(sema, 0, 2);
}
}
@@ -12810,9 +12801,9 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
sema->code.inst_datas[0].extended.opcode == ZIR_EXT_STRUCT_DECL);
uint32_t single_inst = 0;
- s_in_main_analysis = true;
+ sema->zcu->in_main_analysis = true;
(void)analyzeBodyInner(sema, &root_block, &single_inst, 1);
- s_in_main_analysis = false;
+ sema->zcu->in_main_analysis = false;
}
semaBlockDeinit(&root_block);
@@ -12820,9 +12811,9 @@ SemaFuncAirList semaAnalyze(Sema* sema) {
// Clean up module tracking. The root module's ZIR is owned by
// the caller (sema->code), so clear has_zir to prevent double-free.
- if (s_num_loaded_modules > 0)
- s_loaded_modules[s_root_file_idx].has_zir = false;
- resetModuleTracking();
+ if (sema->zcu->num_files > 0)
+ sema->zcu->files[sema->zcu->root_file_idx].has_zir = false;
+ resetModuleTracking(sema);
// Free the module-level Air arrays from sema (they're empty for
// comptime-only modules but allocated).
diff --git a/stage0/sema.h b/stage0/sema.h
@@ -10,6 +10,11 @@
#include <stdbool.h>
#include <stdint.h>
+// Forward declaration — full definition in zcu.h, included by sema.c.
+struct Zcu;
+
+#define MAX_EXPORTED_DECL_NAMES 16
+
// --- InstMap ---
// Maps ZIR instruction index -> AIR instruction ref.
// Uses a flat array indexed by ZIR instruction index minus a start offset.
@@ -109,24 +114,6 @@ typedef struct {
uint32_t runtime_index;
} ComptimeAlloc;
-// --- SemaNamespace ---
-// Groups declarations by owning type (file root struct, etc.).
-// Ported from Zcu.Namespace.
-
-#define SEMA_NS_MAX_NAVS 1024
-#define SEMA_NS_MAX_COMPTIME 64
-
-typedef struct {
- InternPoolIndex owner_type; // type_struct IP index
- uint32_t file_idx; // index into loaded modules
- uint32_t pub_navs[SEMA_NS_MAX_NAVS];
- uint32_t pub_nav_count;
- uint32_t priv_navs[SEMA_NS_MAX_NAVS];
- uint32_t priv_nav_count;
- uint32_t comptime_decls[SEMA_NS_MAX_COMPTIME]; // ZIR inst indices
- uint32_t comptime_decl_count;
-} SemaNamespace;
-
// --- SemaFuncAir ---
// Per-function Air result, produced during sema analysis.
@@ -164,7 +151,8 @@ typedef struct {
// generation.
typedef struct Sema {
- InternPool* ip;
+ InternPool* ip; // points to zcu->ip for convenient access
+ struct Zcu* zcu; // owning Zcu (set by semaInit)
Zir code;
uint8_t* air_inst_tags; // AirInstTag stored as uint8_t (matches Zig u8)
AirInstData* air_inst_datas;
@@ -194,6 +182,7 @@ typedef struct Sema {
// Populated by analyzeBodyInner when processing comptime blocks
// that contain @export. Used by zirFunc to decide whether to analyze
// non-declaration-level-exported functions.
+ uint32_t exported_decl_names[MAX_EXPORTED_DECL_NAMES];
uint32_t num_exported_decl_names;
// Declaration table: maps string_bytes index (name) to the ZIR
// declaration instruction index. Built by zirStructDecl.
@@ -204,10 +193,6 @@ typedef struct Sema {
// Source directory for resolving relative imports.
// Set by the caller before semaAnalyze. NULL = no import resolution.
const char* source_dir;
- // Module root directory for resolving non-relative imports
- // (e.g. @import("std") → <module_root>/lib/std/std.zig).
- // Set by the caller before semaAnalyze. NULL = no std resolution.
- const char* module_root;
// Root FQN prefix for function name construction.
// Function names are "{root_fqn}.funcName" (e.g. "empty_void_function.f").
// Must match the Zig compiler's module naming (filename stem).
@@ -287,7 +272,7 @@ typedef struct Sema {
// --- Function declarations ---
-void semaInit(Sema* sema, InternPool* ip, Zir code);
+void semaInit(Sema* sema, struct Zcu* zcu, Zir code);
void semaDeinit(Sema* sema);
SemaFuncAirList semaAnalyze(Sema* sema);
void semaFuncAirListDeinit(SemaFuncAirList* list);
diff --git a/stage0/sema_test.zig b/stage0/sema_test.zig
@@ -5,6 +5,7 @@ const std = @import("std");
pub const c = @cImport({
@cInclude("astgen.h");
@cInclude("sema.h");
+ @cInclude("zcu.h");
});
// Helper to convert C #define integer constants (c_int) to u32 for comparison
@@ -167,14 +168,14 @@ test "intern_pool: pointer types" {
// ---------------------------------------------------------------------------
const SemaCheckResult = struct {
- c_ip: c.InternPool,
+ c_zcu: *c.Zcu,
c_sema: c.Sema,
c_func_air_list: c.SemaFuncAirList,
fn deinit(self: *SemaCheckResult) void {
c.semaFuncAirListDeinit(&self.c_func_air_list);
c.semaDeinit(&self.c_sema);
- c.ipDeinit(&self.c_ip);
+ c.zcuDeinit(self.c_zcu);
}
};
@@ -184,8 +185,16 @@ fn semaCheck(source: [:0]const u8) !SemaCheckResult {
var c_zir = c.astGen(&c_ast);
defer c.zirDeinit(&c_zir);
var result: SemaCheckResult = undefined;
- result.c_ip = c.ipInit();
- c.semaInit(&result.c_sema, &result.c_ip, c_zir);
+ var comp: c.Compilation = .{ .config = .{
+ .module_root = null,
+ .target_cpu_arch = "wasm32",
+ .target_cpu_model = "lime1",
+ .object_format = "wasm",
+ .link_mode = "static",
+ .is_test = false,
+ } };
+ result.c_zcu = c.zcuInit(&comp);
+ c.semaInit(&result.c_sema, result.c_zcu, c_zir);
result.c_func_air_list = c.semaAnalyze(&result.c_sema);
return result;
}
diff --git a/stage0/stages_test.zig b/stage0/stages_test.zig
@@ -68,29 +68,34 @@ fn stagesCheck(gpa: Allocator, comptime path: []const u8, source: [:0]const u8)
var module_root_buf: [std.fs.max_path_bytes:0]u8 = undefined;
const module_root_path = std.fmt.bufPrintZ(&module_root_buf, "{s}", .{abs_repo_root}) catch unreachable;
- var c_ip = sc.ipInit();
- defer sc.ipDeinit(&c_ip);
+ var comp: sc.Compilation = .{ .config = .{
+ .module_root = module_root_path.ptr,
+ .target_cpu_arch = "wasm32",
+ .target_cpu_model = "lime1",
+ .object_format = "wasm",
+ .link_mode = "static",
+ .is_test = false,
+ } };
+ const c_zcu = sc.zcuInit(&comp);
+ defer sc.zcuDeinit(c_zcu);
var c_sema: sc.Sema = undefined;
- sc.semaInit(&c_sema, &c_ip, @bitCast(c_zir));
+ sc.semaInit(&c_sema, c_zcu, @bitCast(c_zir));
defer sc.semaDeinit(&c_sema);
// Pre-generated AIR uses ReleaseSmall (strip=true), so match it.
c_sema.strip = true;
- // Set source_dir, module_root, root_fqn based on path prefix.
+ // Set source_dir, root_fqn based on path prefix.
if (comptime std.mem.startsWith(u8, path, "stage0/")) {
// Sema unit tests: set module_root to enable std/start/builtin
// loading, matching the Zig compiler which always creates std
// even with std_mod=null (Compilation.zig line 2196).
c_sema.source_dir = source_dir_path.ptr;
- c_sema.module_root = module_root_path.ptr;
c_sema.root_fqn = comptime sema_test.pathStem(path);
} else if (comptime std.mem.startsWith(u8, path, "lib/std/")) {
c_sema.source_dir = source_dir_path.ptr;
- c_sema.module_root = module_root_path.ptr;
c_sema.root_fqn = "std";
c_sema.module_prefix = sema_test.pathToModulePrefix(path);
} else {
c_sema.source_dir = source_dir_path.ptr;
- c_sema.module_root = module_root_path.ptr;
c_sema.root_fqn = comptime sema_test.pathStem(path);
}
var c_func_air_list = sc.semaAnalyze(&c_sema);
diff --git a/stage0/zcu.c b/stage0/zcu.c
@@ -0,0 +1,30 @@
+#include "zcu.h"
+#include <stdlib.h>
+
+Zcu* zcuInit(Compilation* comp) {
+ Zcu* zcu = (Zcu*)calloc(1, sizeof(Zcu));
+ if (!zcu)
+ exit(1);
+ zcu->ip = ipInit();
+ zcu->comp = comp;
+ // Initialize sentinel values.
+ zcu->std_file_idx = UINT32_MAX;
+ zcu->builtin_file_idx = UINT32_MAX;
+ zcu->cg_builtin_ns_idx = UINT32_MAX;
+ zcu->cg_builtin_nav = UINT32_MAX;
+ return zcu;
+}
+
+void zcuDeinit(Zcu* zcu) {
+ // Free loaded file ASTs and ZIRs.
+ for (uint32_t i = 0; i < zcu->num_files; i++) {
+ ZcuFile* f = &zcu->files[i];
+ if (f->has_zir) {
+ zirDeinit(&f->zir);
+ astDeinit(&f->ast);
+ }
+ }
+ ipDeinit(&zcu->ip);
+ // zcuAlloc uses calloc; free the struct itself.
+ free(zcu);
+}
diff --git a/stage0/zcu.h b/stage0/zcu.h
@@ -0,0 +1,109 @@
+// zcu.h — ported from src/Zcu.zig + src/Zcu/PerThread.zig.
+// Holds all module-level state for a compilation unit.
+#ifndef _ZIG0_ZCU_H__
+#define _ZIG0_ZCU_H__
+
+#include "ast.h"
+#include "compilation.h"
+#include "intern_pool.h"
+#include "zir.h"
+#include <stdbool.h>
+#include <stdint.h>
+
+// --- ZcuFile (matches Zcu.File) ---
+// Per-source-file state.
+
+#define ZCU_MAX_FILES 512
+
+typedef struct {
+ char path[1024]; // canonical file path
+ char source_dir[1024]; // directory containing this file
+ Zir zir; // parsed ZIR (inst_len>0 if loaded)
+ Ast ast; // AST (kept alive to own source memory)
+ bool has_zir; // true if zir/ast are populated
+ bool analyzed; // true if createFileRootStructC has been called
+} ZcuFile;
+
+// --- ZcuNamespace (matches Zcu.Namespace) ---
+
+#define ZCU_NS_MAX_NAVS 1024
+#define ZCU_NS_MAX_COMPTIME 64
+#define ZCU_MAX_NAMESPACES 512
+
+typedef struct {
+ InternPoolIndex owner_type; // type_struct IP index
+ uint32_t file_idx; // index into files[]
+ uint32_t pub_navs[ZCU_NS_MAX_NAVS];
+ uint32_t pub_nav_count;
+ uint32_t priv_navs[ZCU_NS_MAX_NAVS];
+ uint32_t priv_nav_count;
+ uint32_t comptime_decls[ZCU_NS_MAX_COMPTIME]; // ZIR inst indices
+ uint32_t comptime_decl_count;
+} ZcuNamespace;
+
+// --- Zcu struct (matches Zcu.zig) ---
+// Heap-allocated (use zcuInit/zcuDeinit); too large for stack.
+
+#define NUM_BUILTIN_DECL_MAIN 36
+
+typedef struct Zcu {
+ InternPool ip; // owns IP; matches Zcu.intern_pool
+
+ // --- File management (matches Zcu.import_table / Zcu.File) ---
+ ZcuFile files[ZCU_MAX_FILES]; // matches Zcu.files
+ uint32_t num_files;
+ uint32_t root_file_idx;
+ uint32_t std_file_idx;
+ uint32_t builtin_file_idx;
+
+ // --- Builtin namespace/nav ---
+ uint32_t cg_builtin_ns_idx; // compiler-generated builtin namespace
+ uint32_t cg_builtin_nav;
+
+ // --- Struct type hashing (C-specific) ---
+ uint32_t next_struct_hash; // unique hash counter for struct types
+
+ // --- Analysis state ---
+ bool in_main_analysis;
+ uint32_t enum_force_intern_threshold;
+
+ // --- Namespaces (matches Zcu.Namespace storage) ---
+ ZcuNamespace namespaces[ZCU_MAX_NAMESPACES];
+ uint32_t num_namespaces;
+ InternPoolIndex file_root_types[ZCU_MAX_FILES];
+ uint32_t file_namespaces[ZCU_MAX_FILES];
+
+ // --- Type/layout resolution tracking ---
+ bool struct_layout_resolved[4096];
+ bool struct_fully_resolved[4096];
+ bool union_fully_resolved[4096];
+ InternPoolIndex union_tag_enums[256];
+ InternPoolIndex union_tag_types[256];
+ uint32_t num_union_tag_enums;
+
+ // --- Memoized builtin state (matches Zcu.builtin_decl_values) ---
+ bool memoized_main_resolved;
+ bool full_memoized_resolved;
+ InternPoolIndex builtin_decl_values[NUM_BUILTIN_DECL_MAIN];
+
+ // --- Preamble IP range tracking (C-specific shard simulation) ---
+ uint32_t preamble_memoized_start;
+ uint32_t preamble_memoized_end;
+ uint32_t preamble_cc_start;
+ uint32_t preamble_cc_end;
+ uint32_t preamble_builtin_navs[5];
+ uint32_t preamble_builtin_nav_count;
+
+ // --- Compilation config ---
+ Compilation* comp; // back-pointer; matches Zcu.comp in Zig
+} Zcu;
+
+// --- Function declarations ---
+
+// Allocate and initialize a Zcu on the heap (too large for stack).
+Zcu* zcuInit(Compilation* comp);
+
+// Free all resources including the struct itself (matches zcuInit).
+void zcuDeinit(Zcu* zcu);
+
+#endif
diff --git a/stage0/zcu_per_thread.h b/stage0/zcu_per_thread.h
@@ -0,0 +1,67 @@
+// zcu_per_thread.h — ported from src/Zcu/PerThread.zig.
+// Functions for per-thread analysis orchestration.
+#ifndef _ZIG0_ZCU_PER_THREAD_H__
+#define _ZIG0_ZCU_PER_THREAD_H__
+
+#include "zcu.h"
+#include "zir.h"
+#include <stdbool.h>
+#include <stdint.h>
+
+// Forward declaration: avoid including sema.h here.
+struct Sema;
+
+// These match PerThread.zig functions (taking Sema* for Zcu access):
+
+// Load, parse, and analyze an imported file. Returns the file index,
+// or UINT32_MAX on failure. (matches PerThread.ensureFileAnalyzed)
+uint32_t ensureFileAnalyzedC(struct Sema* sema, const char* full_path);
+
+// Create the root struct type for a file. (matches
+// PerThread.createFileRootStruct)
+InternPoolIndex createFileRootStructC(
+ struct Sema* sema, uint32_t file_idx, const Zir* zir);
+
+// Scan a namespace, building its Nav list. (matches PerThread.scanNamespace)
+void scanNamespaceC(struct Sema* sema, uint32_t ns_idx,
+ const uint32_t* decl_insts, uint32_t decls_len, const Zir* zir);
+
+// Analyze a nav declaration's value. (matches PerThread.analyzeNavVal)
+InternPoolIndex analyzeNavValC(struct Sema* sema, uint32_t nav_idx);
+
+// Resolve memoized state for .main builtins. (matches
+// PerThread.analyzeMemoizedState)
+void analyzeMemoizedStateC(struct Sema* sema);
+
+// Ensure a Nav's value is up to date.
+InternPoolIndex ensureNavValUpToDate(struct Sema* sema, uint32_t nav_idx);
+
+// Resolve all 36 .main-stage builtins. (matches
+// PerThread.ensureFullMemoizedState)
+void ensureFullMemoizedStateC(struct Sema* sema);
+
+// Handle @import. (matches PerThread.importFile / doImport)
+uint32_t doImport(
+ struct Sema* sema, const char* source_dir, const char* import_string);
+
+// Resolve struct layout (field offsets).
+bool resolveStructLayoutC(struct Sema* sema, uint32_t nav_idx);
+
+// Resolve struct fully (field types).
+void resolveStructFullyC(struct Sema* sema, uint32_t nav_idx);
+
+// Resolve union fully (field types + tag enum).
+void resolveUnionFullyC(struct Sema* sema, uint32_t nav_idx);
+
+// Find namespace index for a type IP index.
+uint32_t findNamespaceForType(struct Sema* sema, InternPoolIndex type_ip);
+
+// Find a nav in a namespace by name. Returns UINT32_MAX if not found.
+uint32_t findNavInNamespace(
+ struct Sema* sema, uint32_t ns_idx, const char* name);
+
+// Analyze a comptime block at file scope.
+void analyzeComptimeUnit(
+ struct Sema* sema, uint32_t file_idx, uint32_t comptime_decl);
+
+#endif
diff --git a/stage0/zig0.c b/stage0/zig0.c
@@ -1,9 +1,11 @@
#include "ast.h"
#include "astgen.h"
+#include "compilation.h"
#include "intern_pool.h"
#include "sema.h"
#include "verbose_air.h"
#include "verbose_intern_pool.h"
+#include "zcu.h"
#include "zir.h"
#include <stdbool.h>
@@ -44,19 +46,25 @@ static int zig0Run(const char* program, const char* source_dir,
fprintf(stderr, "zir: %u instructions, %u extra, %u string bytes\n",
zir.inst_len, zir.extra_len, zir.string_bytes_len);
- InternPool ip = ipInit();
+ Compilation comp;
+ comp.config.module_root = module_root;
+ comp.config.target_cpu_arch = "wasm32";
+ comp.config.target_cpu_model = "lime1";
+ comp.config.object_format = "wasm";
+ comp.config.link_mode = "static";
+ comp.config.is_test = false;
+ Zcu* zcu = zcuInit(&comp);
Sema sema;
- semaInit(&sema, &ip, zir);
+ semaInit(&sema, zcu, zir);
sema.source_dir = source_dir;
- sema.module_root = module_root;
SemaFuncAirList func_airs = semaAnalyze(&sema);
if (verbose_intern_pool)
- verboseIpPrint(stderr, &ip);
+ verboseIpPrint(stderr, &zcu->ip);
if (verbose_air)
- verboseAirPrint(stderr, &func_airs, &ip);
+ verboseAirPrint(stderr, &func_airs, &zcu->ip);
semaDeinit(&sema);
semaFuncAirListDeinit(&func_airs);
- ipDeinit(&ip);
+ zcuDeinit(zcu);
zirDeinit(&zir);
return 0;
}