diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 2977801cb5..6d43361ae4 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -250,14 +250,7 @@ pub const HashHelper = struct { pub fn final(hh: *HashHelper) HexDigest { var bin_digest: BinDigest = undefined; hh.hasher.final(&bin_digest); - - var out_digest: HexDigest = undefined; - _ = fmt.bufPrint( - &out_digest, - "{s}", - .{fmt.fmtSliceHexLower(&bin_digest)}, - ) catch unreachable; - return out_digest; + return binToHex(bin_digest); } pub fn oneShot(bytes: []const u8) [hex_digest_len]u8 { @@ -265,16 +258,20 @@ pub const HashHelper = struct { hasher.update(bytes); var bin_digest: BinDigest = undefined; hasher.final(&bin_digest); - var out_digest: [hex_digest_len]u8 = undefined; - _ = fmt.bufPrint( - &out_digest, - "{s}", - .{fmt.fmtSliceHexLower(&bin_digest)}, - ) catch unreachable; - return out_digest; + return binToHex(bin_digest); } }; +pub fn binToHex(bin_digest: BinDigest) HexDigest { + var out_digest: HexDigest = undefined; + _ = fmt.bufPrint( + &out_digest, + "{s}", + .{fmt.fmtSliceHexLower(&bin_digest)}, + ) catch unreachable; + return out_digest; +} + pub const Lock = struct { manifest_file: fs.File, @@ -426,11 +423,7 @@ pub const Manifest = struct { var bin_digest: BinDigest = undefined; self.hash.hasher.final(&bin_digest); - _ = fmt.bufPrint( - &self.hex_digest, - "{s}", - .{fmt.fmtSliceHexLower(&bin_digest)}, - ) catch unreachable; + self.hex_digest = binToHex(bin_digest); self.hash.hasher = hasher_init; self.hash.hasher.update(&bin_digest); @@ -899,14 +892,7 @@ pub const Manifest = struct { var bin_digest: BinDigest = undefined; self.hash.hasher.final(&bin_digest); - var out_digest: HexDigest = undefined; - _ = fmt.bufPrint( - &out_digest, - "{s}", - .{fmt.fmtSliceHexLower(&bin_digest)}, - ) catch unreachable; - - return out_digest; + return binToHex(bin_digest); } /// If `want_shared_lock` is true, this function automatically downgrades the diff --git a/lib/std/debug.zig b/lib/std/debug.zig index f7dc462421..fb6609b8b1 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -398,20 +398,30 @@ pub fn dumpStackTrace(stack_trace: std.builtin.StackTrace) void { } } -/// This function invokes undefined behavior when `ok` is `false`. +/// Invokes detectable illegal behavior when `ok` is `false`. +/// /// In Debug and ReleaseSafe modes, calls to this function are always /// generated, and the `unreachable` statement triggers a panic. -/// In ReleaseFast and ReleaseSmall modes, calls to this function are -/// optimized away, and in fact the optimizer is able to use the assertion -/// in its heuristics. -/// Inside a test block, it is best to use the `std.testing` module rather -/// than this function, because this function may not detect a test failure -/// in ReleaseFast and ReleaseSmall mode. Outside of a test block, this assert +/// +/// In ReleaseFast and ReleaseSmall modes, calls to this function are optimized +/// away, and in fact the optimizer is able to use the assertion in its +/// heuristics. +/// +/// Inside a test block, it is best to use the `std.testing` module rather than +/// this function, because this function may not detect a test failure in +/// ReleaseFast and ReleaseSmall mode. Outside of a test block, this assert /// function is the correct function to use. pub fn assert(ok: bool) void { if (!ok) unreachable; // assertion failure } +/// Invokes detectable illegal behavior when the provided slice is not mapped +/// or lacks read permissions. +pub fn assertReadable(slice: []const volatile u8) void { + if (!runtime_safety) return; + for (slice) |*byte| _ = byte.*; +} + pub fn panic(comptime format: []const u8, args: anytype) noreturn { @setCold(true); diff --git a/src/Compilation.zig b/src/Compilation.zig index 9d3a31e792..eda5f63a58 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -116,7 +116,7 @@ win32_resource_work_queue: if (build_options.only_core_functionality) void else /// These jobs are to tokenize, parse, and astgen files, which may be outdated /// since the last compilation, as well as scan for `@import` and queue up /// additional jobs corresponding to those new files. -astgen_work_queue: std.fifo.LinearFifo(*Module.File, .Dynamic), +astgen_work_queue: std.fifo.LinearFifo(Zcu.File.Index, .Dynamic), /// These jobs are to inspect the file system stat() and if the embedded file has changed /// on disk, mark the corresponding Decl outdated and queue up an `analyze_decl` /// task for it. @@ -1433,7 +1433,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil .work_queue = std.fifo.LinearFifo(Job, .Dynamic).init(gpa), .c_object_work_queue = std.fifo.LinearFifo(*CObject, .Dynamic).init(gpa), .win32_resource_work_queue = if (build_options.only_core_functionality) {} else std.fifo.LinearFifo(*Win32Resource, .Dynamic).init(gpa), - .astgen_work_queue = std.fifo.LinearFifo(*Module.File, .Dynamic).init(gpa), + .astgen_work_queue = std.fifo.LinearFifo(Zcu.File.Index, .Dynamic).init(gpa), .embed_file_work_queue = std.fifo.LinearFifo(*Module.EmbedFile, .Dynamic).init(gpa), .c_source_files = options.c_source_files, .rc_source_files = options.rc_source_files, @@ -2095,13 +2095,13 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { } } - if (comp.module) |module| { - module.compile_log_text.shrinkAndFree(gpa, 0); + if (comp.module) |zcu| { + zcu.compile_log_text.shrinkAndFree(gpa, 0); // Make sure std.zig is inside the import_table. We unconditionally need // it for start.zig. - const std_mod = module.std_mod; - _ = try module.importPkg(std_mod); + const std_mod = zcu.std_mod; + _ = try zcu.importPkg(std_mod); // Normally we rely on importing std to in turn import the root source file // in the start code, but when using the stage1 backend that won't happen, @@ -2110,64 +2110,65 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { // Likewise, in the case of `zig test`, the test runner is the root source file, // and so there is nothing to import the main file. if (comp.config.is_test) { - _ = try module.importPkg(module.main_mod); + _ = try zcu.importPkg(zcu.main_mod); } - if (module.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { - _ = try module.importPkg(compiler_rt_mod); + if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { + _ = try zcu.importPkg(compiler_rt_mod); } // Put a work item in for every known source file to detect if // it changed, and, if so, re-compute ZIR and then queue the job // to update it. - try comp.astgen_work_queue.ensureUnusedCapacity(module.import_table.count()); - for (module.import_table.values()) |file| { + try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count()); + for (zcu.import_table.values(), 0..) |file, file_index_usize| { + const file_index: Zcu.File.Index = @enumFromInt(file_index_usize); if (file.mod.isBuiltin()) continue; - comp.astgen_work_queue.writeItemAssumeCapacity(file); + comp.astgen_work_queue.writeItemAssumeCapacity(file_index); } // Put a work item in for checking if any files used with `@embedFile` changed. - try comp.embed_file_work_queue.ensureUnusedCapacity(module.embed_table.count()); - for (module.embed_table.values()) |embed_file| { + try comp.embed_file_work_queue.ensureUnusedCapacity(zcu.embed_table.count()); + for (zcu.embed_table.values()) |embed_file| { comp.embed_file_work_queue.writeItemAssumeCapacity(embed_file); } try comp.work_queue.writeItem(.{ .analyze_mod = std_mod }); if (comp.config.is_test) { - try comp.work_queue.writeItem(.{ .analyze_mod = module.main_mod }); + try comp.work_queue.writeItem(.{ .analyze_mod = zcu.main_mod }); } - if (module.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { + if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| { try comp.work_queue.writeItem(.{ .analyze_mod = compiler_rt_mod }); } } try comp.performAllTheWork(main_progress_node); - if (comp.module) |module| { + if (comp.module) |zcu| { if (build_options.enable_debug_extensions and comp.verbose_intern_pool) { std.debug.print("intern pool stats for '{s}':\n", .{ comp.root_name, }); - module.intern_pool.dump(); + zcu.intern_pool.dump(); } if (build_options.enable_debug_extensions and comp.verbose_generic_instances) { std.debug.print("generic instances for '{s}:0x{x}':\n", .{ comp.root_name, - @as(usize, @intFromPtr(module)), + @as(usize, @intFromPtr(zcu)), }); - module.intern_pool.dumpGenericInstances(gpa); + zcu.intern_pool.dumpGenericInstances(gpa); } if (comp.config.is_test and comp.totalErrorCount() == 0) { // The `test_functions` decl has been intentionally postponed until now, // at which point we must populate it with the list of test functions that // have been discovered and not filtered out. - try module.populateTestFunctions(main_progress_node); + try zcu.populateTestFunctions(main_progress_node); } - try module.processExports(); + try zcu.processExports(); } if (comp.totalErrorCount() != 0) { @@ -2615,7 +2616,9 @@ fn resolveEmitLoc( return slice.ptr; } -fn reportMultiModuleErrors(mod: *Module) !void { +fn reportMultiModuleErrors(zcu: *Zcu) !void { + const gpa = zcu.gpa; + const ip = &zcu.intern_pool; // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to // print all of, so we'll cap the number of these to emit. var num_errors: u32 = 0; @@ -2623,37 +2626,39 @@ fn reportMultiModuleErrors(mod: *Module) !void { // Attach the "some omitted" note to the final error message var last_err: ?*Module.ErrorMsg = null; - for (mod.import_table.values()) |file| { + for (zcu.import_table.values(), 0..) |file, file_index_usize| { if (!file.multi_pkg) continue; num_errors += 1; if (num_errors > max_errors) continue; + const file_index: Zcu.File.Index = @enumFromInt(file_index_usize); + const err = err_blk: { // Like with errors, let's cap the number of notes to prevent a huge error spew. const max_notes = 5; const omitted = file.references.items.len -| max_notes; const num_notes = file.references.items.len - omitted; - const notes = try mod.gpa.alloc(Module.ErrorMsg, if (omitted > 0) num_notes + 1 else num_notes); - errdefer mod.gpa.free(notes); + const notes = try gpa.alloc(Module.ErrorMsg, if (omitted > 0) num_notes + 1 else num_notes); + errdefer gpa.free(notes); for (notes[0..num_notes], file.references.items[0..num_notes], 0..) |*note, ref, i| { - errdefer for (notes[0..i]) |*n| n.deinit(mod.gpa); + errdefer for (notes[0..i]) |*n| n.deinit(gpa); note.* = switch (ref) { .import => |import| try Module.ErrorMsg.init( - mod.gpa, + gpa, .{ - .base_node_inst = try mod.intern_pool.trackZir(mod.gpa, import.file, .main_struct_inst), + .base_node_inst = try ip.trackZir(gpa, import.file, .main_struct_inst), .offset = .{ .token_abs = import.token }, }, "imported from module {s}", - .{import.file.mod.fully_qualified_name}, + .{zcu.fileByIndex(import.file).mod.fully_qualified_name}, ), .root => |pkg| try Module.ErrorMsg.init( - mod.gpa, + gpa, .{ - .base_node_inst = try mod.intern_pool.trackZir(mod.gpa, file, .main_struct_inst), + .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst), .offset = .entire_file, }, "root of module {s}", @@ -2661,25 +2666,25 @@ fn reportMultiModuleErrors(mod: *Module) !void { ), }; } - errdefer for (notes[0..num_notes]) |*n| n.deinit(mod.gpa); + errdefer for (notes[0..num_notes]) |*n| n.deinit(gpa); if (omitted > 0) { notes[num_notes] = try Module.ErrorMsg.init( - mod.gpa, + gpa, .{ - .base_node_inst = try mod.intern_pool.trackZir(mod.gpa, file, .main_struct_inst), + .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst), .offset = .entire_file, }, "{} more references omitted", .{omitted}, ); } - errdefer if (omitted > 0) notes[num_notes].deinit(mod.gpa); + errdefer if (omitted > 0) notes[num_notes].deinit(gpa); const err = try Module.ErrorMsg.create( - mod.gpa, + gpa, .{ - .base_node_inst = try mod.intern_pool.trackZir(mod.gpa, file, .main_struct_inst), + .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst), .offset = .entire_file, }, "file exists in multiple modules", @@ -2688,8 +2693,8 @@ fn reportMultiModuleErrors(mod: *Module) !void { err.notes = notes; break :err_blk err; }; - errdefer err.destroy(mod.gpa); - try mod.failed_files.putNoClobber(mod.gpa, file, err); + errdefer err.destroy(gpa); + try zcu.failed_files.putNoClobber(gpa, file, err); last_err = err; } @@ -2700,15 +2705,15 @@ fn reportMultiModuleErrors(mod: *Module) !void { // There isn't really any meaningful place to put this note, so just attach it to the // last failed file var note = try Module.ErrorMsg.init( - mod.gpa, + gpa, err.src_loc, "{} more errors omitted", .{num_errors - max_errors}, ); - errdefer note.deinit(mod.gpa); + errdefer note.deinit(gpa); const i = err.notes.len; - err.notes = try mod.gpa.realloc(err.notes, i + 1); + err.notes = try gpa.realloc(err.notes, i + 1); err.notes[i] = note; } @@ -2719,8 +2724,8 @@ fn reportMultiModuleErrors(mod: *Module) !void { // to add this flag after reporting the errors however, as otherwise // we'd get an error for every single downstream file, which wouldn't be // very useful. - for (mod.import_table.values()) |file| { - if (file.multi_pkg) file.recursiveMarkMultiPkg(mod); + for (zcu.import_table.values()) |file| { + if (file.multi_pkg) file.recursiveMarkMultiPkg(zcu); } } @@ -2752,6 +2757,7 @@ const Header = extern struct { first_dependency_len: u32, dep_entries_len: u32, free_dep_entries_len: u32, + files_len: u32, }, }; @@ -2759,7 +2765,7 @@ const Header = extern struct { /// saved, such as the target and most CLI flags. A cache hit will only occur /// when subsequent compiler invocations use the same set of flags. pub fn saveState(comp: *Compilation) !void { - var bufs_list: [19]std.posix.iovec_const = undefined; + var bufs_list: [21]std.posix.iovec_const = undefined; var bufs_len: usize = 0; const lf = comp.bin_file orelse return; @@ -2780,6 +2786,7 @@ pub fn saveState(comp: *Compilation) !void { .first_dependency_len = @intCast(ip.first_dependency.count()), .dep_entries_len = @intCast(ip.dep_entries.items.len), .free_dep_entries_len = @intCast(ip.free_dep_entries.items.len), + .files_len = @intCast(ip.files.entries.len), }, }; addBuf(&bufs_list, &bufs_len, mem.asBytes(&header)); @@ -2804,8 +2811,10 @@ pub fn saveState(comp: *Compilation) !void { addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items)); addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items)); + addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys())); + addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values())); + // TODO: compilation errors - // TODO: files // TODO: namespaces // TODO: decls // TODO: linker state @@ -2827,6 +2836,9 @@ pub fn saveState(comp: *Compilation) !void { } fn addBuf(bufs_list: []std.posix.iovec_const, bufs_len: *usize, buf: []const u8) void { + // Even when len=0, the undefined pointer might cause EFAULT. + if (buf.len == 0) return; + const i = bufs_len.*; bufs_len.* = i + 1; bufs_list[i] = .{ @@ -3350,16 +3362,31 @@ pub fn performAllTheWork( } } - while (comp.astgen_work_queue.readItem()) |file| { - comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerAstGenFile, .{ - comp, file, zir_prog_node, &comp.astgen_wait_group, .root, - }); - } + if (comp.module) |zcu| { + { + // Worker threads may append to zcu.files and zcu.import_table + // so we must hold the lock while spawning those tasks, since + // we access those tables in this loop. + comp.mutex.lock(); + defer comp.mutex.unlock(); - while (comp.embed_file_work_queue.readItem()) |embed_file| { - comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerCheckEmbedFile, .{ - comp, embed_file, - }); + while (comp.astgen_work_queue.readItem()) |file_index| { + // Pre-load these things from our single-threaded context since they + // will be needed by the worker threads. + const path_digest = zcu.filePathDigest(file_index); + const root_decl = zcu.fileRootDecl(file_index); + const file = zcu.fileByIndex(file_index); + comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerAstGenFile, .{ + comp, file, file_index, path_digest, root_decl, zir_prog_node, &comp.astgen_wait_group, .root, + }); + } + } + + while (comp.embed_file_work_queue.readItem()) |embed_file| { + comp.thread_pool.spawnWg(&comp.astgen_wait_group, workerCheckEmbedFile, .{ + comp, embed_file, + }); + } } while (comp.c_object_work_queue.readItem()) |c_object| { @@ -3423,8 +3450,8 @@ pub fn performAllTheWork( fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !void { switch (job) { .codegen_decl => |decl_index| { - const module = comp.module.?; - const decl = module.declPtr(decl_index); + const zcu = comp.module.?; + const decl = zcu.declPtr(decl_index); switch (decl.analysis) { .unreferenced => unreachable, @@ -3442,7 +3469,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo assert(decl.has_tv); - try module.linkerUpdateDecl(decl_index); + try zcu.linkerUpdateDecl(decl_index); return; }, } @@ -3451,16 +3478,16 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo const named_frame = tracy.namedFrame("codegen_func"); defer named_frame.end(); - const module = comp.module.?; + const zcu = comp.module.?; // This call takes ownership of `func.air`. - try module.linkerUpdateFunc(func.func, func.air); + try zcu.linkerUpdateFunc(func.func, func.air); }, .analyze_func => |func| { const named_frame = tracy.namedFrame("analyze_func"); defer named_frame.end(); - const module = comp.module.?; - module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { + const zcu = comp.module.?; + zcu.ensureFuncBodyAnalyzed(func) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.AnalysisFail => return, }; @@ -3469,8 +3496,8 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo if (true) @panic("regressed compiler feature: emit-h should hook into updateExports, " ++ "not decl analysis, which is too early to know about @export calls"); - const module = comp.module.?; - const decl = module.declPtr(decl_index); + const zcu = comp.module.?; + const decl = zcu.declPtr(decl_index); switch (decl.analysis) { .unreferenced => unreachable, @@ -3488,7 +3515,7 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo defer named_frame.end(); const gpa = comp.gpa; - const emit_h = module.emit_h.?; + const emit_h = zcu.emit_h.?; _ = try emit_h.decl_table.getOrPut(gpa, decl_index); const decl_emit_h = emit_h.declPtr(decl_index); const fwd_decl = &decl_emit_h.fwd_decl; @@ -3496,10 +3523,12 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo var ctypes_arena = std.heap.ArenaAllocator.init(gpa); defer ctypes_arena.deinit(); + const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); + var dg: c_codegen.DeclGen = .{ .gpa = gpa, - .zcu = module, - .mod = module.namespacePtr(decl.src_namespace).file_scope.mod, + .zcu = zcu, + .mod = file_scope.mod, .error_msg = null, .pass = .{ .decl = decl_index }, .is_naked_fn = false, @@ -3528,17 +3557,17 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo } }, .analyze_decl => |decl_index| { - const module = comp.module.?; - module.ensureDeclAnalyzed(decl_index) catch |err| switch (err) { + const zcu = comp.module.?; + zcu.ensureDeclAnalyzed(decl_index) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.AnalysisFail => return, }; - const decl = module.declPtr(decl_index); + const decl = zcu.declPtr(decl_index); if (decl.kind == .@"test" and comp.config.is_test) { // Tests are always emitted in test binaries. The decl_refs are created by - // Module.populateTestFunctions, but this will not queue body analysis, so do + // Zcu.populateTestFunctions, but this will not queue body analysis, so do // that now. - try module.ensureFuncBodyAnalysisQueued(decl.val.toIntern()); + try zcu.ensureFuncBodyAnalysisQueued(decl.val.toIntern()); } }, .resolve_type_fully => |ty| { @@ -3556,30 +3585,30 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: std.Progress.Node) !vo defer named_frame.end(); const gpa = comp.gpa; - const module = comp.module.?; - const decl = module.declPtr(decl_index); + const zcu = comp.module.?; + const decl = zcu.declPtr(decl_index); const lf = comp.bin_file.?; - lf.updateDeclLineNumber(module, decl_index) catch |err| { - try module.failed_analysis.ensureUnusedCapacity(gpa, 1); - module.failed_analysis.putAssumeCapacityNoClobber( + lf.updateDeclLineNumber(zcu, decl_index) catch |err| { + try zcu.failed_analysis.ensureUnusedCapacity(gpa, 1); + zcu.failed_analysis.putAssumeCapacityNoClobber( InternPool.AnalUnit.wrap(.{ .decl = decl_index }), - try Module.ErrorMsg.create( + try Zcu.ErrorMsg.create( gpa, - decl.navSrcLoc(module), + decl.navSrcLoc(zcu), "unable to update line number: {s}", .{@errorName(err)}, ), ); decl.analysis = .codegen_failure; - try module.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); + try zcu.retryable_failures.append(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index })); }; }, .analyze_mod => |pkg| { const named_frame = tracy.namedFrame("analyze_mod"); defer named_frame.end(); - const module = comp.module.?; - module.semaPkg(pkg) catch |err| switch (err) { + const zcu = comp.module.?; + zcu.semaPkg(pkg) catch |err| switch (err) { error.OutOfMemory => return error.OutOfMemory, error.AnalysisFail => return, }; @@ -4012,14 +4041,17 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye const AstGenSrc = union(enum) { root, import: struct { - importing_file: *Module.File, + importing_file: Zcu.File.Index, import_tok: std.zig.Ast.TokenIndex, }, }; fn workerAstGenFile( comp: *Compilation, - file: *Module.File, + file: *Zcu.File, + file_index: Zcu.File.Index, + path_digest: Cache.BinDigest, + root_decl: Zcu.Decl.OptionalIndex, prog_node: std.Progress.Node, wg: *WaitGroup, src: AstGenSrc, @@ -4027,12 +4059,12 @@ fn workerAstGenFile( const child_prog_node = prog_node.start(file.sub_file_path, 0); defer child_prog_node.end(); - const mod = comp.module.?; - mod.astGenFile(file) catch |err| switch (err) { + const zcu = comp.module.?; + zcu.astGenFile(file, file_index, path_digest, root_decl) catch |err| switch (err) { error.AnalysisFail => return, else => { file.status = .retryable_failure; - comp.reportRetryableAstGenError(src, file, err) catch |oom| switch (oom) { + comp.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) { // Swallowing this error is OK because it's implied to be OOM when // there is a missing `failed_files` error message. error.OutOfMemory => {}, @@ -4059,29 +4091,31 @@ fn workerAstGenFile( // `@import("builtin")` is handled specially. if (mem.eql(u8, import_path, "builtin")) continue; - const import_result = blk: { + const import_result, const imported_path_digest, const imported_root_decl = blk: { comp.mutex.lock(); defer comp.mutex.unlock(); - const res = mod.importFile(file, import_path) catch continue; + const res = zcu.importFile(file, import_path) catch continue; if (!res.is_pkg) { - res.file.addReference(mod.*, .{ .import = .{ - .file = file, + res.file.addReference(zcu.*, .{ .import = .{ + .file = file_index, .token = item.data.token, } }) catch continue; } - break :blk res; + const imported_path_digest = zcu.filePathDigest(res.file_index); + const imported_root_decl = zcu.fileRootDecl(res.file_index); + break :blk .{ res, imported_path_digest, imported_root_decl }; }; if (import_result.is_new) { log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{ file.sub_file_path, import_path, import_result.file.sub_file_path, }); const sub_src: AstGenSrc = .{ .import = .{ - .importing_file = file, + .importing_file = file_index, .import_tok = item.data.token, } }; comp.thread_pool.spawnWg(wg, workerAstGenFile, .{ - comp, import_result.file, prog_node, wg, sub_src, + comp, import_result.file, import_result.file_index, imported_path_digest, imported_root_decl, prog_node, wg, sub_src, }); } } @@ -4432,21 +4466,22 @@ fn reportRetryableWin32ResourceError( fn reportRetryableAstGenError( comp: *Compilation, src: AstGenSrc, - file: *Module.File, + file_index: Zcu.File.Index, err: anyerror, ) error{OutOfMemory}!void { - const mod = comp.module.?; - const gpa = mod.gpa; + const zcu = comp.module.?; + const gpa = zcu.gpa; + const file = zcu.fileByIndex(file_index); file.status = .retryable_failure; const src_loc: Module.LazySrcLoc = switch (src) { .root => .{ - .base_node_inst = try mod.intern_pool.trackZir(gpa, file, .main_struct_inst), + .base_node_inst = try zcu.intern_pool.trackZir(gpa, file_index, .main_struct_inst), .offset = .entire_file, }, .import => |info| .{ - .base_node_inst = try mod.intern_pool.trackZir(gpa, info.importing_file, .main_struct_inst), + .base_node_inst = try zcu.intern_pool.trackZir(gpa, info.importing_file, .main_struct_inst), .offset = .{ .token_abs = info.import_tok }, }, }; @@ -4459,7 +4494,7 @@ fn reportRetryableAstGenError( { comp.mutex.lock(); defer comp.mutex.unlock(); - try mod.failed_files.putNoClobber(gpa, file, err_msg); + try zcu.failed_files.putNoClobber(gpa, file, err_msg); } } diff --git a/src/InternPool.zig b/src/InternPool.zig index c6b27acaf3..18cd21d08d 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -92,12 +92,27 @@ dep_entries: std.ArrayListUnmanaged(DepEntry) = .{}, /// garbage collection pass. free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{}, +/// Elements are ordered identically to the `import_table` field of `Zcu`. +/// +/// Unlike `import_table`, this data is serialized as part of incremental +/// compilation state. +/// +/// Key is the hash of the path to this file, used to store +/// `InternPool.TrackedInst`. +/// +/// Value is the `Decl` of the struct that represents this `File`. +files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, OptionalDeclIndex) = .{}, + +pub const FileIndex = enum(u32) { + _, +}; + pub const TrackedInst = extern struct { - path_digest: Cache.BinDigest, + file: FileIndex, inst: Zir.Inst.Index, comptime { // The fields should be tightly packed. See also serialiation logic in `Compilation.saveState`. - assert(@sizeOf(@This()) == Cache.bin_digest_len + @sizeOf(Zir.Inst.Index)); + assert(@sizeOf(@This()) == @sizeOf(FileIndex) + @sizeOf(Zir.Inst.Index)); } pub const Index = enum(u32) { _, @@ -123,9 +138,14 @@ pub const TrackedInst = extern struct { }; }; -pub fn trackZir(ip: *InternPool, gpa: Allocator, file: *Module.File, inst: Zir.Inst.Index) Allocator.Error!TrackedInst.Index { +pub fn trackZir( + ip: *InternPool, + gpa: Allocator, + file: FileIndex, + inst: Zir.Inst.Index, +) Allocator.Error!TrackedInst.Index { const key: TrackedInst = .{ - .path_digest = file.path_digest, + .file = file, .inst = inst, }; const gop = try ip.tracked_insts.getOrPut(gpa, key); @@ -4592,6 +4612,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { ip.dep_entries.deinit(gpa); ip.free_dep_entries.deinit(gpa); + ip.files.deinit(gpa); + ip.* = undefined; } diff --git a/src/Package/Module.zig b/src/Package/Module.zig index 80d7015610..61b7d2ac4d 100644 --- a/src/Package/Module.zig +++ b/src/Package/Module.zig @@ -379,7 +379,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { const new_file = try arena.create(File); - const bin_digest, const hex_digest = digest: { + const hex_digest = digest: { var hasher: Cache.Hasher = Cache.hasher_init; hasher.update(generated_builtin_source); @@ -393,7 +393,7 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { .{std.fmt.fmtSliceHexLower(&bin_digest)}, ) catch unreachable; - break :digest .{ bin_digest, hex_digest }; + break :digest hex_digest; }; const builtin_sub_path = try arena.dupe(u8, "b" ++ std.fs.path.sep_str ++ hex_digest); @@ -443,10 +443,6 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module { .zir = undefined, .status = .never_loaded, .mod = new, - .root_decl = .none, - // We might as well use this digest for the File `path digest`, since there's a - // one-to-one correspondence here between distinct paths and distinct contents. - .path_digest = bin_digest, }; break :b new; }; diff --git a/src/Sema.zig b/src/Sema.zig index 0d4cf26871..40fe11af3a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -546,8 +546,12 @@ pub const Block = struct { }; } - pub fn getFileScope(block: *Block, mod: *Module) *Module.File { - return mod.namespacePtr(block.namespace).file_scope; + pub fn getFileScope(block: *Block, zcu: *Zcu) *Zcu.File { + return zcu.fileByIndex(getFileScopeIndex(block, zcu)); + } + + pub fn getFileScopeIndex(block: *Block, zcu: *Zcu) Zcu.File.Index { + return zcu.namespacePtr(block.namespace).file_scope; } fn addTy( @@ -826,7 +830,16 @@ pub const Block = struct { pub fn ownerModule(block: Block) *Package.Module { const zcu = block.sema.mod; - return zcu.namespacePtr(block.namespace).file_scope.mod; + return zcu.namespacePtr(block.namespace).fileScope(zcu).mod; + } + + fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index { + const sema = block.sema; + const gpa = sema.gpa; + const zcu = sema.mod; + const ip = &zcu.intern_pool; + const file_index = block.getFileScopeIndex(zcu); + return ip.trackZir(gpa, file_index, inst); } }; @@ -979,7 +992,7 @@ fn analyzeBodyInner( try sema.inst_map.ensureSpaceForInstructions(sema.gpa, body); - const mod = sema.mod; + const zcu = sema.mod; const map = &sema.inst_map; const tags = sema.code.instructions.items(.tag); const datas = sema.code.instructions.items(.data); @@ -999,9 +1012,9 @@ fn analyzeBodyInner( // The hashmap lookup in here is a little expensive, and LLVM fails to optimize it away. if (build_options.enable_logging) { std.log.scoped(.sema_zir).debug("sema ZIR {s} %{d}", .{ sub_file_path: { - const path_digest = block.src_base_inst.resolveFull(&mod.intern_pool).path_digest; - const index = mod.path_digest_map.getIndex(path_digest).?; - break :sub_file_path mod.import_table.values()[index].sub_file_path; + const file_index = block.src_base_inst.resolveFull(&zcu.intern_pool).file; + const file = zcu.fileByIndex(file_index); + break :sub_file_path file.sub_file_path; }, inst }); } @@ -1762,9 +1775,9 @@ fn analyzeBodyInner( const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); const err_union = try sema.resolveInst(extra.data.operand); const err_union_ty = sema.typeOf(err_union); - if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) { + if (err_union_ty.zigTypeTag(zcu) != .ErrorUnion) { return sema.fail(block, operand_src, "expected error union type, found '{}'", .{ - err_union_ty.fmt(mod), + err_union_ty.fmt(zcu), }); } const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); @@ -2730,7 +2743,7 @@ fn zirStructDecl( const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); const extra = sema.code.extraData(Zir.Inst.StructDecl, extended.operand); - const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst); + const tracked_inst = try block.trackZir(inst); const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0), @@ -2806,7 +2819,7 @@ fn zirStructDecl( try ip.addDependency( sema.gpa, AnalUnit.wrap(.{ .decl = new_decl_index }), - .{ .src_hash = try ip.trackZir(sema.gpa, block.getFileScope(mod), inst) }, + .{ .src_hash = try block.trackZir(inst) }, ); } @@ -2814,7 +2827,7 @@ fn zirStructDecl( const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try mod.createNamespace(.{ .parent = block.namespace.toOptional(), .decl_index = new_decl_index, - .file_scope = block.getFileScope(mod), + .file_scope = block.getFileScopeIndex(mod), })).toOptional() else .none; errdefer if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns); @@ -2947,7 +2960,7 @@ fn zirEnumDecl( const extra = sema.code.extraData(Zir.Inst.EnumDecl, extended.operand); var extra_index: usize = extra.end; - const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst); + const tracked_inst = try block.trackZir(inst); const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; const tag_ty_src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = .{ .node_offset_container_tag = 0 } }; @@ -3040,9 +3053,9 @@ fn zirEnumDecl( if (sema.mod.comp.debug_incremental) { try mod.intern_pool.addDependency( - sema.gpa, + gpa, AnalUnit.wrap(.{ .decl = new_decl_index }), - .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) }, + .{ .src_hash = try block.trackZir(inst) }, ); } @@ -3050,7 +3063,7 @@ fn zirEnumDecl( const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try mod.createNamespace(.{ .parent = block.namespace.toOptional(), .decl_index = new_decl_index, - .file_scope = block.getFileScope(mod), + .file_scope = block.getFileScopeIndex(mod), })).toOptional() else .none; errdefer if (!done) if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns); @@ -3232,7 +3245,7 @@ fn zirUnionDecl( const extra = sema.code.extraData(Zir.Inst.UnionDecl, extended.operand); var extra_index: usize = extra.end; - const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst); + const tracked_inst = try block.trackZir(inst); const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; extra_index += @intFromBool(small.has_tag_type); @@ -3306,9 +3319,9 @@ fn zirUnionDecl( if (sema.mod.comp.debug_incremental) { try mod.intern_pool.addDependency( - sema.gpa, + gpa, AnalUnit.wrap(.{ .decl = new_decl_index }), - .{ .src_hash = try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst) }, + .{ .src_hash = try block.trackZir(inst) }, ); } @@ -3316,7 +3329,7 @@ fn zirUnionDecl( const new_namespace_index: InternPool.OptionalNamespaceIndex = if (true or decls_len > 0) (try mod.createNamespace(.{ .parent = block.namespace.toOptional(), .decl_index = new_decl_index, - .file_scope = block.getFileScope(mod), + .file_scope = block.getFileScopeIndex(mod), })).toOptional() else .none; errdefer if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns); @@ -3348,7 +3361,7 @@ fn zirOpaqueDecl( const extra = sema.code.extraData(Zir.Inst.OpaqueDecl, extended.operand); var extra_index: usize = extra.end; - const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst); + const tracked_inst = try block.trackZir(inst); const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0) }; const captures_len = if (small.has_captures_len) blk: { @@ -3397,14 +3410,14 @@ fn zirOpaqueDecl( try ip.addDependency( gpa, AnalUnit.wrap(.{ .decl = new_decl_index }), - .{ .src_hash = try ip.trackZir(gpa, block.getFileScope(mod), inst) }, + .{ .src_hash = try block.trackZir(inst) }, ); } const new_namespace_index: InternPool.OptionalNamespaceIndex = if (decls_len > 0) (try mod.createNamespace(.{ .parent = block.namespace.toOptional(), .decl_index = new_decl_index, - .file_scope = block.getFileScope(mod), + .file_scope = block.getFileScopeIndex(mod), })).toOptional() else .none; errdefer if (new_namespace_index.unwrap()) |ns| mod.destroyNamespace(ns); @@ -5893,8 +5906,8 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr const tracy = trace(@src()); defer tracy.end(); - const mod = sema.mod; - const comp = mod.comp; + const zcu = sema.mod; + const comp = zcu.comp; const gpa = sema.gpa; const pl_node = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node; const src = parent_block.nodeOffset(pl_node.src_node); @@ -5940,7 +5953,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr if (!comp.config.link_libc) try sema.errNote(src, msg, "libc headers not available; compilation does not link against libc", .{}); - const gop = try mod.cimport_errors.getOrPut(gpa, sema.ownerUnit()); + const gop = try zcu.cimport_errors.getOrPut(gpa, sema.ownerUnit()); if (!gop.found_existing) { gop.value_ptr.* = c_import_res.errors; c_import_res.errors = std.zig.ErrorBundle.empty; @@ -5984,14 +5997,16 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr else => |e| return e, }; - const result = mod.importPkg(c_import_mod) catch |err| + const result = zcu.importPkg(c_import_mod) catch |err| return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); - mod.astGenFile(result.file) catch |err| + const path_digest = zcu.filePathDigest(result.file_index); + const root_decl = zcu.fileRootDecl(result.file_index); + zcu.astGenFile(result.file, result.file_index, path_digest, root_decl) catch |err| return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); - try mod.ensureFileAnalyzed(result.file); - const file_root_decl_index = result.file.root_decl.unwrap().?; + try zcu.ensureFileAnalyzed(result.file_index); + const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?; return sema.analyzeDeclVal(parent_block, src, file_root_decl_index); } @@ -6730,7 +6745,9 @@ fn lookupInNamespace( // Skip decls which are not marked pub, which are in a different // file than the `a.b`/`@hasDecl` syntax. const decl = mod.declPtr(decl_index); - if (decl.is_pub or (src_file == decl.getFileScope(mod) and checked_namespaces.values()[check_i])) { + if (decl.is_pub or (src_file == decl.getFileScopeIndex(mod) and + checked_namespaces.values()[check_i])) + { try candidates.append(gpa, decl_index); } } @@ -6741,7 +6758,7 @@ fn lookupInNamespace( if (sub_usingnamespace_decl_index == sema.owner_decl_index) continue; const sub_usingnamespace_decl = mod.declPtr(sub_usingnamespace_decl_index); const sub_is_pub = entry.value_ptr.*; - if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScope(mod)) { + if (!sub_is_pub and src_file != sub_usingnamespace_decl.getFileScopeIndex(mod)) { // Skip usingnamespace decls which are not marked pub, which are in // a different file than the `a.b`/`@hasDecl` syntax. continue; @@ -6749,7 +6766,7 @@ fn lookupInNamespace( try sema.ensureDeclAnalyzed(sub_usingnamespace_decl_index); const ns_ty = sub_usingnamespace_decl.val.toType(); const sub_ns = mod.namespacePtrUnwrap(ns_ty.getNamespaceIndex(mod)) orelse continue; - try checked_namespaces.put(gpa, sub_ns, src_file == sub_usingnamespace_decl.getFileScope(mod)); + try checked_namespaces.put(gpa, sub_ns, src_file == sub_usingnamespace_decl.getFileScopeIndex(mod)); } } @@ -8067,20 +8084,20 @@ fn instantiateGenericCall( call_tag: Air.Inst.Tag, call_dbg_node: ?Zir.Inst.Index, ) CompileError!Air.Inst.Ref { - const mod = sema.mod; + const zcu = sema.mod; const gpa = sema.gpa; - const ip = &mod.intern_pool; + const ip = &zcu.intern_pool; const func_val = try sema.resolveConstDefinedValue(block, func_src, func, .{ .needed_comptime_reason = "generic function being called must be comptime-known", }); - const generic_owner = switch (mod.intern_pool.indexToKey(func_val.toIntern())) { + const generic_owner = switch (zcu.intern_pool.indexToKey(func_val.toIntern())) { .func => func_val.toIntern(), - .ptr => |ptr| mod.declPtr(ptr.base_addr.decl).val.toIntern(), + .ptr => |ptr| zcu.declPtr(ptr.base_addr.decl).val.toIntern(), else => unreachable, }; - const generic_owner_func = mod.intern_pool.indexToKey(generic_owner).func; - const generic_owner_ty_info = mod.typeToFunc(Type.fromInterned(generic_owner_func.ty)).?; + const generic_owner_func = zcu.intern_pool.indexToKey(generic_owner).func; + const generic_owner_ty_info = zcu.typeToFunc(Type.fromInterned(generic_owner_func.ty)).?; try sema.declareDependency(.{ .src_hash = generic_owner_func.zir_body_inst }); @@ -8092,10 +8109,10 @@ fn instantiateGenericCall( // The actual monomorphization happens via adding `func_instance` to // `InternPool`. - const fn_owner_decl = mod.declPtr(generic_owner_func.owner_decl); + const fn_owner_decl = zcu.declPtr(generic_owner_func.owner_decl); const namespace_index = fn_owner_decl.src_namespace; - const namespace = mod.namespacePtr(namespace_index); - const fn_zir = namespace.file_scope.zir; + const namespace = zcu.namespacePtr(namespace_index); + const fn_zir = namespace.fileScope(zcu).zir; const fn_info = fn_zir.getFnInfo(generic_owner_func.zir_body_inst.resolve(ip)); const comptime_args = try sema.arena.alloc(InternPool.Index, args_info.count()); @@ -8110,7 +8127,7 @@ fn instantiateGenericCall( // `param_anytype_comptime` ZIR instructions to be ignored, resulting in a // new, monomorphized function, with the comptime parameters elided. var child_sema: Sema = .{ - .mod = mod, + .mod = zcu, .gpa = gpa, .arena = sema.arena, .code = fn_zir, @@ -8199,7 +8216,7 @@ fn instantiateGenericCall( const arg_ref = try args_info.analyzeArg(sema, block, arg_index, param_ty, generic_owner_ty_info, func); try sema.validateRuntimeValue(block, args_info.argSrc(block, arg_index), arg_ref); const arg_ty = sema.typeOf(arg_ref); - if (arg_ty.zigTypeTag(mod) == .NoReturn) { + if (arg_ty.zigTypeTag(zcu) == .NoReturn) { // This terminates argument analysis. return arg_ref; } @@ -8283,12 +8300,12 @@ fn instantiateGenericCall( const new_func_inst = try child_sema.resolveInlineBody(&child_block, fn_info.param_body[args_info.count()..], fn_info.param_body_inst); const callee_index = (child_sema.resolveConstDefinedValue(&child_block, LazySrcLoc.unneeded, new_func_inst, undefined) catch unreachable).toIntern(); - const callee = mod.funcInfo(callee_index); + const callee = zcu.funcInfo(callee_index); callee.branchQuota(ip).* = @max(callee.branchQuota(ip).*, sema.branch_quota); // Make a runtime call to the new function, making sure to omit the comptime args. const func_ty = Type.fromInterned(callee.ty); - const func_ty_info = mod.typeToFunc(func_ty).?; + const func_ty_info = zcu.typeToFunc(func_ty).?; // If the call evaluated to a return type that requires comptime, never mind // our generic instantiation. Instead we need to perform a comptime call. @@ -8304,13 +8321,13 @@ fn instantiateGenericCall( if (call_dbg_node) |some| try sema.zirDbgStmt(block, some); if (sema.owner_func_index != .none and - Type.fromInterned(func_ty_info.return_type).isError(mod)) + Type.fromInterned(func_ty_info.return_type).isError(zcu)) { ip.funcAnalysis(sema.owner_func_index).calls_or_awaits_errorable_fn = true; } try sema.addReferenceEntry(call_src, AnalUnit.wrap(.{ .func = callee_index })); - try mod.ensureFuncBodyAnalysisQueued(callee_index); + try zcu.ensureFuncBodyAnalysisQueued(callee_index); try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Call).Struct.fields.len + runtime_args.items.len); const result = try block.addInst(.{ @@ -8333,7 +8350,7 @@ fn instantiateGenericCall( if (call_tag == .call_always_tail) { return sema.handleTailCall(block, call_src, func_ty, result); } - if (func_ty.fnReturnType(mod).isNoReturn(mod)) { + if (func_ty.fnReturnType(zcu).isNoReturn(zcu)) { _ = try block.addNoOp(.unreach); return .unreachable_value; } @@ -9653,7 +9670,7 @@ fn funcCommon( .is_generic = final_is_generic, .is_noinline = is_noinline, - .zir_body_inst = try ip.trackZir(gpa, block.getFileScope(mod), func_inst), + .zir_body_inst = try block.trackZir(func_inst), .lbrace_line = src_locs.lbrace_line, .rbrace_line = src_locs.rbrace_line, .lbrace_column = @as(u16, @truncate(src_locs.columns)), @@ -9731,7 +9748,7 @@ fn funcCommon( .ty = func_ty, .cc = cc, .is_noinline = is_noinline, - .zir_body_inst = try ip.trackZir(gpa, block.getFileScope(mod), func_inst), + .zir_body_inst = try block.trackZir(func_inst), .lbrace_line = src_locs.lbrace_line, .rbrace_line = src_locs.rbrace_line, .lbrace_column = @as(u16, @truncate(src_locs.columns)), @@ -13787,18 +13804,18 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. const tracy = trace(@src()); defer tracy.end(); - const mod = sema.mod; + const zcu = sema.mod; const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].str_tok; const operand_src = block.tokenOffset(inst_data.src_tok); const operand = inst_data.get(sema.code); - const result = mod.importFile(block.getFileScope(mod), operand) catch |err| switch (err) { + const result = zcu.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) { error.ImportOutsideModulePath => { return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand}); }, error.ModuleNotFound => { return sema.fail(block, operand_src, "no module named '{s}' available within module {s}", .{ - operand, block.getFileScope(mod).mod.fully_qualified_name, + operand, block.getFileScope(zcu).mod.fully_qualified_name, }); }, else => { @@ -13807,8 +13824,8 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. return sema.fail(block, operand_src, "unable to open '{s}': {s}", .{ operand, @errorName(err) }); }, }; - try mod.ensureFileAnalyzed(result.file); - const file_root_decl_index = result.file.root_decl.unwrap().?; + try zcu.ensureFileAnalyzed(result.file_index); + const file_root_decl_index = zcu.fileRootDecl(result.file_index).unwrap().?; return sema.analyzeDeclVal(block, operand_src, file_root_decl_index); } @@ -21089,7 +21106,7 @@ fn zirReify( const ip = &mod.intern_pool; const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small); const extra = sema.code.extraData(Zir.Inst.Reify, extended.operand).data; - const tracked_inst = try ip.trackZir(gpa, block.getFileScope(mod), inst); + const tracked_inst = try block.trackZir(inst); const src: LazySrcLoc = .{ .base_node_inst = tracked_inst, .offset = LazySrcLoc.Offset.nodeOffset(0), @@ -21466,7 +21483,7 @@ fn zirReify( const wip_ty = switch (try ip.getOpaqueType(gpa, .{ .has_namespace = false, .key = .{ .reified = .{ - .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst), + .zir_index = try block.trackZir(inst), } }, })) { .existing => |ty| return Air.internedToRef(ty), @@ -21660,7 +21677,7 @@ fn reifyEnum( .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive, .fields_len = fields_len, .key = .{ .reified = .{ - .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst), + .zir_index = try block.trackZir(inst), .type_hash = hasher.final(), } }, })) { @@ -21810,7 +21827,7 @@ fn reifyUnion( .field_types = &.{}, // set later .field_aligns = &.{}, // set later .key = .{ .reified = .{ - .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst), + .zir_index = try block.trackZir(inst), .type_hash = hasher.final(), } }, })) { @@ -22062,7 +22079,7 @@ fn reifyStruct( .inits_resolved = true, .has_namespace = false, .key = .{ .reified = .{ - .zir_index = try ip.trackZir(gpa, block.getFileScope(mod), inst), + .zir_index = try block.trackZir(inst), .type_hash = hasher.final(), } }, })) { @@ -34894,14 +34911,14 @@ pub fn resolveStructLayout(sema: *Sema, ty: Type) SemaError!void { _ = try sema.typeRequiresComptime(ty); } -fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) CompileError!void { - const gpa = mod.gpa; - const ip = &mod.intern_pool; +fn semaBackingIntType(zcu: *Zcu, struct_type: InternPool.LoadedStructType) CompileError!void { + const gpa = zcu.gpa; + const ip = &zcu.intern_pool; const decl_index = struct_type.decl.unwrap().?; - const decl = mod.declPtr(decl_index); + const decl = zcu.declPtr(decl_index); - const zir = mod.namespacePtr(struct_type.namespace.unwrap().?).file_scope.zir; + const zir = zcu.namespacePtr(struct_type.namespace.unwrap().?).fileScope(zcu).zir; var analysis_arena = std.heap.ArenaAllocator.init(gpa); defer analysis_arena.deinit(); @@ -34910,7 +34927,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co defer comptime_err_ret_trace.deinit(); var sema: Sema = .{ - .mod = mod, + .mod = zcu, .gpa = gpa, .arena = analysis_arena.allocator(), .code = zir, @@ -34941,7 +34958,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co var accumulator: u64 = 0; for (0..struct_type.field_types.len) |i| { const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[i]); - accumulator += try field_ty.bitSizeAdvanced(mod, .sema); + accumulator += try field_ty.bitSizeAdvanced(zcu, .sema); } break :blk accumulator; }; @@ -34987,7 +35004,7 @@ fn semaBackingIntType(mod: *Module, struct_type: InternPool.LoadedStructType) Co if (fields_bit_sum > std.math.maxInt(u16)) { return sema.fail(&block, block.nodeOffset(0), "size of packed struct '{d}' exceeds maximum bit width of 65535", .{fields_bit_sum}); } - const backing_int_ty = try mod.intType(.unsigned, @intCast(fields_bit_sum)); + const backing_int_ty = try zcu.intType(.unsigned, @intCast(fields_bit_sum)); struct_type.backingIntType(ip).* = backing_int_ty.toIntern(); } @@ -35597,23 +35614,23 @@ fn structZirInfo(zir: Zir, zir_index: Zir.Inst.Index) struct { } fn semaStructFields( - mod: *Module, + zcu: *Zcu, arena: Allocator, struct_type: InternPool.LoadedStructType, ) CompileError!void { - const gpa = mod.gpa; - const ip = &mod.intern_pool; + const gpa = zcu.gpa; + const ip = &zcu.intern_pool; const decl_index = struct_type.decl.unwrap() orelse return; - const decl = mod.declPtr(decl_index); + const decl = zcu.declPtr(decl_index); const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; - const zir = mod.namespacePtr(namespace_index).file_scope.zir; + const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir; const zir_index = struct_type.zir_index.unwrap().?.resolve(ip); const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); if (fields_len == 0) switch (struct_type.layout) { .@"packed" => { - try semaBackingIntType(mod, struct_type); + try semaBackingIntType(zcu, struct_type); return; }, .auto, .@"extern" => { @@ -35627,7 +35644,7 @@ fn semaStructFields( defer comptime_err_ret_trace.deinit(); var sema: Sema = .{ - .mod = mod, + .mod = zcu, .gpa = gpa, .arena = arena, .code = zir, @@ -35749,7 +35766,7 @@ fn semaStructFields( struct_type.field_types.get(ip)[field_i] = field_ty.toIntern(); - if (field_ty.zigTypeTag(mod) == .Opaque) { + if (field_ty.zigTypeTag(zcu) == .Opaque) { const msg = msg: { const msg = try sema.errMsg(ty_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{}); errdefer msg.destroy(sema.gpa); @@ -35759,7 +35776,7 @@ fn semaStructFields( }; return sema.failWithOwnedErrorMsg(&block_scope, msg); } - if (field_ty.zigTypeTag(mod) == .NoReturn) { + if (field_ty.zigTypeTag(zcu) == .NoReturn) { const msg = msg: { const msg = try sema.errMsg(ty_src, "struct fields cannot be 'noreturn'", .{}); errdefer msg.destroy(sema.gpa); @@ -35772,7 +35789,7 @@ fn semaStructFields( switch (struct_type.layout) { .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) { const msg = msg: { - const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(mod)}); + const msg = try sema.errMsg(ty_src, "extern structs cannot contain fields of type '{}'", .{field_ty.fmt(zcu)}); errdefer msg.destroy(sema.gpa); try sema.explainWhyTypeIsNotExtern(msg, ty_src, field_ty, .struct_field); @@ -35784,7 +35801,7 @@ fn semaStructFields( }, .@"packed" => if (!try sema.validatePackedType(field_ty)) { const msg = msg: { - const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(mod)}); + const msg = try sema.errMsg(ty_src, "packed structs cannot contain fields of type '{}'", .{field_ty.fmt(zcu)}); errdefer msg.destroy(sema.gpa); try sema.explainWhyTypeIsNotPacked(msg, ty_src, field_ty); @@ -35820,19 +35837,19 @@ fn semaStructFields( // This logic must be kept in sync with `semaStructFields` fn semaStructFieldInits( - mod: *Module, + zcu: *Zcu, arena: Allocator, struct_type: InternPool.LoadedStructType, ) CompileError!void { - const gpa = mod.gpa; - const ip = &mod.intern_pool; + const gpa = zcu.gpa; + const ip = &zcu.intern_pool; assert(!struct_type.haveFieldInits(ip)); const decl_index = struct_type.decl.unwrap() orelse return; - const decl = mod.declPtr(decl_index); + const decl = zcu.declPtr(decl_index); const namespace_index = struct_type.namespace.unwrap() orelse decl.src_namespace; - const zir = mod.namespacePtr(namespace_index).file_scope.zir; + const zir = zcu.namespacePtr(namespace_index).fileScope(zcu).zir; const zir_index = struct_type.zir_index.unwrap().?.resolve(ip); const fields_len, const small, var extra_index = structZirInfo(zir, zir_index); @@ -35840,7 +35857,7 @@ fn semaStructFieldInits( defer comptime_err_ret_trace.deinit(); var sema: Sema = .{ - .mod = mod, + .mod = zcu, .gpa = gpa, .arena = arena, .code = zir, @@ -35950,7 +35967,7 @@ fn semaStructFieldInits( }); }; - if (default_val.canMutateComptimeVarState(mod)) { + if (default_val.canMutateComptimeVarState(zcu)) { return sema.fail(&block_scope, init_src, "field default value contains reference to comptime-mutable memory", .{}); } struct_type.field_inits.get(ip)[field_i] = default_val.toIntern(); @@ -35960,14 +35977,14 @@ fn semaStructFieldInits( try sema.flushExports(); } -fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void { +fn semaUnionFields(zcu: *Zcu, arena: Allocator, union_type: InternPool.LoadedUnionType) CompileError!void { const tracy = trace(@src()); defer tracy.end(); - const gpa = mod.gpa; - const ip = &mod.intern_pool; + const gpa = zcu.gpa; + const ip = &zcu.intern_pool; const decl_index = union_type.decl; - const zir = mod.namespacePtr(union_type.namespace.unwrap().?).file_scope.zir; + const zir = zcu.namespacePtr(union_type.namespace.unwrap().?).fileScope(zcu).zir; const zir_index = union_type.zir_index.resolve(ip); const extended = zir.instructions.items(.data)[@intFromEnum(zir_index)].extended; assert(extended.opcode == .union_decl); @@ -36011,13 +36028,13 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded const body = zir.bodySlice(extra_index, body_len); extra_index += body.len; - const decl = mod.declPtr(decl_index); + const decl = zcu.declPtr(decl_index); var comptime_err_ret_trace = std.ArrayList(LazySrcLoc).init(gpa); defer comptime_err_ret_trace.deinit(); var sema: Sema = .{ - .mod = mod, + .mod = zcu, .gpa = gpa, .arena = arena, .code = zir, @@ -36063,18 +36080,18 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded if (small.auto_enum_tag) { // The provided type is an integer type and we must construct the enum tag type here. int_tag_ty = provided_ty; - if (int_tag_ty.zigTypeTag(mod) != .Int and int_tag_ty.zigTypeTag(mod) != .ComptimeInt) { - return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(mod)}); + if (int_tag_ty.zigTypeTag(zcu) != .Int and int_tag_ty.zigTypeTag(zcu) != .ComptimeInt) { + return sema.fail(&block_scope, tag_ty_src, "expected integer tag type, found '{}'", .{int_tag_ty.fmt(zcu)}); } if (fields_len > 0) { - const field_count_val = try mod.intValue(Type.comptime_int, fields_len - 1); + const field_count_val = try zcu.intValue(Type.comptime_int, fields_len - 1); if (!(try sema.intFitsInType(field_count_val, int_tag_ty, null))) { const msg = msg: { const msg = try sema.errMsg(tag_ty_src, "specified integer tag type cannot represent every field", .{}); errdefer msg.destroy(sema.gpa); try sema.errNote(tag_ty_src, msg, "type '{}' cannot fit values in range 0...{d}", .{ - int_tag_ty.fmt(mod), + int_tag_ty.fmt(zcu), fields_len - 1, }); break :msg msg; @@ -36089,7 +36106,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded union_type.tagTypePtr(ip).* = provided_ty.toIntern(); const enum_type = switch (ip.indexToKey(provided_ty.toIntern())) { .enum_type => ip.loadEnumType(provided_ty.toIntern()), - else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(mod)}), + else => return sema.fail(&block_scope, tag_ty_src, "expected enum tag type, found '{}'", .{provided_ty.fmt(zcu)}), }; // The fields of the union must match the enum exactly. // A flag per field is used to check for missing and extraneous fields. @@ -36185,7 +36202,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded const val = if (last_tag_val) |val| try sema.intAdd(val, Value.one_comptime_int, int_tag_ty, undefined) else - try mod.intValue(int_tag_ty, 0); + try zcu.intValue(int_tag_ty, 0); last_tag_val = val; break :blk val; @@ -36197,7 +36214,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded .offset = .{ .container_field_value = @intCast(gop.index) }, }; const msg = msg: { - const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(mod, &sema)}); + const msg = try sema.errMsg(value_src, "enum tag value {} already taken", .{enum_tag_val.fmtValue(zcu, &sema)}); errdefer msg.destroy(gpa); try sema.errNote(other_value_src, msg, "other occurrence here", .{}); break :msg msg; @@ -36227,7 +36244,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded const tag_info = ip.loadEnumType(union_type.tagTypePtr(ip).*); const enum_index = tag_info.nameIndex(ip, field_name) orelse { return sema.fail(&block_scope, name_src, "no field named '{}' in enum '{}'", .{ - field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(mod), + field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(zcu), }); }; @@ -36254,7 +36271,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded } } - if (field_ty.zigTypeTag(mod) == .Opaque) { + if (field_ty.zigTypeTag(zcu) == .Opaque) { const msg = msg: { const msg = try sema.errMsg(type_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{}); errdefer msg.destroy(sema.gpa); @@ -36269,7 +36286,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded !try sema.validateExternType(field_ty, .union_field)) { const msg = msg: { - const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)}); + const msg = try sema.errMsg(type_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(zcu)}); errdefer msg.destroy(sema.gpa); try sema.explainWhyTypeIsNotExtern(msg, type_src, field_ty, .union_field); @@ -36280,7 +36297,7 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded return sema.failWithOwnedErrorMsg(&block_scope, msg); } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) { const msg = msg: { - const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(mod)}); + const msg = try sema.errMsg(type_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(zcu)}); errdefer msg.destroy(sema.gpa); try sema.explainWhyTypeIsNotPacked(msg, type_src, field_ty); @@ -36325,10 +36342,10 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Loaded return sema.failWithOwnedErrorMsg(&block_scope, msg); } } else if (enum_field_vals.count() > 0) { - const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), mod.declPtr(union_type.decl)); + const enum_ty = try sema.generateUnionTagTypeNumbered(&block_scope, enum_field_names, enum_field_vals.keys(), zcu.declPtr(union_type.decl)); union_type.tagTypePtr(ip).* = enum_ty; } else { - const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, mod.declPtr(union_type.decl)); + const enum_ty = try sema.generateUnionTagTypeSimple(&block_scope, enum_field_names, zcu.declPtr(union_type.decl)); union_type.tagTypePtr(ip).* = enum_ty; } diff --git a/src/Type.zig b/src/Type.zig index 9f11a70bf3..49f1276070 100644 --- a/src/Type.zig +++ b/src/Type.zig @@ -3455,7 +3455,7 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 { else => return null, }; const info = tracked.resolveFull(&zcu.intern_pool); - const file = zcu.import_table.values()[zcu.path_digest_map.getIndex(info.path_digest).?]; + const file = zcu.fileByIndex(info.file); assert(file.zir_loaded); const zir = file.zir; const inst = zir.instructions.get(@intFromEnum(info.inst)); diff --git a/src/Zcu.zig b/src/Zcu.zig index adfe60e678..203238c633 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -72,6 +72,7 @@ codegen_prog_node: std.Progress.Node = undefined, global_zir_cache: Compilation.Directory, /// Used by AstGen worker to load and store ZIR cache. local_zir_cache: Compilation.Directory, + /// This is where all `Export` values are stored. Not all values here are necessarily valid exports; /// to enumerate all exports, `single_exports` and `multi_exports` must be consulted. all_exports: ArrayListUnmanaged(Export) = .{}, @@ -88,14 +89,22 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { index: u32, len: u32, }) = .{}, -/// The set of all the Zig source files in the Module. We keep track of this in order -/// to iterate over it and check which source files have been modified on the file system when -/// an update is requested, as well as to cache `@import` results. + +/// The set of all the Zig source files in the Zig Compilation Unit. Tracked in +/// order to iterate over it and check which source files have been modified on +/// the file system when an update is requested, as well as to cache `@import` +/// results. +/// /// Keys are fully resolved file paths. This table owns the keys and values. +/// +/// Protected by Compilation's mutex. +/// +/// Not serialized. This state is reconstructed during the first call to +/// `Compilation.update` of the process for a given `Compilation`. +/// +/// Indexes correspond 1:1 to `files`. import_table: std.StringArrayHashMapUnmanaged(*File) = .{}, -/// This acts as a map from `path_digest` to the corresponding `File`. -/// The value is omitted, as keys are ordered identically to `import_table`. -path_digest_map: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, void) = .{}, + /// The set of all the files which have been loaded with `@embedFile` in the Module. /// We keep track of this in order to iterate over it and check which files have been /// modified on the file system when an update is requested, as well as to cache @@ -387,8 +396,8 @@ pub const Decl = struct { anon, }; - const Index = InternPool.DeclIndex; - const OptionalIndex = InternPool.OptionalDeclIndex; + pub const Index = InternPool.DeclIndex; + pub const OptionalIndex = InternPool.OptionalDeclIndex; pub fn zirBodies(decl: Decl, zcu: *Zcu) Zir.Inst.Declaration.Bodies { const zir = decl.getFileScope(zcu).zir; @@ -490,6 +499,10 @@ pub const Decl = struct { } pub fn getFileScope(decl: Decl, zcu: *Zcu) *File { + return zcu.fileByIndex(getFileScopeIndex(decl, zcu)); + } + + pub fn getFileScopeIndex(decl: Decl, zcu: *Zcu) File.Index { return zcu.namespacePtr(decl.src_namespace).file_scope; } @@ -546,19 +559,20 @@ pub const Decl = struct { } pub fn navSrcLine(decl: Decl, zcu: *Zcu) u32 { + const ip = &zcu.intern_pool; const tracked = decl.zir_decl_index.unwrap() orelse inst: { // generic instantiation assert(decl.has_tv); assert(decl.owns_tv); - const generic_owner_func = switch (zcu.intern_pool.indexToKey(decl.val.toIntern())) { + const generic_owner_func = switch (ip.indexToKey(decl.val.toIntern())) { .func => |func| func.generic_owner, else => return 0, // TODO: this is probably a `variable` or something; figure this out when we finish sorting out `Decl`. }; const generic_owner_decl = zcu.declPtr(zcu.funcInfo(generic_owner_func).owner_decl); break :inst generic_owner_decl.zir_decl_index.unwrap().?; }; - const info = tracked.resolveFull(&zcu.intern_pool); - const file = zcu.import_table.values()[zcu.path_digest_map.getIndex(info.path_digest).?]; + const info = tracked.resolveFull(ip); + const file = zcu.fileByIndex(info.file); assert(file.zir_loaded); const zir = file.zir; const inst = zir.instructions.get(@intFromEnum(info.inst)); @@ -595,7 +609,7 @@ pub const DeclAdapter = struct { /// The container that structs, enums, unions, and opaques have. pub const Namespace = struct { parent: OptionalIndex, - file_scope: *File, + file_scope: File.Index, /// Will be a struct, enum, union, or opaque. decl_index: Decl.Index, /// Direct children of the namespace. @@ -627,6 +641,10 @@ pub const Namespace = struct { } }; + pub fn fileScope(ns: Namespace, zcu: *Zcu) *File { + return zcu.fileByIndex(ns.file_scope); + } + // This renders e.g. "std.fs.Dir.OpenOptions" pub fn renderFullyQualifiedName( ns: Namespace, @@ -641,7 +659,7 @@ pub const Namespace = struct { writer, ); } else { - try ns.file_scope.renderFullyQualifiedName(writer); + try ns.fileScope(zcu).renderFullyQualifiedName(writer); } if (name != .empty) try writer.print(".{}", .{name.fmt(&zcu.intern_pool)}); } @@ -661,7 +679,7 @@ pub const Namespace = struct { ); break :sep '.'; } else sep: { - try ns.file_scope.renderFullyQualifiedDebugName(writer); + try ns.fileScope(zcu).renderFullyQualifiedDebugName(writer); break :sep ':'; }; if (name != .empty) try writer.print("{c}{}", .{ sep, name.fmt(&zcu.intern_pool) }); @@ -680,7 +698,7 @@ pub const Namespace = struct { const decl = zcu.declPtr(cur_ns.decl_index); count += decl.name.length(ip) + 1; cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse { - count += ns.file_scope.sub_file_path.len; + count += ns.fileScope(zcu).sub_file_path.len; break :count count; }); } @@ -715,8 +733,6 @@ pub const Namespace = struct { }; pub const File = struct { - /// The Decl of the struct that represents this File. - root_decl: Decl.OptionalIndex, status: enum { never_loaded, retryable_failure, @@ -744,8 +760,6 @@ pub const File = struct { multi_pkg: bool = false, /// List of references to this file, used for multi-package errors. references: std.ArrayListUnmanaged(File.Reference) = .{}, - /// The hash of the path to this file, used to store `InternPool.TrackedInst`. - path_digest: Cache.BinDigest, /// The most recent successful ZIR for this file, with no errors. /// This is only populated when a previously successful ZIR @@ -757,7 +771,7 @@ pub const File = struct { pub const Reference = union(enum) { /// The file is imported directly (i.e. not as a package) with @import. import: struct { - file: *File, + file: File.Index, token: Ast.TokenIndex, }, /// The file is the root of a module. @@ -791,28 +805,6 @@ pub const File = struct { } } - pub fn deinit(file: *File, mod: *Module) void { - const gpa = mod.gpa; - const is_builtin = file.mod.isBuiltin(); - log.debug("deinit File {s}", .{file.sub_file_path}); - if (is_builtin) { - file.unloadTree(gpa); - file.unloadZir(gpa); - } else { - gpa.free(file.sub_file_path); - file.unload(gpa); - } - file.references.deinit(gpa); - if (file.root_decl.unwrap()) |root_decl| { - mod.destroyDecl(root_decl); - } - if (file.prev_zir) |prev_zir| { - prev_zir.deinit(gpa); - gpa.destroy(prev_zir); - } - file.* = undefined; - } - pub const Source = struct { bytes: [:0]const u8, stat: Cache.File.Stat, @@ -865,13 +857,6 @@ pub const File = struct { return &file.tree; } - pub fn destroy(file: *File, mod: *Module) void { - const gpa = mod.gpa; - const is_builtin = file.mod.isBuiltin(); - file.deinit(mod); - if (!is_builtin) gpa.destroy(file); - } - pub fn renderFullyQualifiedName(file: File, writer: anytype) !void { // Convert all the slashes into dots and truncate the extension. const ext = std.fs.path.extension(file.sub_file_path); @@ -937,7 +922,7 @@ pub const File = struct { } const mod = switch (ref) { - .import => |import| import.file.mod, + .import => |import| zcu.fileByIndex(import.file).mod, .root => |mod| mod, }; if (mod != file.mod) file.multi_pkg = true; @@ -971,6 +956,8 @@ pub const File = struct { } } } + + pub const Index = InternPool.FileIndex; }; pub const EmbedFile = struct { @@ -2350,14 +2337,12 @@ pub const LazySrcLoc = struct { }; pub fn resolveBaseNode(base_node_inst: InternPool.TrackedInst.Index, zcu: *Zcu) struct { *File, Ast.Node.Index } { - const want_path_digest, const zir_inst = inst: { - const info = base_node_inst.resolveFull(&zcu.intern_pool); - break :inst .{ info.path_digest, info.inst }; - }; - const file = file: { - const index = zcu.path_digest_map.getIndex(want_path_digest).?; - break :file zcu.import_table.values()[index]; + const ip = &zcu.intern_pool; + const file_index, const zir_inst = inst: { + const info = base_node_inst.resolveFull(ip); + break :inst .{ info.file, info.inst }; }; + const file = zcu.fileByIndex(file_index); assert(file.zir_loaded); const zir = file.zir; @@ -2423,11 +2408,11 @@ pub fn deinit(zcu: *Zcu) void { for (zcu.import_table.keys()) |key| { gpa.free(key); } - for (zcu.import_table.values()) |value| { - value.destroy(zcu); + for (0..zcu.import_table.entries.len) |file_index_usize| { + const file_index: File.Index = @enumFromInt(file_index_usize); + zcu.destroyFile(file_index); } zcu.import_table.deinit(gpa); - zcu.path_digest_map.deinit(gpa); for (zcu.embed_table.keys(), zcu.embed_table.values()) |path, embed_file| { gpa.free(path); @@ -2531,6 +2516,37 @@ pub fn destroyDecl(mod: *Module, decl_index: Decl.Index) void { } } +fn deinitFile(zcu: *Zcu, file_index: File.Index) void { + const gpa = zcu.gpa; + const file = zcu.fileByIndex(file_index); + const is_builtin = file.mod.isBuiltin(); + log.debug("deinit File {s}", .{file.sub_file_path}); + if (is_builtin) { + file.unloadTree(gpa); + file.unloadZir(gpa); + } else { + gpa.free(file.sub_file_path); + file.unload(gpa); + } + file.references.deinit(gpa); + if (zcu.fileRootDecl(file_index).unwrap()) |root_decl| { + zcu.destroyDecl(root_decl); + } + if (file.prev_zir) |prev_zir| { + prev_zir.deinit(gpa); + gpa.destroy(prev_zir); + } + file.* = undefined; +} + +pub fn destroyFile(zcu: *Zcu, file_index: File.Index) void { + const gpa = zcu.gpa; + const file = zcu.fileByIndex(file_index); + const is_builtin = file.mod.isBuiltin(); + zcu.deinitFile(file_index); + if (!is_builtin) gpa.destroy(file); +} + pub fn declPtr(mod: *Module, index: Decl.Index) *Decl { return mod.intern_pool.declPtr(index); } @@ -2563,14 +2579,23 @@ comptime { } } -pub fn astGenFile(mod: *Module, file: *File) !void { +pub fn astGenFile( + zcu: *Zcu, + file: *File, + /// This parameter is provided separately from `file` because it is not + /// safe to access `import_table` without a lock, and this index is needed + /// in the call to `updateZirRefs`. + file_index: File.Index, + path_digest: Cache.BinDigest, + opt_root_decl: Zcu.Decl.OptionalIndex, +) !void { assert(!file.mod.isBuiltin()); const tracy = trace(@src()); defer tracy.end(); - const comp = mod.comp; - const gpa = mod.gpa; + const comp = zcu.comp; + const gpa = zcu.gpa; // In any case we need to examine the stat of the file to determine the course of action. var source_file = try file.mod.root.openFile(file.sub_file_path, .{}); @@ -2578,17 +2603,9 @@ pub fn astGenFile(mod: *Module, file: *File) !void { const stat = try source_file.stat(); - const want_local_cache = file.mod == mod.main_mod; - const hex_digest = hex: { - var hex: Cache.HexDigest = undefined; - _ = std.fmt.bufPrint( - &hex, - "{s}", - .{std.fmt.fmtSliceHexLower(&file.path_digest)}, - ) catch unreachable; - break :hex hex; - }; - const cache_directory = if (want_local_cache) mod.local_zir_cache else mod.global_zir_cache; + const want_local_cache = file.mod == zcu.main_mod; + const hex_digest = Cache.binToHex(path_digest); + const cache_directory = if (want_local_cache) zcu.local_zir_cache else zcu.global_zir_cache; const zir_dir = cache_directory.handle; // Determine whether we need to reload the file from disk and redo parsing and AstGen. @@ -2688,7 +2705,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { { comp.mutex.lock(); defer comp.mutex.unlock(); - try mod.failed_files.putNoClobber(gpa, file, null); + try zcu.failed_files.putNoClobber(gpa, file, null); } file.status = .astgen_failure; return error.AnalysisFail; @@ -2712,7 +2729,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { else => |e| return e, }; - mod.lockAndClearFileCompileError(file); + zcu.lockAndClearFileCompileError(file); // If the previous ZIR does not have compile errors, keep it around // in case parsing or new ZIR fails. In case of successful ZIR update @@ -2818,27 +2835,27 @@ pub fn astGenFile(mod: *Module, file: *File) !void { { comp.mutex.lock(); defer comp.mutex.unlock(); - try mod.failed_files.putNoClobber(gpa, file, null); + try zcu.failed_files.putNoClobber(gpa, file, null); } file.status = .astgen_failure; return error.AnalysisFail; } if (file.prev_zir) |prev_zir| { - try updateZirRefs(mod, file, prev_zir.*); + try updateZirRefs(zcu, file, file_index, prev_zir.*); // No need to keep previous ZIR. prev_zir.deinit(gpa); gpa.destroy(prev_zir); file.prev_zir = null; } - if (file.root_decl.unwrap()) |root_decl| { + if (opt_root_decl.unwrap()) |root_decl| { // The root of this file must be re-analyzed, since the file has changed. comp.mutex.lock(); defer comp.mutex.unlock(); log.debug("outdated root Decl: {}", .{root_decl}); - try mod.outdated_file_root.put(gpa, root_decl, {}); + try zcu.outdated_file_root.put(gpa, root_decl, {}); } } @@ -2914,7 +2931,7 @@ fn loadZirCacheBody(gpa: Allocator, header: Zir.Header, cache_file: std.fs.File) /// This is called from the AstGen thread pool, so must acquire /// the Compilation mutex when acting on shared state. -fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir) !void { +fn updateZirRefs(zcu: *Module, file: *File, file_index: File.Index, old_zir: Zir) !void { const gpa = zcu.gpa; const new_zir = file.zir; @@ -2930,7 +2947,7 @@ fn updateZirRefs(zcu: *Module, file: *File, old_zir: Zir) !void { // iterating over this full set for every updated file. for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| { const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw); - if (!std.mem.eql(u8, &ti.path_digest, &file.path_digest)) continue; + if (ti.file != file_index) continue; const old_inst = ti.inst; ti.inst = inst_map.get(ti.inst) orelse { // Tracking failed for this instruction. Invalidate associated `src_hash` deps. @@ -3378,11 +3395,11 @@ pub fn mapOldZirToNew( } /// Like `ensureDeclAnalyzed`, but the Decl is a file's root Decl. -pub fn ensureFileAnalyzed(zcu: *Zcu, file: *File) SemaError!void { - if (file.root_decl.unwrap()) |existing_root| { +pub fn ensureFileAnalyzed(zcu: *Zcu, file_index: File.Index) SemaError!void { + if (zcu.fileRootDecl(file_index).unwrap()) |existing_root| { return zcu.ensureDeclAnalyzed(existing_root); } else { - return zcu.semaFile(file); + return zcu.semaFile(file_index); } } @@ -3455,7 +3472,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void { } if (mod.declIsRoot(decl_index)) { - const changed = try mod.semaFileUpdate(decl.getFileScope(mod), decl_was_outdated); + const changed = try mod.semaFileUpdate(decl.getFileScopeIndex(mod), decl_was_outdated); break :blk .{ .invalidate_decl_val = changed, .invalidate_decl_ref = changed, @@ -3787,17 +3804,23 @@ pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func_index: InternPool.Index) func.analysis(ip).state = .queued; } -/// https://github.com/ziglang/zig/issues/14307 -pub fn semaPkg(mod: *Module, pkg: *Package.Module) !void { - const file = (try mod.importPkg(pkg)).file; - if (file.root_decl == .none) { - return mod.semaFile(file); +pub fn semaPkg(zcu: *Zcu, pkg: *Package.Module) !void { + const import_file_result = try zcu.importPkg(pkg); + const root_decl_index = zcu.fileRootDecl(import_file_result.file_index); + if (root_decl_index == .none) { + return zcu.semaFile(import_file_result.file_index); } } -fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespace.Index, file: *File) Allocator.Error!InternPool.Index { +fn getFileRootStruct( + zcu: *Zcu, + decl_index: Decl.Index, + namespace_index: Namespace.Index, + file_index: File.Index, +) Allocator.Error!InternPool.Index { const gpa = zcu.gpa; const ip = &zcu.intern_pool; + const file = zcu.fileByIndex(file_index); const extended = file.zir.instructions.items(.data)[@intFromEnum(Zir.Inst.Index.main_struct_inst)].extended; assert(extended.opcode == .struct_decl); const small: Zir.Inst.StructDecl.Small = @bitCast(extended.small); @@ -3818,7 +3841,7 @@ fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespa const decls = file.zir.bodySlice(extra_index, decls_len); extra_index += decls_len; - const tracked_inst = try ip.trackZir(gpa, file, .main_struct_inst); + const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst); const wip_ty = switch (try ip.getStructType(gpa, .{ .layout = .auto, .fields_len = fields_len, @@ -3863,8 +3886,9 @@ fn getFileRootStruct(zcu: *Zcu, decl_index: Decl.Index, namespace_index: Namespa /// If `type_outdated`, the struct type itself is considered outdated and is /// reconstructed at a new InternPool index. Otherwise, the namespace is just /// re-analyzed. Returns whether the decl's tyval was invalidated. -fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool { - const decl = zcu.declPtr(file.root_decl.unwrap().?); +fn semaFileUpdate(zcu: *Zcu, file_index: File.Index, type_outdated: bool) SemaError!bool { + const file = zcu.fileByIndex(file_index); + const decl = zcu.declPtr(zcu.fileRootDecl(file_index).unwrap().?); log.debug("semaFileUpdate mod={s} sub_file_path={s} type_outdated={}", .{ file.mod.fully_qualified_name, @@ -3883,7 +3907,8 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool { if (decl.analysis == .file_failure) { // No struct type currently exists. Create one! - _ = try zcu.getFileRootStruct(file.root_decl.unwrap().?, decl.src_namespace, file); + const root_decl = zcu.fileRootDecl(file_index); + _ = try zcu.getFileRootStruct(root_decl.unwrap().?, decl.src_namespace, file_index); return true; } @@ -3892,10 +3917,13 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool { if (type_outdated) { // Invalidate the existing type, reusing the decl and namespace. - zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ .decl = file.root_decl.unwrap().? })); + const file_root_decl = zcu.fileRootDecl(file_index).unwrap().?; + zcu.intern_pool.removeDependenciesForDepender(zcu.gpa, AnalUnit.wrap(.{ + .decl = file_root_decl, + })); zcu.intern_pool.remove(decl.val.toIntern()); decl.val = undefined; - _ = try zcu.getFileRootStruct(file.root_decl.unwrap().?, decl.src_namespace, file); + _ = try zcu.getFileRootStruct(file_root_decl, decl.src_namespace, file_index); return true; } @@ -3923,35 +3951,36 @@ fn semaFileUpdate(zcu: *Zcu, file: *File, type_outdated: bool) SemaError!bool { /// Regardless of the file status, will create a `Decl` if none exists so that we can track /// dependencies and re-analyze when the file becomes outdated. -fn semaFile(mod: *Module, file: *File) SemaError!void { +fn semaFile(zcu: *Zcu, file_index: File.Index) SemaError!void { const tracy = trace(@src()); defer tracy.end(); - assert(file.root_decl == .none); + const file = zcu.fileByIndex(file_index); + assert(zcu.fileRootDecl(file_index) == .none); - const gpa = mod.gpa; - log.debug("semaFile mod={s} sub_file_path={s}", .{ + const gpa = zcu.gpa; + log.debug("semaFile zcu={s} sub_file_path={s}", .{ file.mod.fully_qualified_name, file.sub_file_path, }); // Because these three things each reference each other, `undefined` // placeholders are used before being set after the struct type gains an // InternPool index. - const new_namespace_index = try mod.createNamespace(.{ + const new_namespace_index = try zcu.createNamespace(.{ .parent = .none, .decl_index = undefined, - .file_scope = file, + .file_scope = file_index, }); - errdefer mod.destroyNamespace(new_namespace_index); + errdefer zcu.destroyNamespace(new_namespace_index); - const new_decl_index = try mod.allocateNewDecl(new_namespace_index); - const new_decl = mod.declPtr(new_decl_index); + const new_decl_index = try zcu.allocateNewDecl(new_namespace_index); + const new_decl = zcu.declPtr(new_decl_index); errdefer @panic("TODO error handling"); - file.root_decl = new_decl_index.toOptional(); - mod.namespacePtr(new_namespace_index).decl_index = new_decl_index; + zcu.setFileRootDecl(file_index, new_decl_index.toOptional()); + zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index; - new_decl.name = try file.fullyQualifiedName(mod); + new_decl.name = try file.fullyQualifiedName(zcu); new_decl.name_fully_qualified = true; new_decl.is_pub = true; new_decl.is_exported = false; @@ -3965,13 +3994,13 @@ fn semaFile(mod: *Module, file: *File) SemaError!void { } assert(file.zir_loaded); - const struct_ty = try mod.getFileRootStruct(new_decl_index, new_namespace_index, file); - errdefer mod.intern_pool.remove(struct_ty); + const struct_ty = try zcu.getFileRootStruct(new_decl_index, new_namespace_index, file_index); + errdefer zcu.intern_pool.remove(struct_ty); - switch (mod.comp.cache_use) { + switch (zcu.comp.cache_use) { .whole => |whole| if (whole.cache_manifest) |man| { const source = file.getSource(gpa) catch |err| { - try reportRetryableFileError(mod, file, "unable to load source: {s}", .{@errorName(err)}); + try reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)}); return error.AnalysisFail; }; @@ -3980,7 +4009,7 @@ fn semaFile(mod: *Module, file: *File) SemaError!void { file.mod.root.sub_path, file.sub_file_path, }) catch |err| { - try reportRetryableFileError(mod, file, "unable to resolve path: {s}", .{@errorName(err)}); + try reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)}); return error.AnalysisFail; }; errdefer gpa.free(resolved_path); @@ -4000,57 +4029,58 @@ const SemaDeclResult = packed struct { invalidate_decl_ref: bool, }; -fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { +fn semaDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult { const tracy = trace(@src()); defer tracy.end(); - const decl = mod.declPtr(decl_index); - const ip = &mod.intern_pool; + const decl = zcu.declPtr(decl_index); + const ip = &zcu.intern_pool; - if (decl.getFileScope(mod).status != .success_zir) { + if (decl.getFileScope(zcu).status != .success_zir) { return error.AnalysisFail; } - assert(!mod.declIsRoot(decl_index)); + assert(!zcu.declIsRoot(decl_index)); if (decl.zir_decl_index == .none and decl.owns_tv) { // We are re-analyzing an anonymous owner Decl (for a function or a namespace type). - return mod.semaAnonOwnerDecl(decl_index); + return zcu.semaAnonOwnerDecl(decl_index); } log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)}); - log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(mod)).fmt(ip)}); + log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(zcu)).fmt(ip)}); defer blk: { - log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(mod) catch break :blk).fmt(ip)}); + log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(zcu) catch break :blk).fmt(ip)}); } const old_has_tv = decl.has_tv; // The following values are ignored if `!old_has_tv` - const old_ty = if (old_has_tv) decl.typeOf(mod) else undefined; + const old_ty = if (old_has_tv) decl.typeOf(zcu) else undefined; const old_val = decl.val; const old_align = decl.alignment; const old_linksection = decl.@"linksection"; const old_addrspace = decl.@"addrspace"; - const old_is_inline = if (decl.getOwnedFunction(mod)) |prev_func| + const old_is_inline = if (decl.getOwnedFunction(zcu)) |prev_func| prev_func.analysis(ip).state == .inline_only else false; const decl_inst = decl.zir_decl_index.unwrap().?.resolve(ip); - const gpa = mod.gpa; - const zir = decl.getFileScope(mod).zir; + const gpa = zcu.gpa; + const zir = decl.getFileScope(zcu).zir; const builtin_type_target_index: InternPool.Index = ip_index: { - const std_mod = mod.std_mod; - if (decl.getFileScope(mod).mod != std_mod) break :ip_index .none; + const std_mod = zcu.std_mod; + if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none; // We're in the std module. - const std_file = (try mod.importPkg(std_mod)).file; - const std_decl = mod.declPtr(std_file.root_decl.unwrap().?); - const std_namespace = std_decl.getInnerNamespace(mod).?; + const std_file_imported = try zcu.importPkg(std_mod); + const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index); + const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?); + const std_namespace = std_decl.getInnerNamespace(zcu).?; const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls); - const builtin_decl = mod.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .zcu = mod }) orelse break :ip_index .none); - const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :ip_index .none; + const builtin_decl = zcu.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .zcu = zcu }) orelse break :ip_index .none); + const builtin_namespace = builtin_decl.getInnerNamespaceIndex(zcu).unwrap() orelse break :ip_index .none; if (decl.src_namespace != builtin_namespace) break :ip_index .none; // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index. for ([_][]const u8{ @@ -4083,7 +4113,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { break :ip_index .none; }; - mod.intern_pool.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .decl = decl_index })); + zcu.intern_pool.removeDependenciesForDepender(gpa, AnalUnit.wrap(.{ .decl = decl_index })); decl.analysis = .in_progress; @@ -4094,7 +4124,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { defer comptime_err_ret_trace.deinit(); var sema: Sema = .{ - .mod = mod, + .mod = zcu, .gpa = gpa, .arena = analysis_arena.allocator(), .code = zir, @@ -4112,8 +4142,8 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source. try sema.declareDependency(.{ .src_hash = try ip.trackZir( - sema.gpa, - decl.getFileScope(mod), + gpa, + decl.getFileScopeIndex(zcu), decl_inst, ) }); @@ -4129,7 +4159,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { }; defer block_scope.instructions.deinit(gpa); - const decl_bodies = decl.zirBodies(mod); + const decl_bodies = decl.zirBodies(zcu); const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst); // We'll do some other bits with the Sema. Clear the type target index just @@ -4141,22 +4171,22 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { const ty_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_ty = 0 }); const init_src: LazySrcLoc = block_scope.src(.{ .node_offset_var_decl_init = 0 }); const decl_val = try sema.resolveFinalDeclValue(&block_scope, init_src, result_ref); - const decl_ty = decl_val.typeOf(mod); + const decl_ty = decl_val.typeOf(zcu); // Note this resolves the type of the Decl, not the value; if this Decl // is a struct, for example, this resolves `type` (which needs no resolution), // not the struct itself. - try decl_ty.resolveLayout(mod); + try decl_ty.resolveLayout(zcu); if (decl.kind == .@"usingnamespace") { - if (!decl_ty.eql(Type.type, mod)) { + if (!decl_ty.eql(Type.type, zcu)) { return sema.fail(&block_scope, ty_src, "expected type, found {}", .{ - decl_ty.fmt(mod), + decl_ty.fmt(zcu), }); } const ty = decl_val.toType(); - if (ty.getNamespace(mod) == null) { - return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)}); + if (ty.getNamespace(zcu) == null) { + return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(zcu)}); } decl.val = ty.toValue(); @@ -4194,7 +4224,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { .func => |func| { decl.owns_tv = func.owner_decl == decl_index; queue_linker_work = false; - is_inline = decl.owns_tv and decl_ty.fnCallingConvention(mod) == .Inline; + is_inline = decl.owns_tv and decl_ty.fnCallingConvention(zcu) == .Inline; is_func = decl.owns_tv; }, @@ -4246,10 +4276,10 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { decl.analysis = .complete; const result: SemaDeclResult = if (old_has_tv) .{ - .invalidate_decl_val = !decl_ty.eql(old_ty, mod) or - !decl.val.eql(old_val, decl_ty, mod) or + .invalidate_decl_val = !decl_ty.eql(old_ty, zcu) or + !decl.val.eql(old_val, decl_ty, zcu) or is_inline != old_is_inline, - .invalidate_decl_ref = !decl_ty.eql(old_ty, mod) or + .invalidate_decl_ref = !decl_ty.eql(old_ty, zcu) or decl.alignment != old_align or decl.@"linksection" != old_linksection or decl.@"addrspace" != old_addrspace or @@ -4263,12 +4293,12 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !SemaDeclResult { if (has_runtime_bits) { // Needed for codegen_decl which will call updateDecl and then the // codegen backend wants full access to the Decl Type. - try decl_ty.resolveFully(mod); + try decl_ty.resolveFully(zcu); - try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); + try zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); - if (result.invalidate_decl_ref and mod.emit_h != null) { - try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index }); + if (result.invalidate_decl_ref and zcu.emit_h != null) { + try zcu.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index }); } } @@ -4322,6 +4352,7 @@ fn semaAnonOwnerDecl(zcu: *Zcu, decl_index: Decl.Index) !SemaDeclResult { pub const ImportFileResult = struct { file: *File, + file_index: File.Index, is_new: bool, is_pkg: bool, }; @@ -4344,20 +4375,27 @@ pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult { errdefer _ = zcu.import_table.pop(); if (gop.found_existing) { try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod }); - return ImportFileResult{ + return .{ .file = gop.value_ptr.*, + .file_index = @enumFromInt(gop.index), .is_new = false, .is_pkg = true, }; } + const ip = &zcu.intern_pool; + + try ip.files.ensureUnusedCapacity(gpa, 1); + if (mod.builtin_file) |builtin_file| { keep_resolved_path = true; // It's now owned by import_table. gop.value_ptr.* = builtin_file; try builtin_file.addReference(zcu.*, .{ .root = mod }); - try zcu.path_digest_map.put(gpa, builtin_file.path_digest, {}); + const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path); + ip.files.putAssumeCapacityNoClobber(path_digest, .none); return .{ .file = builtin_file, + .file_index = @enumFromInt(ip.files.entries.len - 1), .is_new = false, .is_pkg = true, }; @@ -4382,43 +4420,36 @@ pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult { .zir = undefined, .status = .never_loaded, .mod = mod, - .root_decl = .none, - .path_digest = digest: { - const want_local_cache = mod == zcu.main_mod; - var path_hash: Cache.HashHelper = .{}; - path_hash.addBytes(build_options.version); - path_hash.add(builtin.zig_backend); - if (!want_local_cache) { - path_hash.addOptionalBytes(mod.root.root_dir.path); - path_hash.addBytes(mod.root.sub_path); - } - path_hash.addBytes(sub_file_path); - var bin: Cache.BinDigest = undefined; - path_hash.hasher.final(&bin); - break :digest bin; - }, }; + + const path_digest = computePathDigest(zcu, mod, sub_file_path); + try new_file.addReference(zcu.*, .{ .root = mod }); - try zcu.path_digest_map.put(gpa, new_file.path_digest, {}); - return ImportFileResult{ + ip.files.putAssumeCapacityNoClobber(path_digest, .none); + return .{ .file = new_file, + .file_index = @enumFromInt(ip.files.entries.len - 1), .is_new = true, .is_pkg = true, }; } +/// Called from a worker thread during AstGen. +/// Also called from Sema during semantic analysis. pub fn importFile( zcu: *Zcu, cur_file: *File, import_string: []const u8, ) !ImportFileResult { + const mod = cur_file.mod; + if (std.mem.eql(u8, import_string, "std")) { return zcu.importPkg(zcu.std_mod); } if (std.mem.eql(u8, import_string, "root")) { return zcu.importPkg(zcu.root_mod); } - if (cur_file.mod.deps.get(import_string)) |pkg| { + if (mod.deps.get(import_string)) |pkg| { return zcu.importPkg(pkg); } if (!mem.endsWith(u8, import_string, ".zig")) { @@ -4430,8 +4461,8 @@ pub fn importFile( // an import refers to the same as another, despite different relative paths // or differently mapped package names. const resolved_path = try std.fs.path.resolve(gpa, &.{ - cur_file.mod.root.root_dir.path orelse ".", - cur_file.mod.root.sub_path, + mod.root.root_dir.path orelse ".", + mod.root.sub_path, cur_file.sub_file_path, "..", import_string, @@ -4442,18 +4473,23 @@ pub fn importFile( const gop = try zcu.import_table.getOrPut(gpa, resolved_path); errdefer _ = zcu.import_table.pop(); - if (gop.found_existing) return ImportFileResult{ + if (gop.found_existing) return .{ .file = gop.value_ptr.*, + .file_index = @enumFromInt(gop.index), .is_new = false, .is_pkg = false, }; + const ip = &zcu.intern_pool; + + try ip.files.ensureUnusedCapacity(gpa, 1); + const new_file = try gpa.create(File); errdefer gpa.destroy(new_file); const resolved_root_path = try std.fs.path.resolve(gpa, &.{ - cur_file.mod.root.root_dir.path orelse ".", - cur_file.mod.root.sub_path, + mod.root.root_dir.path orelse ".", + mod.root.sub_path, }); defer gpa.free(resolved_root_path); @@ -4484,26 +4520,14 @@ pub fn importFile( .tree = undefined, .zir = undefined, .status = .never_loaded, - .mod = cur_file.mod, - .root_decl = .none, - .path_digest = digest: { - const want_local_cache = cur_file.mod == zcu.main_mod; - var path_hash: Cache.HashHelper = .{}; - path_hash.addBytes(build_options.version); - path_hash.add(builtin.zig_backend); - if (!want_local_cache) { - path_hash.addOptionalBytes(cur_file.mod.root.root_dir.path); - path_hash.addBytes(cur_file.mod.root.sub_path); - } - path_hash.addBytes(sub_file_path); - var bin: Cache.BinDigest = undefined; - path_hash.hasher.final(&bin); - break :digest bin; - }, + .mod = mod, }; - try zcu.path_digest_map.put(gpa, new_file.path_digest, {}); - return ImportFileResult{ + + const path_digest = computePathDigest(zcu, mod, sub_file_path); + ip.files.putAssumeCapacityNoClobber(path_digest, .none); + return .{ .file = new_file, + .file_index = @enumFromInt(ip.files.entries.len - 1), .is_new = true, .is_pkg = false, }; @@ -4581,6 +4605,21 @@ pub fn embedFile( return newEmbedFile(mod, cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc); } +fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest { + const want_local_cache = mod == zcu.main_mod; + var path_hash: Cache.HashHelper = .{}; + path_hash.addBytes(build_options.version); + path_hash.add(builtin.zig_backend); + if (!want_local_cache) { + path_hash.addOptionalBytes(mod.root.root_dir.path); + path_hash.addBytes(mod.root.sub_path); + } + path_hash.addBytes(sub_file_path); + var bin: Cache.BinDigest = undefined; + path_hash.hasher.final(&bin); + return bin; +} + /// https://github.com/ziglang/zig/issues/14307 fn newEmbedFile( mod: *Module, @@ -4765,7 +4804,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void const namespace_index = iter.namespace_index; const namespace = zcu.namespacePtr(namespace_index); const gpa = zcu.gpa; - const zir = namespace.file_scope.zir; + const zir = namespace.fileScope(zcu).zir; const ip = &zcu.intern_pool; const inst_data = zir.instructions.items(.data)[@intFromEnum(decl_inst)].declaration; @@ -4848,7 +4887,8 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void else => {}, } - const tracked_inst = try ip.trackZir(gpa, iter.parent_decl.getFileScope(zcu), decl_inst); + const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu); + const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst); // We create a Decl for it regardless of analysis status. @@ -4878,7 +4918,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void namespace.decls.putAssumeCapacityNoClobberContext(decl_index, {}, .{ .zcu = zcu }); const comp = zcu.comp; - const decl_mod = namespace.file_scope.mod; + const decl_mod = namespace.fileScope(zcu).mod; const want_analysis = declaration.flags.is_export or switch (kind) { .anon => unreachable, .@"comptime" => true, @@ -4908,7 +4948,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_inst: Zir.Inst.Index) Allocator.Error!void // re-analysis for us if necessary. if (prev_exported != declaration.flags.is_export or decl.analysis == .unreferenced) { log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{}' decl_index={d}", .{ - namespace.file_scope.sub_file_path, decl_name.fmt(ip), decl_index, + namespace.fileScope(zcu).sub_file_path, decl_name.fmt(ip), decl_index, }); comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = decl_index }); } @@ -5512,77 +5552,78 @@ fn handleUpdateExports( } pub fn populateTestFunctions( - mod: *Module, + zcu: *Zcu, main_progress_node: std.Progress.Node, ) !void { - const gpa = mod.gpa; - const ip = &mod.intern_pool; - const builtin_mod = mod.root_mod.getBuiltinDependency(); - const builtin_file = (mod.importPkg(builtin_mod) catch unreachable).file; - const root_decl = mod.declPtr(builtin_file.root_decl.unwrap().?); - const builtin_namespace = mod.namespacePtr(root_decl.src_namespace); + const gpa = zcu.gpa; + const ip = &zcu.intern_pool; + const builtin_mod = zcu.root_mod.getBuiltinDependency(); + const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index; + const root_decl_index = zcu.fileRootDecl(builtin_file_index); + const root_decl = zcu.declPtr(root_decl_index.unwrap().?); + const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace); const test_functions_str = try ip.getOrPutString(gpa, "test_functions", .no_embedded_nulls); const decl_index = builtin_namespace.decls.getKeyAdapted( test_functions_str, - DeclAdapter{ .zcu = mod }, + DeclAdapter{ .zcu = zcu }, ).?; { // We have to call `ensureDeclAnalyzed` here in case `builtin.test_functions` // was not referenced by start code. - mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); + zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); defer { - mod.sema_prog_node.end(); - mod.sema_prog_node = undefined; + zcu.sema_prog_node.end(); + zcu.sema_prog_node = undefined; } - try mod.ensureDeclAnalyzed(decl_index); + try zcu.ensureDeclAnalyzed(decl_index); } - const decl = mod.declPtr(decl_index); - const test_fn_ty = decl.typeOf(mod).slicePtrFieldType(mod).childType(mod); + const decl = zcu.declPtr(decl_index); + const test_fn_ty = decl.typeOf(zcu).slicePtrFieldType(zcu).childType(zcu); const array_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = array: { - // Add mod.test_functions to an array decl then make the test_functions + // Add zcu.test_functions to an array decl then make the test_functions // decl reference it as a slice. - const test_fn_vals = try gpa.alloc(InternPool.Index, mod.test_functions.count()); + const test_fn_vals = try gpa.alloc(InternPool.Index, zcu.test_functions.count()); defer gpa.free(test_fn_vals); - for (test_fn_vals, mod.test_functions.keys()) |*test_fn_val, test_decl_index| { - const test_decl = mod.declPtr(test_decl_index); - const test_decl_name = try test_decl.fullyQualifiedName(mod); + for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| { + const test_decl = zcu.declPtr(test_decl_index); + const test_decl_name = try test_decl.fullyQualifiedName(zcu); const test_decl_name_len = test_decl_name.length(ip); const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: { - const test_name_ty = try mod.arrayType(.{ + const test_name_ty = try zcu.arrayType(.{ .len = test_decl_name_len, .child = .u8_type, }); - const test_name_val = try mod.intern(.{ .aggregate = .{ + const test_name_val = try zcu.intern(.{ .aggregate = .{ .ty = test_name_ty.toIntern(), .storage = .{ .bytes = test_decl_name.toString() }, } }); break :n .{ - .orig_ty = (try mod.singleConstPtrType(test_name_ty)).toIntern(), + .orig_ty = (try zcu.singleConstPtrType(test_name_ty)).toIntern(), .val = test_name_val, }; }; const test_fn_fields = .{ // name - try mod.intern(.{ .slice = .{ + try zcu.intern(.{ .slice = .{ .ty = .slice_const_u8_type, - .ptr = try mod.intern(.{ .ptr = .{ + .ptr = try zcu.intern(.{ .ptr = .{ .ty = .manyptr_const_u8_type, .base_addr = .{ .anon_decl = test_name_anon_decl }, .byte_offset = 0, } }), - .len = try mod.intern(.{ .int = .{ + .len = try zcu.intern(.{ .int = .{ .ty = .usize_type, .storage = .{ .u64 = test_decl_name_len }, } }), } }), // func - try mod.intern(.{ .ptr = .{ - .ty = try mod.intern(.{ .ptr_type = .{ - .child = test_decl.typeOf(mod).toIntern(), + try zcu.intern(.{ .ptr = .{ + .ty = try zcu.intern(.{ .ptr_type = .{ + .child = test_decl.typeOf(zcu).toIntern(), .flags = .{ .is_const = true, }, @@ -5591,29 +5632,29 @@ pub fn populateTestFunctions( .byte_offset = 0, } }), }; - test_fn_val.* = try mod.intern(.{ .aggregate = .{ + test_fn_val.* = try zcu.intern(.{ .aggregate = .{ .ty = test_fn_ty.toIntern(), .storage = .{ .elems = &test_fn_fields }, } }); } - const array_ty = try mod.arrayType(.{ + const array_ty = try zcu.arrayType(.{ .len = test_fn_vals.len, .child = test_fn_ty.toIntern(), .sentinel = .none, }); - const array_val = try mod.intern(.{ .aggregate = .{ + const array_val = try zcu.intern(.{ .aggregate = .{ .ty = array_ty.toIntern(), .storage = .{ .elems = test_fn_vals }, } }); break :array .{ - .orig_ty = (try mod.singleConstPtrType(array_ty)).toIntern(), + .orig_ty = (try zcu.singleConstPtrType(array_ty)).toIntern(), .val = array_val, }; }; { - const new_ty = try mod.ptrType(.{ + const new_ty = try zcu.ptrType(.{ .child = test_fn_ty.toIntern(), .flags = .{ .is_const = true, @@ -5621,14 +5662,14 @@ pub fn populateTestFunctions( }, }); const new_val = decl.val; - const new_init = try mod.intern(.{ .slice = .{ + const new_init = try zcu.intern(.{ .slice = .{ .ty = new_ty.toIntern(), - .ptr = try mod.intern(.{ .ptr = .{ - .ty = new_ty.slicePtrFieldType(mod).toIntern(), + .ptr = try zcu.intern(.{ .ptr = .{ + .ty = new_ty.slicePtrFieldType(zcu).toIntern(), .base_addr = .{ .anon_decl = array_anon_decl }, .byte_offset = 0, } }), - .len = (try mod.intValue(Type.usize, mod.test_functions.count())).toIntern(), + .len = (try zcu.intValue(Type.usize, zcu.test_functions.count())).toIntern(), } }); ip.mutateVarInit(decl.val.toIntern(), new_init); @@ -5638,13 +5679,13 @@ pub fn populateTestFunctions( decl.has_tv = true; } { - mod.codegen_prog_node = main_progress_node.start("Code Generation", 0); + zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0); defer { - mod.codegen_prog_node.end(); - mod.codegen_prog_node = undefined; + zcu.codegen_prog_node.end(); + zcu.codegen_prog_node = undefined; } - try mod.linkerUpdateDecl(decl_index); + try zcu.linkerUpdateDecl(decl_index); } } @@ -5684,31 +5725,35 @@ pub fn linkerUpdateDecl(zcu: *Zcu, decl_index: Decl.Index) !void { } fn reportRetryableFileError( - mod: *Module, - file: *File, + zcu: *Zcu, + file_index: File.Index, comptime format: []const u8, args: anytype, ) error{OutOfMemory}!void { + const gpa = zcu.gpa; + const ip = &zcu.intern_pool; + + const file = zcu.fileByIndex(file_index); file.status = .retryable_failure; const err_msg = try ErrorMsg.create( - mod.gpa, + gpa, .{ - .base_node_inst = try mod.intern_pool.trackZir(mod.gpa, file, .main_struct_inst), + .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst), .offset = .entire_file, }, format, args, ); - errdefer err_msg.destroy(mod.gpa); + errdefer err_msg.destroy(gpa); - mod.comp.mutex.lock(); - defer mod.comp.mutex.unlock(); + zcu.comp.mutex.lock(); + defer zcu.comp.mutex.unlock(); - const gop = try mod.failed_files.getOrPut(mod.gpa, file); + const gop = try zcu.failed_files.getOrPut(gpa, file); if (gop.found_existing) { if (gop.value_ptr.*) |old_err_msg| { - old_err_msg.destroy(mod.gpa); + old_err_msg.destroy(gpa); } } gop.value_ptr.* = err_msg; @@ -6528,8 +6573,9 @@ pub fn getBuiltin(zcu: *Zcu, name: []const u8) Allocator.Error!Air.Inst.Ref { pub fn getBuiltinDecl(zcu: *Zcu, name: []const u8) Allocator.Error!InternPool.DeclIndex { const gpa = zcu.gpa; const ip = &zcu.intern_pool; - const std_file = (zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig")).file; - const std_namespace = zcu.declPtr(std_file.root_decl.unwrap().?).getOwnedInnerNamespace(zcu).?; + const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig"); + const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?; + const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?; const builtin_str = try ip.getOrPutString(gpa, "builtin", .no_embedded_nulls); const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Zcu.DeclAdapter{ .zcu = zcu }) orelse @panic("lib/std.zig is corrupt and missing 'builtin'"); zcu.ensureDeclAnalyzed(builtin_decl) catch @panic("std.builtin is corrupt"); @@ -6544,3 +6590,23 @@ pub fn getBuiltinType(zcu: *Zcu, name: []const u8) Allocator.Error!Type { ty.resolveFully(zcu) catch @panic("std.builtin is corrupt"); return ty; } + +pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File { + return zcu.import_table.values()[@intFromEnum(i)]; +} + +/// Returns the `Decl` of the struct that represents this `File`. +pub fn fileRootDecl(zcu: *const Zcu, i: File.Index) Decl.OptionalIndex { + const ip = &zcu.intern_pool; + return ip.files.values()[@intFromEnum(i)]; +} + +pub fn setFileRootDecl(zcu: *Zcu, i: File.Index, root_decl: Decl.OptionalIndex) void { + const ip = &zcu.intern_pool; + ip.files.values()[@intFromEnum(i)] = root_decl; +} + +pub fn filePathDigest(zcu: *const Zcu, i: File.Index) Cache.BinDigest { + const ip = &zcu.intern_pool; + return ip.files.keys()[@intFromEnum(i)]; +} diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 14b9cce3a8..023c86dfb8 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -345,7 +345,7 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.typeOf(zcu); const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const target = &namespace.file_scope.mod.resolved_target.result; + const target = &namespace.fileScope(zcu).mod.resolved_target.result; var branch_stack = std.ArrayList(Branch).init(gpa); defer { diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 0423b63d23..3f10513bb2 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -352,7 +352,7 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.typeOf(zcu); const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const target = &namespace.file_scope.mod.resolved_target.result; + const target = &namespace.fileScope(zcu).mod.resolved_target.result; var branch_stack = std.ArrayList(Branch).init(gpa); defer { diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 3f01b74733..2faddc22e8 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -712,8 +712,8 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.typeOf(zcu); const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const target = &namespace.file_scope.mod.resolved_target.result; - const mod = namespace.file_scope.mod; + const target = &namespace.fileScope(zcu).mod.resolved_target.result; + const mod = namespace.fileScope(zcu).mod; var branch_stack = std.ArrayList(Branch).init(gpa); defer { diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index 2416eb9176..b837eb9ade 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -277,7 +277,7 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.typeOf(zcu); const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const target = &namespace.file_scope.mod.resolved_target.result; + const target = &namespace.fileScope(zcu).mod.resolved_target.result; var branch_stack = std.ArrayList(Branch).init(gpa); defer { diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 2ecface64e..2f2e35a75b 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1212,11 +1212,11 @@ pub fn generate( _ = src_loc; const comp = bin_file.comp; const gpa = comp.gpa; - const mod = comp.module.?; - const func = mod.funcInfo(func_index); - const decl = mod.declPtr(func.owner_decl); - const namespace = mod.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.resolved_target.result; + const zcu = comp.module.?; + const func = zcu.funcInfo(func_index); + const decl = zcu.declPtr(func.owner_decl); + const namespace = zcu.namespacePtr(decl.src_namespace); + const target = namespace.fileScope(zcu).mod.resolved_target.result; var code_gen: CodeGen = .{ .gpa = gpa, .air = air, @@ -7706,7 +7706,7 @@ fn airFence(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { // for a single-threaded build, can we emit the `fence` instruction. // In all other cases, we emit no instructions for a fence. const func_namespace = zcu.namespacePtr(func.decl.src_namespace); - const single_threaded = func_namespace.file_scope.mod.single_threaded; + const single_threaded = func_namespace.fileScope(zcu).mod.single_threaded; if (func.useAtomicFeature() and !single_threaded) { try func.addAtomicTag(.atomic_fence); } diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index def0edcac9..538b740042 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -810,7 +810,7 @@ pub fn generate( assert(fn_owner_decl.has_tv); const fn_type = fn_owner_decl.typeOf(zcu); const namespace = zcu.namespacePtr(fn_owner_decl.src_namespace); - const mod = namespace.file_scope.mod; + const mod = namespace.fileScope(zcu).mod; var function = Self{ .gpa = gpa, diff --git a/src/codegen.zig b/src/codegen.zig index 5e25359d44..059b4fa7d4 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -58,7 +58,7 @@ pub fn generateFunction( const func = zcu.funcInfo(func_index); const decl = zcu.declPtr(func.owner_decl); const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.resolved_target.result; + const target = namespace.fileScope(zcu).mod.resolved_target.result; switch (target.cpu.arch) { .arm, .armeb, @@ -88,7 +88,7 @@ pub fn generateLazyFunction( const decl_index = lazy_sym.ty.getOwnerDecl(zcu); const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.resolved_target.result; + const target = namespace.fileScope(zcu).mod.resolved_target.result; switch (target.cpu.arch) { .x86_64 => return @import("arch/x86_64/CodeGen.zig").generateLazy(lf, src_loc, lazy_sym, code, debug_output), else => unreachable, @@ -742,7 +742,7 @@ fn lowerDeclRef( const zcu = lf.comp.module.?; const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.resolved_target.result; + const target = namespace.fileScope(zcu).mod.resolved_target.result; const ptr_width = target.ptrBitWidth(); const is_fn_body = decl.typeOf(zcu).zigTypeTag(zcu) == .Fn; @@ -836,7 +836,7 @@ fn genDeclRef( const ptr_decl = zcu.declPtr(ptr_decl_index); const namespace = zcu.namespacePtr(ptr_decl.src_namespace); - const target = namespace.file_scope.mod.resolved_target.result; + const target = namespace.fileScope(zcu).mod.resolved_target.result; const ptr_bits = target.ptrBitWidth(); const ptr_bytes: u64 = @divExact(ptr_bits, 8); @@ -875,7 +875,7 @@ fn genDeclRef( } const decl_namespace = zcu.namespacePtr(decl.src_namespace); - const single_threaded = decl_namespace.file_scope.mod.single_threaded; + const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded; const is_threadlocal = val.isPtrToThreadLocal(zcu) and !single_threaded; const is_extern = decl.isExtern(zcu); @@ -985,7 +985,7 @@ pub fn genTypedValue( const owner_decl = zcu.declPtr(owner_decl_index); const namespace = zcu.namespacePtr(owner_decl.src_namespace); - const target = namespace.file_scope.mod.resolved_target.result; + const target = namespace.fileScope(zcu).mod.resolved_target.result; const ptr_bits = target.ptrBitWidth(); if (!ty.isSlice(zcu)) switch (ip.indexToKey(val.toIntern())) { diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 92e9edb433..2fd3d2b164 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -2581,7 +2581,7 @@ pub fn genTypeDecl( _ = try renderTypePrefix(.flush, global_ctype_pool, zcu, writer, global_ctype, .suffix, .{}); try writer.writeByte(';'); const owner_decl = zcu.declPtr(owner_decl_index); - const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).file_scope.mod; + const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu).mod; if (!owner_mod.strip) { try writer.writeAll(" /* "); try owner_decl.renderFullyQualifiedName(zcu, writer); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 02933929c8..6efef20f22 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1362,7 +1362,8 @@ pub const Object = struct { const decl_index = func.owner_decl; const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const owner_mod = namespace.file_scope.mod; + const file_scope = namespace.fileScope(zcu); + const owner_mod = file_scope.mod; const fn_info = zcu.typeToFunc(decl.typeOf(zcu)).?; const target = owner_mod.resolved_target.result; const ip = &zcu.intern_pool; @@ -1633,7 +1634,7 @@ pub const Object = struct { function_index.setAttributes(try attributes.finish(&o.builder), &o.builder); const file, const subprogram = if (!wip.strip) debug_info: { - const file = try o.getDebugFile(namespace.file_scope); + const file = try o.getDebugFile(file_scope); const line_number = decl.navSrcLine(zcu) + 1; const is_internal_linkage = decl.val.getExternFunc(zcu) == null; @@ -1720,23 +1721,23 @@ pub const Object = struct { pub fn updateExports( self: *Object, - mod: *Module, + zcu: *Zcu, exported: Module.Exported, export_indices: []const u32, ) link.File.UpdateExportsError!void { const decl_index = switch (exported) { .decl_index => |i| i, - .value => |val| return updateExportedValue(self, mod, val, export_indices), + .value => |val| return updateExportedValue(self, zcu, val, export_indices), }; - const ip = &mod.intern_pool; + const ip = &zcu.intern_pool; const global_index = self.decl_map.get(decl_index).?; - const decl = mod.declPtr(decl_index); - const comp = mod.comp; + const decl = zcu.declPtr(decl_index); + const comp = zcu.comp; if (export_indices.len != 0) { - return updateExportedGlobal(self, mod, global_index, export_indices); + return updateExportedGlobal(self, zcu, global_index, export_indices); } else { - const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(mod)).toSlice(ip)); + const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(zcu)).toSlice(ip)); try global_index.rename(fqn, &self.builder); global_index.setLinkage(.internal, &self.builder); if (comp.config.dll_export_fns) @@ -1908,12 +1909,12 @@ pub const Object = struct { const gpa = o.gpa; const target = o.target; - const mod = o.module; - const ip = &mod.intern_pool; + const zcu = o.module; + const ip = &zcu.intern_pool; if (o.debug_type_map.get(ty)) |debug_type| return debug_type; - switch (ty.zigTypeTag(mod)) { + switch (ty.zigTypeTag(zcu)) { .Void, .NoReturn, => { @@ -1925,12 +1926,12 @@ pub const Object = struct { return debug_void_type; }, .Int => { - const info = ty.intInfo(mod); + const info = ty.intInfo(zcu); assert(info.bits != 0); const name = try o.allocTypeName(ty); defer gpa.free(name); const builder_name = try o.builder.metadataString(name); - const debug_bits = ty.abiSize(mod) * 8; // lldb cannot handle non-byte sized types + const debug_bits = ty.abiSize(zcu) * 8; // lldb cannot handle non-byte sized types const debug_int_type = switch (info.signedness) { .signed => try o.builder.debugSignedType(builder_name, debug_bits), .unsigned => try o.builder.debugUnsignedType(builder_name, debug_bits), @@ -1939,10 +1940,10 @@ pub const Object = struct { return debug_int_type; }, .Enum => { - const owner_decl_index = ty.getOwnerDecl(mod); + const owner_decl_index = ty.getOwnerDecl(zcu); const owner_decl = o.module.declPtr(owner_decl_index); - if (!ty.hasRuntimeBitsIgnoreComptime(mod)) { + if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { const debug_enum_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); try o.debug_type_map.put(gpa, ty, debug_enum_type); return debug_enum_type; @@ -1954,13 +1955,13 @@ pub const Object = struct { defer gpa.free(enumerators); const int_ty = Type.fromInterned(enum_type.tag_ty); - const int_info = ty.intInfo(mod); + const int_info = ty.intInfo(zcu); assert(int_info.bits != 0); for (enum_type.names.get(ip), 0..) |field_name_ip, i| { var bigint_space: Value.BigIntSpace = undefined; const bigint = if (enum_type.values.len != 0) - Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, mod) + Value.fromInterned(enum_type.values.get(ip)[i]).toBigInt(&bigint_space, zcu) else std.math.big.int.Mutable.init(&bigint_space.limbs, i).toConst(); @@ -1972,7 +1973,8 @@ pub const Object = struct { ); } - const file = try o.getDebugFile(mod.namespacePtr(owner_decl.src_namespace).file_scope); + const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu); + const file = try o.getDebugFile(file_scope); const scope = try o.namespaceToDebugScope(owner_decl.src_namespace); const name = try o.allocTypeName(ty); @@ -1982,10 +1984,10 @@ pub const Object = struct { try o.builder.metadataString(name), file, scope, - owner_decl.typeSrcLine(mod) + 1, // Line + owner_decl.typeSrcLine(zcu) + 1, // Line try o.lowerDebugType(int_ty), - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(enumerators), ); @@ -2014,7 +2016,7 @@ pub const Object = struct { }, .Pointer => { // Normalize everything that the debug info does not represent. - const ptr_info = ty.ptrInfo(mod); + const ptr_info = ty.ptrInfo(zcu); if (ptr_info.sentinel != .none or ptr_info.flags.address_space != .generic or @@ -2025,10 +2027,10 @@ pub const Object = struct { ptr_info.flags.is_const or ptr_info.flags.is_volatile or ptr_info.flags.size == .Many or ptr_info.flags.size == .C or - !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(mod)) + !Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu)) { - const bland_ptr_ty = try mod.ptrType(.{ - .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(mod)) + const bland_ptr_ty = try zcu.ptrType(.{ + .child = if (!Type.fromInterned(ptr_info.child).hasRuntimeBitsIgnoreComptime(zcu)) .anyopaque_type else ptr_info.child, @@ -2050,18 +2052,18 @@ pub const Object = struct { // Set as forward reference while the type is lowered in case it references itself try o.debug_type_map.put(gpa, ty, debug_fwd_ref); - if (ty.isSlice(mod)) { - const ptr_ty = ty.slicePtrFieldType(mod); + if (ty.isSlice(zcu)) { + const ptr_ty = ty.slicePtrFieldType(zcu); const len_ty = Type.usize; const name = try o.allocTypeName(ty); defer gpa.free(name); const line = 0; - const ptr_size = ptr_ty.abiSize(mod); - const ptr_align = ptr_ty.abiAlignment(mod); - const len_size = len_ty.abiSize(mod); - const len_align = len_ty.abiAlignment(mod); + const ptr_size = ptr_ty.abiSize(zcu); + const ptr_align = ptr_ty.abiAlignment(zcu); + const len_size = len_ty.abiSize(zcu); + const len_align = len_ty.abiAlignment(zcu); const len_offset = len_align.forward(ptr_size); @@ -2093,8 +2095,8 @@ pub const Object = struct { o.debug_compile_unit, // Scope line, .none, // Underlying type - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&.{ debug_ptr_type, debug_len_type, @@ -2122,7 +2124,7 @@ pub const Object = struct { 0, // Line debug_elem_ty, target.ptrBitWidth(), - (ty.ptrAlignment(mod).toByteUnits() orelse 0) * 8, + (ty.ptrAlignment(zcu).toByteUnits() orelse 0) * 8, 0, // Offset ); @@ -2146,13 +2148,14 @@ pub const Object = struct { const name = try o.allocTypeName(ty); defer gpa.free(name); - const owner_decl_index = ty.getOwnerDecl(mod); + const owner_decl_index = ty.getOwnerDecl(zcu); const owner_decl = o.module.declPtr(owner_decl_index); + const file_scope = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu); const debug_opaque_type = try o.builder.debugStructType( try o.builder.metadataString(name), - try o.getDebugFile(mod.namespacePtr(owner_decl.src_namespace).file_scope), + try o.getDebugFile(file_scope), try o.namespaceToDebugScope(owner_decl.src_namespace), - owner_decl.typeSrcLine(mod) + 1, // Line + owner_decl.typeSrcLine(zcu) + 1, // Line .none, // Underlying type 0, // Size 0, // Align @@ -2167,13 +2170,13 @@ pub const Object = struct { .none, // File .none, // Scope 0, // Line - try o.lowerDebugType(ty.childType(mod)), - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + try o.lowerDebugType(ty.childType(zcu)), + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&.{ try o.builder.debugSubrange( try o.builder.debugConstant(try o.builder.intConst(.i64, 0)), - try o.builder.debugConstant(try o.builder.intConst(.i64, ty.arrayLen(mod))), + try o.builder.debugConstant(try o.builder.intConst(.i64, ty.arrayLen(zcu))), ), }), ); @@ -2181,14 +2184,14 @@ pub const Object = struct { return debug_array_type; }, .Vector => { - const elem_ty = ty.elemType2(mod); + const elem_ty = ty.elemType2(zcu); // Vector elements cannot be padded since that would make // @bitSizOf(elem) * len > @bitSizOf(vec). // Neither gdb nor lldb seem to be able to display non-byte sized // vectors properly. - const debug_elem_type = switch (elem_ty.zigTypeTag(mod)) { + const debug_elem_type = switch (elem_ty.zigTypeTag(zcu)) { .Int => blk: { - const info = elem_ty.intInfo(mod); + const info = elem_ty.intInfo(zcu); assert(info.bits != 0); const name = try o.allocTypeName(ty); defer gpa.free(name); @@ -2202,7 +2205,7 @@ pub const Object = struct { try o.builder.metadataString("bool"), 1, ), - else => try o.lowerDebugType(ty.childType(mod)), + else => try o.lowerDebugType(ty.childType(zcu)), }; const debug_vector_type = try o.builder.debugVectorType( @@ -2211,12 +2214,12 @@ pub const Object = struct { .none, // Scope 0, // Line debug_elem_type, - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&.{ try o.builder.debugSubrange( try o.builder.debugConstant(try o.builder.intConst(.i64, 0)), - try o.builder.debugConstant(try o.builder.intConst(.i64, ty.vectorLen(mod))), + try o.builder.debugConstant(try o.builder.intConst(.i64, ty.vectorLen(zcu))), ), }), ); @@ -2227,8 +2230,8 @@ pub const Object = struct { .Optional => { const name = try o.allocTypeName(ty); defer gpa.free(name); - const child_ty = ty.optionalChild(mod); - if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) { + const child_ty = ty.optionalChild(zcu); + if (!child_ty.hasRuntimeBitsIgnoreComptime(zcu)) { const debug_bool_type = try o.builder.debugBoolType( try o.builder.metadataString(name), 8, @@ -2242,7 +2245,7 @@ pub const Object = struct { // Set as forward reference while the type is lowered in case it references itself try o.debug_type_map.put(gpa, ty, debug_fwd_ref); - if (ty.optionalReprIsPayload(mod)) { + if (ty.optionalReprIsPayload(zcu)) { const debug_optional_type = try o.lowerDebugType(child_ty); o.builder.debugForwardReferenceSetType(debug_fwd_ref, debug_optional_type); @@ -2255,10 +2258,10 @@ pub const Object = struct { } const non_null_ty = Type.u8; - const payload_size = child_ty.abiSize(mod); - const payload_align = child_ty.abiAlignment(mod); - const non_null_size = non_null_ty.abiSize(mod); - const non_null_align = non_null_ty.abiAlignment(mod); + const payload_size = child_ty.abiSize(zcu); + const payload_align = child_ty.abiAlignment(zcu); + const non_null_size = non_null_ty.abiSize(zcu); + const non_null_align = non_null_ty.abiAlignment(zcu); const non_null_offset = non_null_align.forward(payload_size); const debug_data_type = try o.builder.debugMemberType( @@ -2289,8 +2292,8 @@ pub const Object = struct { o.debug_compile_unit, // Scope 0, // Line .none, // Underlying type - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&.{ debug_data_type, debug_some_type, @@ -2306,8 +2309,8 @@ pub const Object = struct { return debug_optional_type; }, .ErrorUnion => { - const payload_ty = ty.errorUnionPayload(mod); - if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { + const payload_ty = ty.errorUnionPayload(zcu); + if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { // TODO: Maybe remove? const debug_error_union_type = try o.lowerDebugType(Type.anyerror); try o.debug_type_map.put(gpa, ty, debug_error_union_type); @@ -2317,10 +2320,10 @@ pub const Object = struct { const name = try o.allocTypeName(ty); defer gpa.free(name); - const error_size = Type.anyerror.abiSize(mod); - const error_align = Type.anyerror.abiAlignment(mod); - const payload_size = payload_ty.abiSize(mod); - const payload_align = payload_ty.abiAlignment(mod); + const error_size = Type.anyerror.abiSize(zcu); + const error_align = Type.anyerror.abiAlignment(zcu); + const payload_size = payload_ty.abiSize(zcu); + const payload_align = payload_ty.abiAlignment(zcu); var error_index: u32 = undefined; var payload_index: u32 = undefined; @@ -2368,8 +2371,8 @@ pub const Object = struct { o.debug_compile_unit, // Sope 0, // Line .none, // Underlying type - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&fields), ); @@ -2390,14 +2393,14 @@ pub const Object = struct { const name = try o.allocTypeName(ty); defer gpa.free(name); - if (mod.typeToPackedStruct(ty)) |struct_type| { + if (zcu.typeToPackedStruct(ty)) |struct_type| { const backing_int_ty = struct_type.backingIntType(ip).*; if (backing_int_ty != .none) { - const info = Type.fromInterned(backing_int_ty).intInfo(mod); + const info = Type.fromInterned(backing_int_ty).intInfo(zcu); const builder_name = try o.builder.metadataString(name); const debug_int_type = switch (info.signedness) { - .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(mod) * 8), - .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(mod) * 8), + .signed => try o.builder.debugSignedType(builder_name, ty.abiSize(zcu) * 8), + .unsigned => try o.builder.debugUnsignedType(builder_name, ty.abiSize(zcu) * 8), }; try o.debug_type_map.put(gpa, ty, debug_int_type); return debug_int_type; @@ -2417,10 +2420,10 @@ pub const Object = struct { const debug_fwd_ref = try o.builder.debugForwardReference(); for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| { - if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(mod)) continue; + if (field_val != .none or !Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; - const field_size = Type.fromInterned(field_ty).abiSize(mod); - const field_align = Type.fromInterned(field_ty).abiAlignment(mod); + const field_size = Type.fromInterned(field_ty).abiSize(zcu); + const field_align = Type.fromInterned(field_ty).abiAlignment(zcu); const field_offset = field_align.forward(offset); offset = field_offset + field_size; @@ -2448,8 +2451,8 @@ pub const Object = struct { o.debug_compile_unit, // Scope 0, // Line .none, // Underlying type - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(fields.items), ); @@ -2467,7 +2470,7 @@ pub const Object = struct { // into. Therefore we can satisfy this by making an empty namespace, // rather than changing the frontend to unnecessarily resolve the // struct field types. - const owner_decl_index = ty.getOwnerDecl(mod); + const owner_decl_index = ty.getOwnerDecl(zcu); const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); try o.debug_type_map.put(gpa, ty, debug_struct_type); return debug_struct_type; @@ -2476,14 +2479,14 @@ pub const Object = struct { else => {}, } - if (!ty.hasRuntimeBitsIgnoreComptime(mod)) { - const owner_decl_index = ty.getOwnerDecl(mod); + if (!ty.hasRuntimeBitsIgnoreComptime(zcu)) { + const owner_decl_index = ty.getOwnerDecl(zcu); const debug_struct_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); try o.debug_type_map.put(gpa, ty, debug_struct_type); return debug_struct_type; } - const struct_type = mod.typeToStruct(ty).?; + const struct_type = zcu.typeToStruct(ty).?; var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{}; defer fields.deinit(gpa); @@ -2499,14 +2502,14 @@ pub const Object = struct { var it = struct_type.iterateRuntimeOrder(ip); while (it.next()) |field_index| { const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]); - if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; - const field_size = field_ty.abiSize(mod); - const field_align = mod.structFieldAlignment( + if (!field_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; + const field_size = field_ty.abiSize(zcu); + const field_align = zcu.structFieldAlignment( struct_type.fieldAlign(ip, field_index), field_ty, struct_type.layout, ); - const field_offset = ty.structFieldOffset(field_index, mod); + const field_offset = ty.structFieldOffset(field_index, zcu); const field_name = struct_type.fieldName(ip, field_index).unwrap() orelse try ip.getOrPutStringFmt(gpa, "{d}", .{field_index}, .no_embedded_nulls); @@ -2529,8 +2532,8 @@ pub const Object = struct { o.debug_compile_unit, // Scope 0, // Line .none, // Underlying type - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(fields.items), ); @@ -2543,14 +2546,14 @@ pub const Object = struct { return debug_struct_type; }, .Union => { - const owner_decl_index = ty.getOwnerDecl(mod); + const owner_decl_index = ty.getOwnerDecl(zcu); const name = try o.allocTypeName(ty); defer gpa.free(name); const union_type = ip.loadUnionType(ty.toIntern()); if (!union_type.haveFieldTypes(ip) or - !ty.hasRuntimeBitsIgnoreComptime(mod) or + !ty.hasRuntimeBitsIgnoreComptime(zcu) or !union_type.haveLayout(ip)) { const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index); @@ -2558,7 +2561,7 @@ pub const Object = struct { return debug_union_type; } - const layout = mod.getUnionLayout(union_type); + const layout = zcu.getUnionLayout(union_type); const debug_fwd_ref = try o.builder.debugForwardReference(); @@ -2572,8 +2575,8 @@ pub const Object = struct { o.debug_compile_unit, // Scope 0, // Line .none, // Underlying type - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple( &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))}, ), @@ -2600,12 +2603,12 @@ pub const Object = struct { for (0..tag_type.names.len) |field_index| { const field_ty = union_type.field_types.get(ip)[field_index]; - if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue; + if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(zcu)) continue; - const field_size = Type.fromInterned(field_ty).abiSize(mod); + const field_size = Type.fromInterned(field_ty).abiSize(zcu); const field_align: InternPool.Alignment = switch (union_type.flagsPtr(ip).layout) { .@"packed" => .none, - .auto, .@"extern" => mod.unionFieldNormalAlignment(union_type, @intCast(field_index)), + .auto, .@"extern" => zcu.unionFieldNormalAlignment(union_type, @intCast(field_index)), }; const field_name = tag_type.names.get(ip)[field_index]; @@ -2634,8 +2637,8 @@ pub const Object = struct { o.debug_compile_unit, // Scope 0, // Line .none, // Underlying type - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(fields.items), ); @@ -2693,8 +2696,8 @@ pub const Object = struct { o.debug_compile_unit, // Scope 0, // Line .none, // Underlying type - ty.abiSize(mod) * 8, - (ty.abiAlignment(mod).toByteUnits() orelse 0) * 8, + ty.abiSize(zcu) * 8, + (ty.abiAlignment(zcu).toByteUnits() orelse 0) * 8, try o.builder.debugTuple(&full_fields), ); @@ -2707,7 +2710,7 @@ pub const Object = struct { return debug_tagged_union_type; }, .Fn => { - const fn_info = mod.typeToFunc(ty).?; + const fn_info = zcu.typeToFunc(ty).?; var debug_param_types = std.ArrayList(Builder.Metadata).init(gpa); defer debug_param_types.deinit(); @@ -2715,32 +2718,32 @@ pub const Object = struct { try debug_param_types.ensureUnusedCapacity(3 + fn_info.param_types.len); // Return type goes first. - if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(mod)) { - const sret = firstParamSRet(fn_info, mod, target); + if (Type.fromInterned(fn_info.return_type).hasRuntimeBitsIgnoreComptime(zcu)) { + const sret = firstParamSRet(fn_info, zcu, target); const ret_ty = if (sret) Type.void else Type.fromInterned(fn_info.return_type); debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ret_ty)); if (sret) { - const ptr_ty = try mod.singleMutPtrType(Type.fromInterned(fn_info.return_type)); + const ptr_ty = try zcu.singleMutPtrType(Type.fromInterned(fn_info.return_type)); debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); } } else { debug_param_types.appendAssumeCapacity(try o.lowerDebugType(Type.void)); } - if (Type.fromInterned(fn_info.return_type).isError(mod) and + if (Type.fromInterned(fn_info.return_type).isError(zcu) and o.module.comp.config.any_error_tracing) { - const ptr_ty = try mod.singleMutPtrType(try o.getStackTraceType()); + const ptr_ty = try zcu.singleMutPtrType(try o.getStackTraceType()); debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); } for (0..fn_info.param_types.len) |i| { const param_ty = Type.fromInterned(fn_info.param_types.get(ip)[i]); - if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; + if (!param_ty.hasRuntimeBitsIgnoreComptime(zcu)) continue; - if (isByRef(param_ty, mod)) { - const ptr_ty = try mod.singleMutPtrType(param_ty); + if (isByRef(param_ty, zcu)) { + const ptr_ty = try zcu.singleMutPtrType(param_ty); debug_param_types.appendAssumeCapacity(try o.lowerDebugType(ptr_ty)); } else { debug_param_types.appendAssumeCapacity(try o.lowerDebugType(param_ty)); @@ -2767,9 +2770,10 @@ pub const Object = struct { } fn namespaceToDebugScope(o: *Object, namespace_index: InternPool.NamespaceIndex) !Builder.Metadata { - const mod = o.module; - const namespace = mod.namespacePtr(namespace_index); - if (namespace.parent == .none) return try o.getDebugFile(namespace.file_scope); + const zcu = o.module; + const namespace = zcu.namespacePtr(namespace_index); + const file_scope = namespace.fileScope(zcu); + if (namespace.parent == .none) return try o.getDebugFile(file_scope); const gop = try o.debug_unresolved_namespace_scopes.getOrPut(o.gpa, namespace_index); @@ -2779,13 +2783,14 @@ pub const Object = struct { } fn makeEmptyNamespaceDebugType(o: *Object, decl_index: InternPool.DeclIndex) !Builder.Metadata { - const mod = o.module; - const decl = mod.declPtr(decl_index); + const zcu = o.module; + const decl = zcu.declPtr(decl_index); + const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); return o.builder.debugStructType( - try o.builder.metadataString(decl.name.toSlice(&mod.intern_pool)), // TODO use fully qualified name - try o.getDebugFile(mod.namespacePtr(decl.src_namespace).file_scope), + try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)), // TODO use fully qualified name + try o.getDebugFile(file_scope), try o.namespaceToDebugScope(decl.src_namespace), - decl.typeSrcLine(mod) + 1, + decl.typeSrcLine(zcu) + 1, .none, 0, 0, @@ -2794,21 +2799,22 @@ pub const Object = struct { } fn getStackTraceType(o: *Object) Allocator.Error!Type { - const mod = o.module; + const zcu = o.module; - const std_mod = mod.std_mod; - const std_file = (mod.importPkg(std_mod) catch unreachable).file; + const std_mod = zcu.std_mod; + const std_file_imported = zcu.importPkg(std_mod) catch unreachable; - const builtin_str = try mod.intern_pool.getOrPutString(mod.gpa, "builtin", .no_embedded_nulls); - const std_namespace = mod.namespacePtr(mod.declPtr(std_file.root_decl.unwrap().?).src_namespace); - const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Module.DeclAdapter{ .zcu = mod }).?; + const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "builtin", .no_embedded_nulls); + const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index); + const std_namespace = zcu.namespacePtr(zcu.declPtr(std_file_root_decl.unwrap().?).src_namespace); + const builtin_decl = std_namespace.decls.getKeyAdapted(builtin_str, Module.DeclAdapter{ .zcu = zcu }).?; - const stack_trace_str = try mod.intern_pool.getOrPutString(mod.gpa, "StackTrace", .no_embedded_nulls); + const stack_trace_str = try zcu.intern_pool.getOrPutString(zcu.gpa, "StackTrace", .no_embedded_nulls); // buffer is only used for int_type, `builtin` is a struct. - const builtin_ty = mod.declPtr(builtin_decl).val.toType(); - const builtin_namespace = mod.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(mod)).?; - const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .zcu = mod }).?; - const stack_trace_decl = mod.declPtr(stack_trace_decl_index); + const builtin_ty = zcu.declPtr(builtin_decl).val.toType(); + const builtin_namespace = zcu.namespacePtrUnwrap(builtin_ty.getNamespaceIndex(zcu)).?; + const stack_trace_decl_index = builtin_namespace.decls.getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .zcu = zcu }).?; + const stack_trace_decl = zcu.declPtr(stack_trace_decl_index); // Sema should have ensured that StackTrace was analyzed. assert(stack_trace_decl.has_tv); @@ -2834,7 +2840,7 @@ pub const Object = struct { const gpa = o.gpa; const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const owner_mod = namespace.file_scope.mod; + const owner_mod = namespace.fileScope(zcu).mod; const zig_fn_type = decl.typeOf(zcu); const gop = try o.decl_map.getOrPut(gpa, decl_index); if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.function; @@ -3059,17 +3065,17 @@ pub const Object = struct { if (gop.found_existing) return gop.value_ptr.ptr(&o.builder).kind.variable; errdefer assert(o.decl_map.remove(decl_index)); - const mod = o.module; - const decl = mod.declPtr(decl_index); - const is_extern = decl.isExtern(mod); + const zcu = o.module; + const decl = zcu.declPtr(decl_index); + const is_extern = decl.isExtern(zcu); const variable_index = try o.builder.addVariable( try o.builder.strtabString((if (is_extern) decl.name else - try decl.fullyQualifiedName(mod)).toSlice(&mod.intern_pool)), - try o.lowerType(decl.typeOf(mod)), - toLlvmGlobalAddressSpace(decl.@"addrspace", mod.getTarget()), + try decl.fullyQualifiedName(zcu)).toSlice(&zcu.intern_pool)), + try o.lowerType(decl.typeOf(zcu)), + toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()), ); gop.value_ptr.* = variable_index.ptrConst(&o.builder).global; @@ -3077,9 +3083,9 @@ pub const Object = struct { if (is_extern) { variable_index.setLinkage(.external, &o.builder); variable_index.setUnnamedAddr(.default, &o.builder); - if (decl.val.getVariable(mod)) |decl_var| { - const decl_namespace = mod.namespacePtr(decl.src_namespace); - const single_threaded = decl_namespace.file_scope.mod.single_threaded; + if (decl.val.getVariable(zcu)) |decl_var| { + const decl_namespace = zcu.namespacePtr(decl.src_namespace); + const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded; variable_index.setThreadLocal( if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default, &o.builder, @@ -4638,7 +4644,8 @@ pub const DeclGen = struct { const o = dg.object; const zcu = o.module; const namespace = zcu.namespacePtr(dg.decl.src_namespace); - return namespace.file_scope.mod; + const file_scope = namespace.fileScope(zcu); + return file_scope.mod; } fn todo(dg: *DeclGen, comptime format: []const u8, args: anytype) Error { @@ -4682,7 +4689,7 @@ pub const DeclGen = struct { if (decl.val.getVariable(zcu)) |decl_var| { const decl_namespace = zcu.namespacePtr(decl.src_namespace); - const single_threaded = decl_namespace.file_scope.mod.single_threaded; + const single_threaded = decl_namespace.fileScope(zcu).mod.single_threaded; variable_index.setThreadLocal( if (decl_var.is_threadlocal and !single_threaded) .generaldynamic else .default, &o.builder, @@ -4692,10 +4699,11 @@ pub const DeclGen = struct { const line_number = decl.navSrcLine(zcu) + 1; const namespace = zcu.namespacePtr(decl.src_namespace); - const owner_mod = namespace.file_scope.mod; + const file_scope = namespace.fileScope(zcu); + const owner_mod = file_scope.mod; if (!owner_mod.strip) { - const debug_file = try o.getDebugFile(namespace.file_scope); + const debug_file = try o.getDebugFile(file_scope); const debug_global_var = try o.builder.debugGlobalVar( try o.builder.metadataString(decl.name.toSlice(ip)), // Name @@ -5143,9 +5151,10 @@ pub const FuncGen = struct { const decl_index = func.owner_decl; const decl = zcu.declPtr(decl_index); const namespace = zcu.namespacePtr(decl.src_namespace); - const owner_mod = namespace.file_scope.mod; + const file_scope = namespace.fileScope(zcu); + const owner_mod = file_scope.mod; - self.file = try o.getDebugFile(namespace.file_scope); + self.file = try o.getDebugFile(file_scope); const line_number = decl.navSrcLine(zcu) + 1; self.inlined = self.wip.debug_location; diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index c56a5a799e..2fbe9097d6 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -188,19 +188,20 @@ pub const Object = struct { fn genDecl( self: *Object, - mod: *Module, + zcu: *Zcu, decl_index: InternPool.DeclIndex, air: Air, liveness: Liveness, ) !void { - const decl = mod.declPtr(decl_index); - const namespace = mod.namespacePtr(decl.src_namespace); - const structured_cfg = namespace.file_scope.mod.structured_cfg; + const gpa = self.gpa; + const decl = zcu.declPtr(decl_index); + const namespace = zcu.namespacePtr(decl.src_namespace); + const structured_cfg = namespace.fileScope(zcu).mod.structured_cfg; var decl_gen = DeclGen{ - .gpa = self.gpa, + .gpa = gpa, .object = self, - .module = mod, + .module = zcu, .spv = &self.spv, .decl_index = decl_index, .air = air, @@ -212,19 +213,19 @@ pub const Object = struct { false => .{ .unstructured = .{} }, }, .current_block_label = undefined, - .base_line = decl.navSrcLine(mod), + .base_line = decl.navSrcLine(zcu), }; defer decl_gen.deinit(); decl_gen.genDecl() catch |err| switch (err) { error.CodegenFail => { - try mod.failed_analysis.put(mod.gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), decl_gen.error_msg.?); + try zcu.failed_analysis.put(gpa, InternPool.AnalUnit.wrap(.{ .decl = decl_index }), decl_gen.error_msg.?); }, else => |other| { // There might be an error that happened *after* self.error_msg // was already allocated, so be sure to free it. if (decl_gen.error_msg) |error_msg| { - error_msg.deinit(mod.gpa); + error_msg.deinit(gpa); } return other; diff --git a/src/link/C.zig b/src/link/C.zig index 21245c1e30..563604f7e0 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -208,6 +208,8 @@ pub fn updateFunc( fwd_decl.clearRetainingCapacity(); code.clearRetainingCapacity(); + const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); + var function: codegen.Function = .{ .value_map = codegen.CValueMap.init(gpa), .air = air, @@ -217,7 +219,7 @@ pub fn updateFunc( .dg = .{ .gpa = gpa, .zcu = zcu, - .mod = zcu.namespacePtr(decl.src_namespace).file_scope.mod, + .mod = file_scope.mod, .error_msg = null, .pass = .{ .decl = decl_index }, .is_naked_fn = decl.typeOf(zcu).fnCallingConvention(zcu) == .Naked, @@ -335,11 +337,13 @@ pub fn updateDecl(self: *C, zcu: *Zcu, decl_index: InternPool.DeclIndex) !void { fwd_decl.clearRetainingCapacity(); code.clearRetainingCapacity(); + const file_scope = zcu.namespacePtr(decl.src_namespace).fileScope(zcu); + var object: codegen.Object = .{ .dg = .{ .gpa = gpa, .zcu = zcu, - .mod = zcu.namespacePtr(decl.src_namespace).file_scope.mod, + .mod = file_scope.mod, .error_msg = null, .pass = .{ .decl = decl_index }, .is_naked_fn = false, @@ -491,7 +495,7 @@ pub fn flushModule(self: *C, arena: Allocator, prog_node: std.Progress.Node) !vo for (self.decl_table.keys(), self.decl_table.values()) |decl_index, *decl_block| { const decl = zcu.declPtr(decl_index); const extern_name = if (decl.isExtern(zcu)) decl.name.toOptional() else .none; - const mod = zcu.namespacePtr(decl.src_namespace).file_scope.mod; + const mod = zcu.namespacePtr(decl.src_namespace).fileScope(zcu).mod; try self.flushDeclBlock( zcu, mod, @@ -848,7 +852,7 @@ pub fn updateExports( const gpa = self.base.comp.gpa; const mod, const pass: codegen.DeclGen.Pass, const decl_block, const exported_block = switch (exported) { .decl_index => |decl_index| .{ - zcu.namespacePtr(zcu.declPtr(decl_index).src_namespace).file_scope.mod, + zcu.namespacePtr(zcu.declPtr(decl_index).src_namespace).fileScope(zcu).mod, .{ .decl = decl_index }, self.decl_table.getPtr(decl_index).?, (try self.exported_decls.getOrPut(gpa, decl_index)).value_ptr, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 2bb0a4c0a0..40cbfd28a8 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -1204,7 +1204,7 @@ pub fn commitDeclState( const decl = zcu.declPtr(decl_index); const ip = &zcu.intern_pool; const namespace = zcu.namespacePtr(decl.src_namespace); - const target = namespace.file_scope.mod.resolved_target.result; + const target = namespace.fileScope(zcu).mod.resolved_target.result; const target_endian = target.cpu.arch.endian(); var dbg_line_buffer = &decl_state.dbg_line; diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig index 24fc66367a..da38381cbb 100644 --- a/src/link/Wasm/ZigObject.zig +++ b/src/link/Wasm/ZigObject.zig @@ -335,29 +335,29 @@ fn finishUpdateDecl( code: []const u8, ) !void { const gpa = wasm_file.base.comp.gpa; - const mod = wasm_file.base.comp.module.?; - const decl = mod.declPtr(decl_index); + const zcu = wasm_file.base.comp.module.?; + const decl = zcu.declPtr(decl_index); const decl_info = zig_object.decls_map.get(decl_index).?; const atom_index = decl_info.atom; const atom = wasm_file.getAtomPtr(atom_index); const sym = zig_object.symbol(atom.sym_index); - const full_name = try decl.fullyQualifiedName(mod); - sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&mod.intern_pool)); + const full_name = try decl.fullyQualifiedName(zcu); + sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&zcu.intern_pool)); try atom.code.appendSlice(gpa, code); atom.size = @intCast(code.len); - switch (decl.typeOf(mod).zigTypeTag(mod)) { + switch (decl.typeOf(zcu).zigTypeTag(zcu)) { .Fn => { sym.index = try zig_object.appendFunction(gpa, .{ .type_index = zig_object.atom_types.get(atom_index).? }); sym.tag = .function; }, else => { - const segment_name: []const u8 = if (decl.getOwnedVariable(mod)) |variable| name: { + const segment_name: []const u8 = if (decl.getOwnedVariable(zcu)) |variable| name: { if (variable.is_const) { break :name ".rodata."; - } else if (Value.fromInterned(variable.init).isUndefDeep(mod)) { - const decl_namespace = mod.namespacePtr(decl.src_namespace); - const optimize_mode = decl_namespace.file_scope.mod.optimize_mode; + } else if (Value.fromInterned(variable.init).isUndefDeep(zcu)) { + const decl_namespace = zcu.namespacePtr(decl.src_namespace); + const optimize_mode = decl_namespace.fileScope(zcu).mod.optimize_mode; const is_initialized = switch (optimize_mode) { .Debug, .ReleaseSafe => true, .ReleaseFast, .ReleaseSmall => false, @@ -382,7 +382,7 @@ fn finishUpdateDecl( // Will be freed upon freeing of decl or after cleanup of Wasm binary. const full_segment_name = try std.mem.concat(gpa, u8, &.{ segment_name, - full_name.toSlice(&mod.intern_pool), + full_name.toSlice(&zcu.intern_pool), }); errdefer gpa.free(full_segment_name); sym.tag = .data; @@ -390,7 +390,7 @@ fn finishUpdateDecl( }, } if (code.len == 0) return; - atom.alignment = decl.getAlignment(mod); + atom.alignment = decl.getAlignment(zcu); } /// Creates and initializes a new segment in the 'Data' section. diff --git a/src/main.zig b/src/main.zig index d9084686c8..3ba1276abf 100644 --- a/src/main.zig +++ b/src/main.zig @@ -27,8 +27,6 @@ const Cache = std.Build.Cache; const target_util = @import("target.zig"); const crash_report = @import("crash_report.zig"); const Zcu = @import("Zcu.zig"); -/// Deprecated. -const Module = Zcu; const AstGen = std.zig.AstGen; const mingw = @import("mingw.zig"); const Server = std.zig.Server; @@ -919,7 +917,7 @@ fn buildOutputType( var contains_res_file: bool = false; var reference_trace: ?u32 = null; var pdb_out_path: ?[]const u8 = null; - var error_limit: ?Module.ErrorInt = null; + var error_limit: ?Zcu.ErrorInt = null; // These are before resolving sysroot. var extra_cflags: std.ArrayListUnmanaged([]const u8) = .{}; var extra_rcflags: std.ArrayListUnmanaged([]const u8) = .{}; @@ -1107,7 +1105,7 @@ fn buildOutputType( ); } else if (mem.eql(u8, arg, "--error-limit")) { const next_arg = args_iter.nextOrFatal(); - error_limit = std.fmt.parseUnsigned(Module.ErrorInt, next_arg, 0) catch |err| { + error_limit = std.fmt.parseUnsigned(Zcu.ErrorInt, next_arg, 0) catch |err| { fatal("unable to parse error limit '{s}': {s}", .{ next_arg, @errorName(err) }); }; } else if (mem.eql(u8, arg, "-cflags")) { @@ -5956,7 +5954,7 @@ fn cmdAstCheck( } } - var file: Module.File = .{ + var file: Zcu.File = .{ .status = .never_loaded, .source_loaded = false, .tree_loaded = false, @@ -5967,8 +5965,6 @@ fn cmdAstCheck( .tree = undefined, .zir = undefined, .mod = undefined, - .root_decl = .none, - .path_digest = undefined, }; if (zig_source_file) |file_name| { var f = fs.cwd().openFile(file_name, .{}) catch |err| { @@ -6275,7 +6271,7 @@ fn cmdDumpZir( }; defer f.close(); - var file: Module.File = .{ + var file: Zcu.File = .{ .status = .never_loaded, .source_loaded = false, .tree_loaded = false, @@ -6284,10 +6280,8 @@ fn cmdDumpZir( .source = undefined, .stat = undefined, .tree = undefined, - .zir = try Module.loadZirCache(gpa, f), + .zir = try Zcu.loadZirCache(gpa, f), .mod = undefined, - .root_decl = .none, - .path_digest = undefined, }; defer file.zir.deinit(gpa); @@ -6342,7 +6336,7 @@ fn cmdChangelist( if (stat.size > std.zig.max_src_size) return error.FileTooBig; - var file: Module.File = .{ + var file: Zcu.File = .{ .status = .never_loaded, .source_loaded = false, .tree_loaded = false, @@ -6357,8 +6351,6 @@ fn cmdChangelist( .tree = undefined, .zir = undefined, .mod = undefined, - .root_decl = .none, - .path_digest = undefined, }; file.mod = try Package.Module.createLimited(arena, .{ @@ -6431,7 +6423,7 @@ fn cmdChangelist( var inst_map: std.AutoHashMapUnmanaged(Zir.Inst.Index, Zir.Inst.Index) = .{}; defer inst_map.deinit(gpa); - try Module.mapOldZirToNew(gpa, old_zir, file.zir, &inst_map); + try Zcu.mapOldZirToNew(gpa, old_zir, file.zir, &inst_map); var bw = io.bufferedWriter(io.getStdOut().writer()); const stdout = bw.writer();