authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-11 05:41:28-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 11:00:55-04:00
loge761d5200a0888e4c56e04a725979c70de457e71
tree23713636a7a766d1a5a0c4624f21c90e350cce67
parent0bf3e08c705ec460c71d3b2261acb0b87aacd066

link: fix `@tagName` incremental bug


22 files changed, 299 insertions(+), 246 deletions(-)

src/Compilation.zig+4-4
......@@ -2829,6 +2829,7 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
28292829 }
28302830
28312831 const is_hit = man.hit(main_progress_node) catch |err| switch (err) {
2832 error.Canceled, error.OutOfMemory => |e| return e,
28322833 error.CacheCheckFailed => switch (man.diagnostic) {
28332834 .none => unreachable,
28342835 .manifest_create, .manifest_read, .manifest_lock => |e| return comp.setMiscFailure(
......@@ -2844,7 +2845,6 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) UpdateE
28442845 });
28452846 },
28462847 },
2847 error.OutOfMemory, error.Canceled => |e| return e,
28482848 error.InvalidFormat => return comp.setMiscFailure(
28492849 .check_whole_cache,
28502850 "failed to check cache: invalid manifest file format",
......@@ -3283,8 +3283,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error
32833283 .fuzz = comp.config.any_fuzz,
32843284 .lto = comp.config.lto,
32853285 }) catch |err| switch (err) {
3286 error.Canceled, error.OutOfMemory => |e| return e,
32863287 error.AlreadyReported => {},
3287 error.OutOfMemory => |e| return e,
32883288 };
32893289
32903290 if (zcu_obj_path) |path| {
......@@ -3293,8 +3293,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error
32933293 // `link.Queue` has not called `prelink` because it knew we would want to send that
32943294 // final link input. It is *our* responsibility to call `prelink` now we're done.
32953295 comp.bin_file.?.prelink() catch |err| switch (err) {
3296 error.Canceled, error.OutOfMemory => |e| return e,
32963297 error.AlreadyReported => return,
3297 else => |e| return e,
32983298 };
32993299 }
33003300 }
......@@ -3308,8 +3308,8 @@ fn flush(comp: *Compilation, arena: Allocator) (Io.Cancelable || Allocator.Error
33083308 };
33093309 // This is needed before reading the error flags.
33103310 lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) {
3311 error.Canceled, error.OutOfMemory => |e| return e,
33113312 error.AlreadyReported => return,
3312 error.OutOfMemory, error.Canceled => |e| return e,
33133313 };
33143314 }
33153315}
src/Zcu.zig+1-1
......@@ -4707,7 +4707,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)
47074707 return .ok;
47084708}
47094709
4710pub const CodegenFailError = error{
4710pub const CodegenFailError = Io.Cancelable || error{
47114711 /// Indicates the error message has been already stored at `Zcu.failed_codegen`.
47124712 AlreadyReported,
47134713 OutOfMemory,
src/codegen/aarch64/Select.zig+5-5
......@@ -896,7 +896,7 @@ pub fn finishAnalysis(isel: *Select) !void {
896896 }
897897}
898898
899pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, AlreadyReported }!void {
899pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void {
900900 const zcu = isel.pt.zcu;
901901 const ip = &zcu.intern_pool;
902902 const gpa = zcu.gpa;
......@@ -8024,7 +8024,7 @@ fn emitLiteral(isel: *Select, bytes: []const u8) !void {
80248024 }
80258025}
80268026
8027fn fail(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
8027fn fail(isel: *Select, comptime format: []const u8, args: anytype) codegen.Error {
80288028 @branchHint(.cold);
80298029 return isel.pt.zcu.codegenFail(isel.nav_index, format, args);
80308030}
......@@ -10618,7 +10618,7 @@ pub const Value = struct {
1061810618 vi: Value.Index,
1061910619 ra: Register.Alias,
1062010620
10621 fn finish(mat: Value.Materialize, isel: *Select) error{ OutOfMemory, AlreadyReported }!void {
10621 fn finish(mat: Value.Materialize, isel: *Select) codegen.Error!void {
1062210622 const live_vi = isel.live_registers.getPtr(mat.ra);
1062310623 assert(live_vi.* == .allocating);
1062410624 var vi = mat.vi;
......@@ -11659,7 +11659,7 @@ fn use(isel: *Select, air_ref: Air.Inst.Ref) !Value.Index {
1165911659 return vi;
1166011660}
1166111661
11662fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReported }!bool {
11662fn fill(isel: *Select, dst_ra: Register.Alias) codegen.Error!bool {
1166311663 switch (dst_ra) {
1166411664 else => {},
1166511665 Register.Alias.fp, .zr, .sp, .pc, .fpcr, .fpsr, .ffr => return false,
......@@ -11692,7 +11692,7 @@ fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReport
1169211692 return true;
1169311693}
1169411694
11695fn fillMemory(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReported }!bool {
11695fn fillMemory(isel: *Select, dst_ra: Register.Alias) codegen.Error!bool {
1169611696 const dst_live_vi = isel.live_registers.getPtr(dst_ra);
1169711697 const dst_vi = switch (dst_live_vi.*) {
1169811698 _ => |dst_vi| dst_vi,
src/codegen/c.zig+3-2
......@@ -6,6 +6,7 @@ const log = std.log.scoped(.c);
66const Allocator = mem.Allocator;
77const Writer = std.Io.Writer;
88
9const codegen = @import("../codegen.zig");
910const dev = @import("../dev.zig");
1011const link = @import("../link.zig");
1112const Zcu = @import("../Zcu.zig");
......@@ -86,7 +87,7 @@ pub const Mir = struct {
8687 }
8788};
8889
89pub const Error = Writer.Error || Allocator.Error || error{AlreadyReported};
90pub const Error = codegen.Error || Writer.Error;
9091
9192pub const CType = @import("c/type.zig").CType;
9293
......@@ -2251,7 +2252,7 @@ pub fn generate(
22512252 func_index: InternPool.Index,
22522253 air: *const Air,
22532254 liveness: *const ?Air.Liveness,
2254) @import("../codegen.zig").Error!Mir {
2255) codegen.Error!Mir {
22552256 const zcu = pt.zcu;
22562257 const gpa = zcu.gpa;
22572258
src/codegen/llvm.zig+3-3
......@@ -348,7 +348,7 @@ pub const Object = struct {
348348 lto: std.zig.LtoMode,
349349 };
350350
351 pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) error{ AlreadyReported, OutOfMemory }!void {
351 pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) link.Error!void {
352352 const zcu = o.zcu;
353353 const comp = zcu.comp;
354354 const io = comp.io;
......@@ -1141,7 +1141,7 @@ pub const Object = struct {
11411141 }
11421142 }
11431143
1144 fn flushTypePool(o: *Object, pt: Zcu.PerThread) Allocator.Error!void {
1144 fn flushTypePool(o: *Object, pt: Zcu.PerThread) link.Error!void {
11451145 try o.type_pool.flushPending(pt, .{ .llvm = o });
11461146 }
11471147
......@@ -1304,7 +1304,7 @@ pub const Object = struct {
13041304 }, &o.builder);
13051305 }
13061306
1307 pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Allocator.Error!void {
1307 pub fn updateContainerType(o: *Object, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) link.Error!void {
13081308 _ = o.type_map.remove(ty);
13091309 try o.type_pool.updateContainerType(pt, .{ .llvm = o }, ty, success);
13101310 if (o.named_enum_map.get(ty)) |llvm_function| {
src/codegen/loongarch/Mir.zig+1-1
......@@ -115,7 +115,7 @@ pub fn emit(
115115 @fromBackingInt(ef.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(ef, pt, lazy_reloc.symbol) catch |err|
116116 return zcu.codegenFail(func.owner_nav, "{s} creating lazy symbol", .{@errorName(err)}))
117117 else if (lf.cast(.elf2)) |elf|
118 elf.lazySymbol(lazy_reloc.symbol) catch |err|
118 elf.lazySymbol(pt, lazy_reloc.symbol) catch |err|
119119 return zcu.codegenFail(func.owner_nav, "emit lazy symbol: {t}", .{err})
120120 else
121121 return zcu.codegenFail(func.owner_nav, "external symbols unimplemented for {s}", .{@tagName(lf.tag)}),
src/codegen/riscv64/CodeGen.zig+2-2
......@@ -8349,7 +8349,7 @@ fn wantSafety(func: *Func) bool {
83498349 };
83508350}
83518351
8352fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
8352fn fail(func: *const Func, comptime format: []const u8, args: anytype) codegen.Error {
83538353 @branchHint(.cold);
83548354 const zcu = func.pt.zcu;
83558355 switch (func.owner) {
......@@ -8359,7 +8359,7 @@ fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ Ou
83598359 return error.AlreadyReported;
83608360}
83618361
8362fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, AlreadyReported } {
8362fn failMsg(func: *const Func, msg: *ErrorMsg) codegen.Error {
83638363 @branchHint(.cold);
83648364 const zcu = func.pt.zcu;
83658365 switch (func.owner) {
src/codegen/sparc64/CodeGen.zig+2-2
......@@ -3450,7 +3450,7 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
34503450 }
34513451}
34523452
3453fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
3453fn fail(self: *Self, comptime format: []const u8, args: anytype) codegen.Error {
34543454 @branchHint(.cold);
34553455 const zcu = self.pt.zcu;
34563456 const func = zcu.funcInfo(self.func_index);
......@@ -3458,7 +3458,7 @@ fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMem
34583458 return zcu.codegenFailMsg(func.owner_nav, msg);
34593459}
34603460
3461fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, AlreadyReported } {
3461fn failMsg(self: *Self, msg: *ErrorMsg) codegen.Error {
34623462 @branchHint(.cold);
34633463 const zcu = self.pt.zcu;
34643464 const func = zcu.funcInfo(self.func_index);
src/codegen/spirv/CodeGen.zig+3-9
......@@ -240,10 +240,7 @@ pub fn generate(
240240 };
241241 defer cg.deinit();
242242
243 cg.genNav(true) catch |err| switch (err) {
244 error.AlreadyReported => return error.AlreadyReported,
245 error.OutOfMemory => return error.OutOfMemory,
246 };
243 try cg.genNav(true);
247244
248245 return cg.serializeToMir(gpa);
249246}
......@@ -270,10 +267,7 @@ pub fn generateNav(
270267 };
271268 defer cg.deinit();
272269
273 cg.genNav(false) catch |err| switch (err) {
274 error.AlreadyReported => return error.AlreadyReported,
275 error.OutOfMemory => return error.OutOfMemory,
276 };
270 try cg.genNav(false);
277271
278272 return cg.serializeToMir(gpa);
279273}
......@@ -854,7 +848,7 @@ pub fn storageClass(cg: *const CodeGen, as: std.lang.AddressSpace) spec.StorageC
854848 };
855849}
856850
857const Error = error{ AlreadyReported, OutOfMemory };
851const Error = codegen.Error;
858852
859853pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
860854 const gpa = cg.gpa;
src/codegen/spork8/CodeGen.zig+15-27
......@@ -4,6 +4,7 @@ const Allocator = std.mem.Allocator;
44const assert = std.debug.assert;
55
66const CodeGen = @This();
7const codegen = @import("../../codegen.zig");
78const link = @import("../../link.zig");
89const Spork8 = link.File.Spork8;
910const Zcu = @import("../../Zcu.zig");
......@@ -133,37 +134,20 @@ pub fn generate(
133134 _ = bin_file;
134135 const zcu = pt.zcu;
135136 const gpa = zcu.gpa;
136 const cg = zcu.funcInfo(func_index);
137 const func = zcu.funcInfo(func_index);
137138
138 var code_gen: CodeGen = .{
139 var cg: CodeGen = .{
139140 .gpa = gpa,
140141 .pt = pt,
141142 .air = air.*,
142143 .liveness = liveness.*.?,
143 .owner_nav = cg.owner_nav,
144 .owner_nav = func.owner_nav,
144145 .func_index = func_index,
145146 .mir_instructions = .empty,
146147 .mir_extra = .empty,
147148 };
148 defer code_gen.deinit();
149 defer cg.deinit();
149150
150 return generateInner(&code_gen) catch |err| switch (err) {
151 error.AlreadyReported,
152 error.OutOfMemory,
153 => |e| return e,
154 };
155}
156
157pub fn deinit(cg: *CodeGen) void {
158 cg.* = undefined;
159}
160
161const InnerError = error{
162 AlreadyReported,
163 OutOfMemory,
164};
165
166fn generateInner(cg: *CodeGen) InnerError!Mir {
167151 // Generate MIR for function body
168152 try cg.genBody(cg.air.getMainBody());
169153
......@@ -175,7 +159,11 @@ fn generateInner(cg: *CodeGen) InnerError!Mir {
175159 };
176160}
177161
178fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
162pub fn deinit(cg: *CodeGen) void {
163 cg.* = undefined;
164}
165
166fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) codegen.Error!void {
179167 const zcu = cg.pt.zcu;
180168 const ip = &zcu.intern_pool;
181169
......@@ -185,7 +173,7 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void {
185173 }
186174}
187175
188fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
176fn genInst(cg: *CodeGen, inst: Air.Inst.Index) codegen.Error!void {
189177 const air_tags = cg.air.instructions.items(.tag);
190178 return switch (air_tags[@backingInt(inst)]) {
191179 .inferred_alloc, .inferred_alloc_comptime => unreachable,
......@@ -444,17 +432,17 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
444432 };
445433}
446434
447fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
435fn airUnreachable(cg: *CodeGen, inst: Air.Inst.Index) codegen.Error!void {
448436 _ = cg;
449437 _ = inst;
450438}
451439
452fn airTrap(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
440fn airTrap(cg: *CodeGen, inst: Air.Inst.Index) codegen.Error!void {
453441 _ = inst;
454442 try cg.addTag(.halt);
455443}
456444
457fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
445fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) codegen.Error!void {
458446 const unwrapped_asm = cg.air.unwrapAsm(inst);
459447 const outputs = unwrapped_asm.outputs;
460448 // const inputs = unwrapped_asm.inputs;
......@@ -538,7 +526,7 @@ pub fn addTagImm8(cg: *CodeGen, tag: Mir.Inst.Tag, imm8: u8) error{OutOfMemory}!
538526 try cg.addInst(.{ .tag = tag, .data = .{ .imm8 = imm8 } });
539527}
540528
541fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
529fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) codegen.Error {
542530 const zcu = cg.pt.zcu;
543531 const func = zcu.funcInfo(cg.func_index);
544532 return zcu.codegenFail(func.owner_nav, fmt, args);
src/codegen/wasm/CodeGen.zig+3-8
......@@ -332,8 +332,7 @@ const ValueTable = std.array_hash_map.Auto(Air.Inst.Ref, WValue);
332332
333333const bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {};
334334
335const InnerError = error{
336 OutOfMemory,
335const InnerError = Error || error{
337336 /// An error occurred when trying to lower AIR to MIR.
338337 AlreadyReported,
339338 /// Compiler implementation could not handle a large integer.
......@@ -361,7 +360,7 @@ pub fn deinit(cg: *CodeGen) void {
361360 cg.* = undefined;
362361}
363362
364pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
363pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) Error {
365364 const zcu = cg.pt.zcu;
366365 const func = zcu.funcInfo(cg.func_index);
367366 return zcu.codegenFail(func.owner_nav, fmt, args);
......@@ -760,11 +759,7 @@ fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue {
760759 return .{ .local = .{ .value = initial_index, .references = 1 } };
761760}
762761
763pub const Error = error{
764 OutOfMemory,
765 /// Indicates the error is already stored in Zcu `failed_codegen`.
766 AlreadyReported,
767};
762pub const Error = codegen.Error;
768763
769764pub fn generate(
770765 bin_file: *link.File,
src/codegen/x86_64/CodeGen.zig+1-1
......@@ -182172,7 +182172,7 @@ fn resolveCallingConventionValues(
182172182172 return result;
182173182173}
182174182174
182175fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
182175fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) codegen.Error {
182176182176 @branchHint(.cold);
182177182177 const zcu = cg.pt.zcu;
182178182178 return switch (cg.owner) {
src/codegen/x86_64/Emit.zig+1-1
......@@ -138,7 +138,7 @@ pub fn emitMir(emit: *Emit) Error!void {
138138 return emit.fail("{s} creating lazy symbol", .{@errorName(err)}),
139139 ))
140140 else if (emit.bin_file.cast(.elf2)) |elf|
141 try elf.lazySymbol(lazy_sym)
141 try elf.lazySymbol(emit.pt, lazy_sym)
142142 else if (emit.bin_file.cast(.macho)) |macho_file|
143143 @fromBackingInt(@intCast(macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, emit.pt, lazy_sym) catch |err|
144144 return emit.fail("{s} creating lazy symbol", .{@errorName(err)})))
src/link.zig+9-14
......@@ -838,7 +838,7 @@ pub const File = struct {
838838 switch (base.tag) {
839839 .lld => unreachable,
840840 else => {},
841 inline .elf, .c => |tag| {
841 inline .elf, .elf2, .c, .coff2 => |tag| {
842842 dev.check(tag.devFeature());
843843 return @as(*tag.Type(), @fieldParentPtr("base", base)).updateContainerType(pt, ty, success);
844844 },
......@@ -1690,19 +1690,14 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
16901690 const name = Type.fromInterned(container_update.ty).containerTypeName(ip).toSlice(ip);
16911691 const ty_prog_node = comp.link_prog_node.start(name, 0);
16921692 defer ty_prog_node.end();
1693 if (zcu.llvm_object) |llvm_object| {
1694 llvm_object.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) {
1695 error.OutOfMemory => diags.setAllocFailure(),
1696 };
1697 } else {
1698 if (comp.bin_file) |lf| {
1699 lf.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) {
1700 error.OutOfMemory => diags.setAllocFailure(),
1701 error.Canceled => io.recancel(),
1702 error.AlreadyReported => {},
1703 };
1704 }
1705 }
1693 (if (zcu.llvm_object) |llvm_object|
1694 llvm_object.updateContainerType(pt, container_update.ty, container_update.success)
1695 else if (comp.bin_file) |lf|
1696 lf.updateContainerType(pt, container_update.ty, container_update.success)) catch |err| switch (err) {
1697 error.OutOfMemory => diags.setAllocFailure(),
1698 error.Canceled => io.recancel(),
1699 error.AlreadyReported => {},
1700 };
17061701 break :nav null;
17071702 },
17081703 .debug_update_line_number => |ti| nav: {
src/link/C.zig+14-14
......@@ -498,7 +498,7 @@ pub fn updateFunc(
498498 pt: Zcu.PerThread,
499499 func_index: InternPool.Index,
500500 mir: *AnyMir,
501) Allocator.Error!void {
501) link.Error!void {
502502 const zcu = pt.zcu;
503503 const gpa = zcu.gpa;
504504 const nav = zcu.funcInfo(func_index).owner_nav;
......@@ -536,11 +536,7 @@ pub fn updateFunc(
536536 try c.type_pool.flushPending(pt, .{ .c = c });
537537}
538538
539pub fn updateNav(
540 c: *C,
541 pt: Zcu.PerThread,
542 nav_index: InternPool.Nav.Index,
543) Allocator.Error!void {
539pub fn updateNav(c: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void {
544540 const tracy = trace(@src());
545541 defer tracy.end();
546542
......@@ -603,7 +599,8 @@ pub fn updateNav(
603599 const start = aw.written().len;
604600 codegen.genDeclFwd(&dg, &aw.writer) catch |err| switch (err) {
605601 error.AlreadyReported => return,
606 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
602 error.WriteFailed => return error.OutOfMemory,
603 error.Canceled, error.OutOfMemory => |e| return e,
607604 };
608605 break :fwd_decl .{
609606 .start = @intCast(start),
......@@ -617,7 +614,8 @@ pub fn updateNav(
617614 const start = aw.written().len;
618615 codegen.genDecl(&dg, &aw.writer) catch |err| switch (err) {
619616 error.AlreadyReported => return,
620 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
617 error.WriteFailed => return error.OutOfMemory,
618 error.Canceled, error.OutOfMemory => |e| return e,
621619 };
622620 break :code .{
623621 .start = @intCast(start),
......@@ -655,7 +653,7 @@ fn updateUav(
655653 pt: Zcu.PerThread,
656654 val: Value,
657655 rendered_decl: *RenderedDecl,
658) Allocator.Error!void {
656) link.Error!void {
659657 const tracy = trace(@src());
660658 defer tracy.end();
661659
......@@ -691,7 +689,8 @@ fn updateUav(
691689 .init_val = val,
692690 }) catch |err| switch (err) {
693691 error.AlreadyReported => return,
694 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
692 error.WriteFailed => return error.OutOfMemory,
693 error.Canceled, error.OutOfMemory => |e| return e,
695694 };
696695 break :fwd_decl .{
697696 .start = @intCast(start),
......@@ -710,7 +709,8 @@ fn updateUav(
710709 .init_val = val,
711710 }) catch |err| switch (err) {
712711 error.AlreadyReported => return,
713 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
712 error.WriteFailed => return error.OutOfMemory,
713 error.Canceled, error.OutOfMemory => |e| return e,
714714 };
715715 break :code .{
716716 .start = @intCast(start),
......@@ -1144,14 +1144,14 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
11441144 for (need_never_tail_funcs.keys()) |fn_nav| {
11451145 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_tail, &lazy_decls_aw.writer) catch |err| switch (err) {
11461146 error.WriteFailed => return error.OutOfMemory,
1147 error.OutOfMemory => |e| return e,
1147 error.Canceled, error.OutOfMemory => |e| return e,
11481148 error.AlreadyReported => unreachable,
11491149 };
11501150 }
11511151 for (need_never_inline_funcs.keys()) |fn_nav| {
11521152 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_inline, &lazy_decls_aw.writer) catch |err| switch (err) {
11531153 error.WriteFailed => return error.OutOfMemory,
1154 error.OutOfMemory => |e| return e,
1154 error.Canceled, error.OutOfMemory => |e| return e,
11551155 error.AlreadyReported => unreachable,
11561156 };
11571157 }
......@@ -1399,7 +1399,7 @@ fn addCTypeDependencies(
13991399 };
14001400}
14011401
1402fn updateNewUavs(c: *C, pt: Zcu.PerThread, old_uavs_len: usize) Allocator.Error!void {
1402fn updateNewUavs(c: *C, pt: Zcu.PerThread, old_uavs_len: usize) link.Error!void {
14031403 const gpa = pt.zcu.comp.gpa;
14041404 var index = old_uavs_len;
14051405 while (index < c.uavs.count()) : (index += 1) {
src/link/Coff.zig+87-51
......@@ -1666,7 +1666,7 @@ fn create(
16661666 .global_pending_index = 0,
16671667 .navs = .empty,
16681668 .uavs = .empty,
1669 .lazy = .initFill(.{
1669 .lazy = comptime .initFill(.{
16701670 .map = .empty,
16711671 .pending_index = 0,
16721672 }),
......@@ -3158,7 +3158,7 @@ fn flushSymbolTableEntry(coff: *Coff, index: u32, pt: Zcu.PerThread) !void {
31583158 },
31593159 inline .lazy_code, .lazy_const_data => |mi, tag| {
31603160 const lazy_sym = mi.lazySymbol(coff);
3161 const name = try std.fmt.allocPrint(gpa, "__lazy_{s}_{f}", .{
3161 const name = try gpa.print("__lazy_{s}_{f}", .{
31623162 @tagName(lazy_sym.kind),
31633163 Type.fromInterned(lazy_sym.ty).fmt(pt),
31643164 });
......@@ -5488,6 +5488,44 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
54885488 if (nav.resolved.?.@"linksection".unwrap()) |_| {
54895489 try ni.resizeLeaf(&coff.mf, gpa, si.get(coff).extra.size);
54905490 }
5491
5492 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.
5493 try coff.genPending(pt);
5494}
5495
5496pub fn updateContainerType(
5497 coff: *Coff,
5498 pt: Zcu.PerThread,
5499 ty: InternPool.Index,
5500 success: bool,
5501) link.Error!void {
5502 if (!success) return;
5503 var lazy_it = coff.lazy.iterator();
5504 while (lazy_it.next()) |lazy| if (lazy.value.map.getIndex(ty)) |lmi| {
5505 if (lazy.value.pending_index <= lmi) continue;
5506 // This type has changed on this incremental update, so update the lazy code/data.
5507 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = @intCast(lmi) };
5508 const kind = switch (lmr.kind) {
5509 .code => "code",
5510 .const_data => "data",
5511 };
5512 var name: [std.Progress.Node.max_name_len]u8 = undefined;
5513 const sub_prog_node = coff.synth_prog_node.start(
5514 std.mem.print(&name, "lazy {s} for {f}", .{
5515 kind,
5516 Type.fromInterned(ty).fmt(pt),
5517 }) catch &name,
5518 0,
5519 );
5520 defer sub_prog_node.end();
5521 coff.genLazy(pt, lmr) catch |err| switch (err) {
5522 else => |e| return e,
5523 error.MappedFileIo => return coff.base.comp.link_diags.fail(
5524 "linker failed to lower lazy {s}: {t}",
5525 .{ kind, coff.mf.io_err.? },
5526 ),
5527 };
5528 };
54915529}
54925530
54935531pub fn lowerUav(
......@@ -5603,10 +5641,13 @@ fn updateFuncInner(
56035641 };
56045642 si.get(coff).extra.size = @intCast(nw.interface.end);
56055643 try si.applyLocationRelocs(coff);
5644
5645 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.
5646 try coff.genPending(pt);
56065647}
56075648
56085649pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void {
5609 coff.flushLazy(pt, .{
5650 coff.genLazy(pt, .{
56105651 .kind = .const_data,
56115652 .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
56125653 }) catch |err| switch (err) {
......@@ -5919,22 +5960,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
59195960 };
59205961 break :task;
59215962 }
5922 while (coff.pending_uavs.pop()) |pending_uav| {
5923 const sub_prog_node = coff.idleProgNode(tid, coff.const_prog_node, .{ .uav = pending_uav.key });
5924 defer sub_prog_node.end();
5925 coff.flushUav(
5926 .{ .zcu = comp.zcu.?, .tid = tid },
5927 pending_uav.key,
5928 pending_uav.value.alignment,
5929 ) catch |err| switch (err) {
5930 else => |e| return e,
5931 error.MappedFileIo => return comp.link_diags.fail(
5932 "linker failed to lower constant: {t}",
5933 .{coff.mf.io_err.?},
5934 ),
5935 };
5936 break :task;
5937 }
59385963 if (coff.pending_input) |pending_iami| {
59395964 const name_slice = pending_iami.member(coff).name.toSlice(coff);
59405965 const sub_prog_node = coff.input_prog_node.start(
......@@ -5983,33 +6008,6 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
59836008 };
59846009 break :task;
59856010 }
5986 var lazy_it = coff.lazy.iterator();
5987 while (lazy_it.next()) |lazy| if (lazy.value.pending_index < lazy.value.map.count()) {
5988 const pt: Zcu.PerThread = .{ .zcu = comp.zcu.?, .tid = tid };
5989 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = lazy.value.pending_index };
5990 lazy.value.pending_index += 1;
5991 const kind = switch (lmr.kind) {
5992 .code => "code",
5993 .const_data => "data",
5994 };
5995 var name: [std.Progress.Node.max_name_len]u8 = undefined;
5996 const sub_prog_node = coff.synth_prog_node.start(
5997 std.mem.print(&name, "lazy {s} for {f}", .{
5998 kind,
5999 Type.fromInterned(lmr.lazySymbol(coff).ty).fmt(pt),
6000 }) catch &name,
6001 0,
6002 );
6003 defer sub_prog_node.end();
6004 coff.flushLazy(pt, lmr) catch |err| switch (err) {
6005 else => |e| return e,
6006 error.MappedFileIo => return comp.link_diags.fail(
6007 "linker failed to lower lazy {s}: {t}",
6008 .{ kind, coff.mf.io_err.? },
6009 ),
6010 };
6011 break :task;
6012 };
60136011 if (coff.symbol_table.pending_symbol_index < coff.symbol_table.symbols.count()) {
60146012 defer coff.symbol_table.pending_symbol_index += 1;
60156013 const si = coff.symbol_table.symbols.keys()[coff.symbol_table.pending_symbol_index];
......@@ -6038,12 +6036,10 @@ fn resolve(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
60386036 }
60396037
60406038 if (coff.section_merge_pending_index < coff.section_merges.count()) return true;
6041 if (coff.pending_uavs.count() > 0) return true;
60426039 if (coff.pending_input != null) return true;
60436040 if (coff.exports_complete and coff.globals.count() > coff.global_pending_index) return true;
60446041 assert(!coff.exports_complete or coff.inputs_complete);
60456042 if (coff.exports_complete and coff.pending_special_symbol != .none) return true;
6046 for (&coff.lazy.values) |lazy| if (lazy.map.count() > lazy.pending_index) return true;
60476043 if (coff.symbol_table.pending_symbol_index < coff.symbol_table.symbols.count()) return true;
60486044 return false;
60496045}
......@@ -6153,7 +6149,47 @@ fn idleProgNode(
61536149 }, 0);
61546150}
61556151
6156fn flushUav(
6152fn genPending(coff: *Coff, pt: Zcu.PerThread) Error!void {
6153 const comp = pt.zcu.comp;
6154 while (coff.pending_uavs.pop()) |pending_uav| {
6155 const sub_prog_node = coff.idleProgNode(pt.tid, coff.const_prog_node, .{ .uav = pending_uav.key });
6156 defer sub_prog_node.end();
6157 coff.genUav(pt, pending_uav.key, pending_uav.value.alignment) catch |err| switch (err) {
6158 else => |e| return e,
6159 error.MappedFileIo => return comp.link_diags.fail(
6160 "linker failed to lower constant: {t}",
6161 .{coff.mf.io_err.?},
6162 ),
6163 };
6164 }
6165 var lazy_it = coff.lazy.iterator();
6166 while (lazy_it.next()) |lazy| if (lazy.value.pending_index < lazy.value.map.count()) {
6167 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = lazy.value.pending_index };
6168 lazy.value.pending_index += 1;
6169 const kind = switch (lmr.kind) {
6170 .code => "code",
6171 .const_data => "data",
6172 };
6173 var name: [std.Progress.Node.max_name_len]u8 = undefined;
6174 const sub_prog_node = coff.synth_prog_node.start(
6175 std.mem.print(&name, "lazy {s} for {f}", .{
6176 kind,
6177 Type.fromInterned(lmr.lazySymbol(coff).ty).fmt(pt),
6178 }) catch &name,
6179 0,
6180 );
6181 defer sub_prog_node.end();
6182 coff.genLazy(pt, lmr) catch |err| switch (err) {
6183 else => |e| return e,
6184 error.MappedFileIo => return comp.link_diags.fail(
6185 "linker failed to lower lazy {s}: {t}",
6186 .{ kind, coff.mf.io_err.? },
6187 ),
6188 };
6189 };
6190}
6191
6192fn genUav(
61576193 coff: *Coff,
61586194 pt: Zcu.PerThread,
61596195 umi: Node.UavMapIndex,
......@@ -6311,7 +6347,7 @@ fn flushGlobal(coff: *Coff, gmi: Node.GlobalMapIndex) !bool {
63116347 .{ name, imp_match }
63126348 else name: {
63136349 try coff.ensureUnusedStringCapacity(imp_prefix.len + name_slice.len);
6314 const imp_name = try std.fmt.allocPrint(gpa, imp_prefix ++ "{s}", .{name_slice});
6350 const imp_name = try gpa.print(imp_prefix ++ "{s}", .{name_slice});
63156351 defer gpa.free(imp_name);
63166352 break :name .{ coff.getOrPutStringAssumeCapacity(imp_name), true };
63176353 };
......@@ -6773,7 +6809,7 @@ fn flushSpecialSymbol(coff: *Coff, pending: SpecialSymbol) !SpecialSymbol {
67736809 };
67746810}
67756811
6776fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
6812fn genLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
67776813 const zcu = pt.zcu;
67786814 const gpa = zcu.gpa;
67796815
src/link/ConstPool.zig+10-5
......@@ -46,6 +46,7 @@ pub const Index = enum(u32) {
4646
4747pub const User = union(enum) {
4848 dwarf: *@import("Dwarf.zig"),
49 elf2: *@import("Elf2.zig"),
4950 c: *@import("C.zig"),
5051 llvm: @import("../codegen/llvm.zig").Object.Ptr,
5152
......@@ -73,7 +74,7 @@ pub const User = union(enum) {
7374 pt: Zcu.PerThread,
7475 index: Index,
7576 val: InternPool.Index,
76 ) Allocator.Error!void {
77 ) link.Error!void {
7778 switch (user) {
7879 inline else => |impl| return impl.updateConst(pt, index, val),
7980 }
......@@ -89,7 +90,7 @@ pub const User = union(enum) {
8990 pt: Zcu.PerThread,
9091 index: Index,
9192 val: InternPool.Index,
92 ) Allocator.Error!void {
93 ) link.Error!void {
9394 switch (user) {
9495 inline else => |impl| return impl.updateConstIncomplete(pt, index, val),
9596 }
......@@ -128,7 +129,7 @@ pub fn updateContainerType(
128129 user: User,
129130 container_ty: InternPool.Index,
130131 success: bool,
131) Allocator.Error!void {
132) link.Error!void {
132133 if (success) {
133134 const gpa = pt.zcu.comp.gpa;
134135 try pool.complete_containers.put(gpa, container_ty, {});
......@@ -160,13 +161,16 @@ pub fn get(pool: *ConstPool, pt: Zcu.PerThread, user: User, val: InternPool.Inde
160161 }
161162 return index;
162163}
163pub fn flushPending(pool: *ConstPool, pt: Zcu.PerThread, user: User) Allocator.Error!void {
164pub fn getIfExists(pool: *ConstPool, val: InternPool.Index) ?ConstPool.Index {
165 return @fromBackingInt(@intCast(pool.values.getIndex(val) orelse return null));
166}
167pub fn flushPending(pool: *ConstPool, pt: Zcu.PerThread, user: User) link.Error!void {
164168 while (pool.pending.pop()) |pending_ty| {
165169 try pool.update(pt, user, pending_ty);
166170 }
167171}
168172
169fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Index) Allocator.Error!void {
173fn update(pool: *ConstPool, pt: Zcu.PerThread, user: User, index: ConstPool.Index) link.Error!void {
170174 const zcu = pt.zcu;
171175 const ip = &zcu.intern_pool;
172176 const val = index.val(pool);
......@@ -286,5 +290,6 @@ const std = @import("std");
286290const Allocator = std.mem.Allocator;
287291
288292const InternPool = @import("../InternPool.zig");
293const link = @import("../link.zig");
289294const Type = @import("../Type.zig");
290295const Zcu = @import("../Zcu.zig");
src/link/Dwarf.zig+2-2
......@@ -2585,7 +2585,7 @@ pub fn initWipNav(
25852585 pt: Zcu.PerThread,
25862586 nav_index: InternPool.Nav.Index,
25872587 sym_index: link.File.SymbolId,
2588) error{ OutOfMemory, AlreadyReported }!WipNav {
2588) link.Error!WipNav {
25892589 return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {
25902590 error.OutOfMemory => error.OutOfMemory,
25912591 else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),
......@@ -3008,7 +3008,7 @@ fn finishWipNavWriterError(
30083008 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
30093009}
30103010
3011pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, AlreadyReported }!void {
3011pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void {
30123012 return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {
30133013 error.OutOfMemory => error.OutOfMemory,
30143014 else => |e| pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),
src/link/Elf.zig+1-3
......@@ -1677,9 +1677,7 @@ pub fn updateContainerType(
16771677 ty: InternPool.Index,
16781678 success: bool,
16791679) link.Error!void {
1680 return self.zigObjectPtr().?.updateContainerType(pt, ty, success) catch |err| switch (err) {
1681 error.OutOfMemory => |e| return e,
1682 };
1680 try self.zigObjectPtr().?.updateContainerType(pt, ty, success);
16831681}
16841682
16851683pub fn updateExports(
src/link/Elf2.zig+105-73
......@@ -174,16 +174,13 @@ uavs: std.array_hash_map.Auto(InternPool.Index, struct {
174174 first_symbol_reloc: SymbolReloc.Index,
175175 // No `first_got_reloc` field because a UAV never contains GOT relocations.
176176}),
177lazy: std.EnumArray(link.File.LazySymbol.Kind, struct {
178 map: std.array_hash_map.Auto(InternPool.Index, struct {
179 lsi: Symbol.LocalIndex,
180 /// The start index of the contiguous sequence of symbol relocations in this lazy code/data.
181 first_symbol_reloc: SymbolReloc.Index,
182 /// The start index of the contiguous sequence of GOT relocations in this lazy code/data.
183 first_got_reloc: GotReloc.Index,
184 }),
185 pending_index: u32,
186}),
177lazy: std.EnumArray(link.File.LazySymbol.Kind, std.array_hash_map.Auto(link.ConstPool.Index, struct {
178 lsi: Symbol.LocalIndex,
179 /// The start index of the contiguous sequence of symbol relocations in this lazy code/data.
180 first_symbol_reloc: SymbolReloc.Index,
181 /// The start index of the contiguous sequence of GOT relocations in this lazy code/data.
182 first_got_reloc: GotReloc.Index,
183})),
187184pending_uavs: std.ArrayList(Node.UavMapIndex),
188185symbol_relocs: std.ArrayList(SymbolReloc),
189186node_relocs: std.ArrayList(NodeReloc),
......@@ -240,7 +237,6 @@ overflowed_reloc_count: u32,
240237misaligned_reloc_count: u32,
241238
242239const_prog_node: std.Progress.Node,
243synth_prog_node: std.Progress.Node,
244240input_prog_node: std.Progress.Node,
245241
246242const Error = link.Error || error{MappedFileIo};
......@@ -408,20 +404,23 @@ const Node = union(enum) {
408404 }
409405
410406 fn firstSymbolReloc(lmi: @This(), elf: *const Elf) SymbolReloc.Index {
411 return elf.lazy.getPtrConst(kind).map.values()[@backingInt(lmi)].first_symbol_reloc;
407 return elf.lazy.getPtrConst(kind).values()[@backingInt(lmi)].first_symbol_reloc;
412408 }
413409 fn firstGotReloc(lmi: @This(), elf: *const Elf) GotReloc.Index {
414 return elf.lazy.getPtrConst(kind).map.values()[@backingInt(lmi)].first_got_reloc;
410 return elf.lazy.getPtrConst(kind).values()[@backingInt(lmi)].first_got_reloc;
415411 }
416412 };
417413 }
418414
419415 pub fn lazySymbol(lmr: LazyMapRef, elf: *const Elf) link.File.LazySymbol {
420 return .{ .kind = lmr.kind, .ty = elf.lazy.getPtrConst(lmr.kind).map.keys()[lmr.index] };
416 return .{
417 .kind = lmr.kind,
418 .ty = elf.lazy.getPtrConst(lmr.kind).keys()[lmr.index].val(&elf.dwarf.const_pool),
419 };
421420 }
422421
423422 pub fn symbol(lmr: LazyMapRef, elf: *const Elf) Symbol.LocalIndex {
424 return elf.lazy.getPtrConst(lmr.kind).map.values()[lmr.index].lsi;
423 return elf.lazy.getPtrConst(lmr.kind).values()[lmr.index].lsi;
425424 }
426425 };
427426
......@@ -3283,21 +3282,26 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
32833282 const s: Symbol.Id = .local(lsi);
32843283 return s.toTypeErased();
32853284}
3286pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) link.Error!link.File.SymbolId {
3285pub fn lazySymbol(
3286 elf: *Elf,
3287 pt: Zcu.PerThread,
3288 lazy: link.File.LazySymbol,
3289) link.Error!link.File.SymbolId {
32873290 const diags = &elf.base.comp.link_diags;
3288 return elf.lazySymbolInner(lazy) catch |err| switch (err) {
3291 return elf.lazySymbolInner(pt, lazy) catch |err| switch (err) {
32893292 else => |e| return e,
32903293 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
32913294 };
32923295}
3293fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId {
3296fn lazySymbolInner(elf: *Elf, pt: Zcu.PerThread, lazy: link.File.LazySymbol) Error!link.File.SymbolId {
32943297 const gpa = elf.base.comp.gpa;
32953298
32963299 try elf.ensureUnusedSymbolCapacity(1, .all_local);
32973300 try elf.nodes.ensureUnusedCapacity(gpa, 1);
3298 try elf.lazy.getPtr(lazy.kind).map.ensureUnusedCapacity(gpa, 1);
3301 try elf.lazy.getPtr(lazy.kind).ensureUnusedCapacity(gpa, 1);
32993302
3300 const gop = elf.lazy.getPtr(lazy.kind).map.getOrPutAssumeCapacity(lazy.ty);
3303 const cpi = try elf.dwarf.const_pool.get(pt, .{ .elf2 = elf }, lazy.ty);
3304 const gop = elf.lazy.getPtr(lazy.kind).getOrPutAssumeCapacity(cpi);
33013305 if (!gop.found_existing) {
33023306 const shndx: Section.Index, const sym_type: std.elf.STT = switch (lazy.kind) {
33033307 .code => .{ .text, .FUNC },
......@@ -3326,7 +3330,7 @@ fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.Symbol
33263330 .code => .{ .lazy_code = @fromBackingInt(@intCast(gop.index)) },
33273331 .const_data => .{ .lazy_const_data = @fromBackingInt(@intCast(gop.index)) },
33283332 });
3329 elf.synth_prog_node.increaseEstimatedTotalItems(1);
3333 elf.base.comp.link_prog_node.increaseEstimatedTotalItems(1);
33303334 }
33313335 const s: Symbol.Id = .local(gop.value_ptr.lsi);
33323336 return s.toTypeErased();
......@@ -3754,10 +3758,7 @@ fn create(
37543758 .one_shot_fixups = .empty,
37553759 .navs = .empty,
37563760 .uavs = .empty,
3757 .lazy = comptime .initFill(.{
3758 .map = .empty,
3759 .pending_index = 0,
3760 }),
3761 .lazy = comptime .initFill(.empty),
37613762 .pending_uavs = .empty,
37623763 .symbol_relocs = .empty,
37633764 .node_relocs = .empty,
......@@ -3772,7 +3773,7 @@ fn create(
37723773 .dwarf => |v| v,
37733774 .code_view => unreachable,
37743775 }),
3775 .dwarf_shared = .initFill(.{
3776 .dwarf_shared = comptime .initFill(.{
37763777 .first_target_reloc = .none,
37773778 }),
37783779 .dwarf_units = .empty,
......@@ -3784,7 +3785,6 @@ fn create(
37843785 .misaligned_reloc_count = 0,
37853786
37863787 .const_prog_node = .none,
3787 .synth_prog_node = .none,
37883788 .input_prog_node = .none,
37893789 };
37903790 errdefer elf.deinit();
......@@ -3820,7 +3820,7 @@ pub fn deinit(elf: *Elf) void {
38203820 elf.one_shot_fixups.deinit(gpa);
38213821 elf.navs.deinit(gpa);
38223822 elf.uavs.deinit(gpa);
3823 for (&elf.lazy.values) |*lazy| lazy.map.deinit(gpa);
3823 for (&elf.lazy.values) |*lazy| lazy.deinit(gpa);
38243824 elf.pending_uavs.deinit(gpa);
38253825 elf.symbol_relocs.deinit(gpa);
38263826 elf.node_relocs.deinit(gpa);
......@@ -5087,11 +5087,6 @@ fn initHeaders(
50875087pub fn startProgress(elf: *Elf, prog_node: std.Progress.Node) void {
50885088 prog_node.increaseEstimatedTotalItems(4);
50895089 elf.const_prog_node = prog_node.start("Constants", elf.pending_uavs.items.len);
5090 elf.synth_prog_node = prog_node.start("Synthetics", count: {
5091 var count: usize = 0;
5092 for (&elf.lazy.values) |*lazy| count += lazy.map.count() - lazy.pending_index;
5093 break :count count;
5094 });
50955090 elf.mf.update_prog_node = prog_node.start("Relocations", elf.mf.updates.items.len);
50965091 elf.input_prog_node = prog_node.start("Inputs", (elf.inputs.items.len - elf.input_pending_index) +
50975092 (elf.input_sections.items.len - elf.input_section_pending_index));
......@@ -5102,8 +5097,6 @@ pub fn endProgress(elf: *Elf) void {
51025097 elf.input_prog_node = .none;
51035098 elf.mf.update_prog_node.end();
51045099 elf.mf.update_prog_node = .none;
5105 elf.synth_prog_node.end();
5106 elf.synth_prog_node = .none;
51075100 elf.const_prog_node.end();
51085101 elf.const_prog_node = .none;
51095102}
......@@ -5267,8 +5260,8 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void {
52675260 .first_symbol_reloc = &elf.uavs.values()[@backingInt(umi)].first_symbol_reloc,
52685261 },
52695262 inline .lazy_code, .lazy_const_data => |lmi| .{
5270 .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_symbol_reloc,
5271 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).map.values()[lmi.ref().index].first_got_reloc,
5263 .first_symbol_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_symbol_reloc,
5264 .first_got_reloc = &elf.lazy.getPtr(lmi.ref().kind).values()[lmi.ref().index].first_got_reloc,
52725265 },
52735266 .unit_debug_info_header => |ui| .{
52745267 .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_node_reloc,
......@@ -8452,6 +8445,73 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
84528445 try elf.genPending(pt);
84538446}
84548447
8448pub fn updateContainerType(
8449 elf: *Elf,
8450 pt: Zcu.PerThread,
8451 ty: InternPool.Index,
8452 success: bool,
8453) link.Error!void {
8454 try elf.dwarf.const_pool.updateContainerType(pt, .{ .elf2 = elf }, ty, success);
8455}
8456
8457pub fn addConst(
8458 elf: *Elf,
8459 pt: Zcu.PerThread,
8460 index: link.ConstPool.Index,
8461 val: InternPool.Index,
8462) std.mem.Allocator.Error!void {
8463 if (false) try elf.dwarf.addConst(pt, index, val);
8464}
8465
8466pub fn updateConst(
8467 elf: *Elf,
8468 pt: Zcu.PerThread,
8469 cpi: link.ConstPool.Index,
8470 val: InternPool.Index,
8471) link.Error!void {
8472 if (val == .anyerror_type) return;
8473 try elf.updateConstInner(pt, cpi, val);
8474}
8475fn updateConstInner(
8476 elf: *Elf,
8477 pt: Zcu.PerThread,
8478 cpi: link.ConstPool.Index,
8479 val: InternPool.Index,
8480) link.Error!void {
8481 var lazy_it = elf.lazy.iterator();
8482 while (lazy_it.next()) |lazy| if (lazy.value.getIndex(cpi)) |li| {
8483 const lazy_ty: Type = .fromInterned(cpi.val(&elf.dwarf.const_pool));
8484 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;
8485 const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(pt.zcu)) {
8486 .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
8487 .error_set => switch (lazy.key) {
8488 .code => std.mem.print(&prog_name_buf, "@errorCast({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
8489 .const_data => "@errorName(anyerror)",
8490 },
8491 else => unreachable,
8492 };
8493 const prog_node = elf.base.comp.link_prog_node.start(prog_name, 0);
8494 defer prog_node.end();
8495 elf.genLazy(pt, .{ .kind = lazy.key, .index = @intCast(li) }) catch |err| switch (err) {
8496 else => |e| return e,
8497 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8498 "failed to write output file: {t}",
8499 .{elf.mf.io_err.?},
8500 ),
8501 };
8502 };
8503 if (false) try elf.dwarf.updateConst(pt, cpi, val);
8504}
8505
8506pub fn updateConstIncomplete(
8507 elf: *Elf,
8508 pt: Zcu.PerThread,
8509 cpi: link.ConstPool.Index,
8510 val: InternPool.Index,
8511) link.Error!void {
8512 if (false) try elf.dwarf.updateConstIncomplete(pt, cpi, val);
8513}
8514
84558515pub fn updateFunc(
84568516 elf: *Elf,
84578517 pt: Zcu.PerThread,
......@@ -8726,16 +8786,11 @@ fn updateFuncInner(
87268786}
87278787
87288788pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
8729 elf.genLazy(pt, .{
8730 .kind = .const_data,
8731 .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
8732 }) catch |err| switch (err) {
8733 else => |e| return e,
8734 error.MappedFileIo => return elf.base.comp.link_diags.fail(
8735 "failed to write output file: {t}",
8736 .{elf.mf.io_err.?},
8737 ),
8738 };
8789 try elf.updateConstInner(
8790 pt,
8791 elf.dwarf.const_pool.getIfExists(.anyerror_type) orelse return,
8792 .anyerror_type,
8793 );
87398794}
87408795
87418796pub fn flush(
......@@ -8782,8 +8837,7 @@ fn flushInner(
87828837 while (try elf.idle(tid)) {}
87838838
87848839 assert(elf.pending_uavs.items.len == 0);
8785 var lazy_it = elf.lazy.iterator();
8786 while (lazy_it.next()) |lazy| assert(lazy.value.pending_index == lazy.value.map.count());
8840 assert(elf.dwarf.const_pool.pending.items.len == 0);
87878841
87888842 // We've done the final `idle` loop, so everything is at its final place in the file. We have a
87898843 // few more things to check and write now that addresses and offsets are finalized.
......@@ -8844,9 +8898,7 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {
88448898 const diags = &comp.link_diags;
88458899
88468900 assert(elf.pending_uavs.items.len == 0);
8847 for (&elf.lazy.values) |*lazy| {
8848 assert(lazy.pending_index == lazy.map.count());
8849 }
8901 assert(elf.dwarf.const_pool.pending.items.len == 0);
88508902
88518903 task: {
88528904 if (elf.input_pending_index < elf.inputs.items.len) {
......@@ -9061,8 +9113,6 @@ fn idleProgNode(
90619113}
90629114
90639115fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void {
9064 const zcu = elf.base.comp.zcu.?;
9065
90669116 while (elf.pending_uavs.pop()) |umi| {
90679117 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;
90689118 const prog_name = std.mem.print(&prog_name_buf, "{f}", .{
......@@ -9072,25 +9122,7 @@ fn genPending(elf: *Elf, pt: Zcu.PerThread) Error!void {
90729122 defer prog_node.end();
90739123 try elf.genUav(pt, umi);
90749124 }
9075
9076 var lazy_it = elf.lazy.iterator();
9077 while (lazy_it.next()) |lazy| while (lazy.value.pending_index < lazy.value.map.count()) {
9078 const lmr: Node.LazyMapRef = .{ .kind = lazy.key, .index = lazy.value.pending_index };
9079 lazy.value.pending_index += 1;
9080 const lazy_ty: Type = .fromInterned(lmr.lazySymbol(elf).ty);
9081 var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined;
9082 const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(zcu)) {
9083 .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
9084 .error_set => switch (lmr.kind) {
9085 .code => std.mem.print(&prog_name_buf, "@errorCast({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf,
9086 .const_data => "@errorName",
9087 },
9088 else => unreachable,
9089 };
9090 const prog_node = elf.synth_prog_node.start(prog_name, 0);
9091 defer prog_node.end();
9092 try elf.genLazy(pt, lmr);
9093 };
9125 try elf.dwarf.const_pool.flushPending(pt, .{ .elf2 = elf });
90949126}
90959127
90969128fn genUav(
test/incremental/no_change_preserves_tag_names deleted-18
......@@ -1,18 +0,0 @@
1#update=initial version
2#file=main.zig
3const std = @import("std");
4var some_enum: enum { first, second } = .first;
5const io = std.Io.Threaded.global_single_threaded.io();
6pub fn main() !void {
7 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
8}
9#expect_stdout="first"
10#update=no change
11#file=main.zig
12const std = @import("std");
13var some_enum: enum { first, second } = .first;
14const io = std.Io.Threaded.global_single_threaded.io();
15pub fn main() !void {
16 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
17}
18#expect_stdout="first"
test/incremental/tag_name created+27
......@@ -0,0 +1,27 @@
1#update=initial version
2#file=main.zig
3const std = @import("std");
4var some_enum: enum { first, second } = .first;
5const io = std.Io.Threaded.global_single_threaded.io();
6pub fn main() !void {
7 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
8}
9#expect_stdout="first"
10#update=no change
11#file=main.zig
12const std = @import("std");
13var some_enum: enum { first, second } = .first;
14const io = std.Io.Threaded.global_single_threaded.io();
15pub fn main() !void {
16 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
17}
18#expect_stdout="first"
19#update=swap fields
20#file=main.zig
21const std = @import("std");
22var some_enum: enum { second, first } = .first;
23const io = std.Io.Threaded.global_single_threaded.io();
24pub fn main() !void {
25 try std.Io.File.stdout().writeStreamingAll(io, @tagName(some_enum));
26}
27#expect_stdout="first"