authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-01-04 00:32:28-05:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-01-05 02:20:56+00:00
logdde3116e50c0c5869c717f1eb480705165047be0
tree151ce66b74b958d7d5234cf6947c9589f3b5a132
parent065e10c95ccca509afecfecc849da9114e0000b2
signaturelock-open Commit is signed but in an unrecognized format.

Dwarf: implement new incremental line number update API


11 files changed, 856 insertions(+), 471 deletions(-)

change_line_number deleted-16
......@@ -1,16 +0,0 @@
1#target=x86_64-linux-selfhosted
2#update=initial version
3#file=main.zig
4const std = @import("std");
5pub fn main() !void {
6 try std.io.getStdOut().writeAll("foo\n");
7}
8#expect_stdout="foo\n"
9#update=change line number
10#file=main.zig
11const std = @import("std");
12
13pub fn main() !void {
14 try std.io.getStdOut().writeAll("foo\n");
15}
16#expect_stdout="foo\n"
ci/x86_64-linux-debug.sh+1-1
......@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \
6464
6565stage3-debug/bin/zig build test docs \
6666 --maxrss 21000000000 \
67 -Dlldb=$HOME/deps/lldb-zig/Debug-bfeada333/bin/lldb \
67 -Dlldb=$HOME/deps/lldb-zig/Debug-e0a42bb34/bin/lldb \
6868 -fqemu \
6969 -fwasmtime \
7070 -Dstatic-llvm \
ci/x86_64-linux-release.sh+1-1
......@@ -64,7 +64,7 @@ stage3-release/bin/zig build \
6464
6565stage3-release/bin/zig build test docs \
6666 --maxrss 21000000000 \
67 -Dlldb=$HOME/deps/lldb-zig/Release-bfeada333/bin/lldb \
67 -Dlldb=$HOME/deps/lldb-zig/Release-e0a42bb34/bin/lldb \
6868 -fqemu \
6969 -fwasmtime \
7070 -Dstatic-llvm \
src/InternPool.zig+7-1
......@@ -168,6 +168,8 @@ pub const TrackedInst = extern struct {
168168 _ => @enumFromInt(@intFromEnum(opt)),
169169 };
170170 }
171
172 const debug_state = InternPool.debug_state;
171173 };
172174
173175 pub const Unwrapped = struct {
......@@ -187,6 +189,8 @@ pub const TrackedInst = extern struct {
187189 .index = @intFromEnum(tracked_inst_index) & ip.getIndexMask(u32),
188190 };
189191 }
192
193 const debug_state = InternPool.debug_state;
190194 };
191195};
192196
......@@ -508,7 +512,7 @@ pub const Nav = struct {
508512 /// The fully-qualified name of this `Nav`.
509513 fqn: NullTerminatedString,
510514 /// This field is populated iff this `Nav` is resolved by semantic analysis.
511 /// If this is `null`, then `status == .resolved` always.
515 /// If this is `null`, then `status == .fully_resolved` always.
512516 analysis: ?struct {
513517 namespace: NamespaceIndex,
514518 zir_index: TrackedInst.Index,
......@@ -6631,6 +6635,8 @@ pub fn activate(ip: *const InternPool) void {
66316635 _ = OptionalString.debug_state;
66326636 _ = NullTerminatedString.debug_state;
66336637 _ = OptionalNullTerminatedString.debug_state;
6638 _ = TrackedInst.Index.debug_state;
6639 _ = TrackedInst.Index.Optional.debug_state;
66346640 _ = Nav.Index.debug_state;
66356641 _ = Nav.Index.Optional.debug_state;
66366642 std.debug.assert(debug_state.intern_pool == null);
src/link/Dwarf.zig+745-372
......@@ -8,6 +8,7 @@ mods: std.AutoArrayHashMapUnmanaged(*Module, ModInfo),
88types: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),
99values: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),
1010navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Entry.Index),
11decls: std.AutoArrayHashMapUnmanaged(InternPool.TrackedInst.Index, Entry.Index),
1112
1213debug_abbrev: DebugAbbrev,
1314debug_aranges: DebugAranges,
......@@ -51,9 +52,7 @@ pub const AddressSize = enum(u8) {
5152const ModInfo = struct {
5253 root_dir_path: Entry.Index,
5354 dirs: std.AutoArrayHashMapUnmanaged(Unit.Index, void),
54 files: Files,
55
56 const Files = std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void);
55 files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void),
5756
5857 fn deinit(mod_info: *ModInfo, gpa: std.mem.Allocator) void {
5958 mod_info.dirs.deinit(gpa);
......@@ -137,6 +136,20 @@ const DebugInfo = struct {
137136 return AbbrevCode.decl_bytes + dwarf.sectionOffsetBytes();
138137 }
139138
139 fn declAbbrevCode(debug_info: *DebugInfo, unit: Unit.Index, entry: Entry.Index) !AbbrevCode {
140 const dwarf: *Dwarf = @fieldParentPtr("debug_info", debug_info);
141 const unit_ptr = debug_info.section.getUnit(unit);
142 const entry_ptr = unit_ptr.getEntry(entry);
143 if (entry_ptr.len < AbbrevCode.decl_bytes) return .null;
144 var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined;
145 if (try dwarf.getFile().?.preadAll(
146 &abbrev_code_buf,
147 debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
148 ) != abbrev_code_buf.len) return error.InputOutput;
149 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
150 return @enumFromInt(std.leb.readUleb128(@typeInfo(AbbrevCode).@"enum".tag_type, abbrev_code_fbs.reader()) catch unreachable);
151 }
152
140153 const trailer_bytes = 1 + 1;
141154};
142155
......@@ -206,8 +219,8 @@ const StringSection = struct {
206219 const unit: Unit.Index = @enumFromInt(0);
207220
208221 const init: StringSection = .{
209 .contents = .{},
210 .map = .{},
222 .contents = .empty,
223 .map = .empty,
211224 .section = Section.init,
212225 };
213226
......@@ -219,9 +232,9 @@ const StringSection = struct {
219232
220233 fn addString(str_sec: *StringSection, dwarf: *Dwarf, str: []const u8) UpdateError!Entry.Index {
221234 const gop = try str_sec.map.getOrPutAdapted(dwarf.gpa, str, Adapter{ .str_sec = str_sec });
222 errdefer _ = str_sec.map.pop();
223235 const entry: Entry.Index = @enumFromInt(gop.index);
224236 if (!gop.found_existing) {
237 errdefer _ = str_sec.map.pop();
225238 const unit_ptr = str_sec.section.getUnit(unit);
226239 assert(try str_sec.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
227240 errdefer _ = unit_ptr.entries.pop();
......@@ -284,7 +297,7 @@ pub const Section = struct {
284297 .index = std.math.maxInt(u32),
285298 .first = .none,
286299 .last = .none,
287 .units = .{},
300 .units = .empty,
288301 .len = 0,
289302 };
290303
......@@ -319,13 +332,14 @@ pub const Section = struct {
319332 .next = .none,
320333 .first = .none,
321334 .last = .none,
335 .free = .none,
322336 .header_len = aligned_header_len,
323337 .trailer_len = aligned_trailer_len,
324338 .off = 0,
325339 .len = aligned_header_len + aligned_trailer_len,
326 .entries = .{},
327 .cross_unit_relocs = .{},
328 .cross_section_relocs = .{},
340 .entries = .empty,
341 .cross_unit_relocs = .empty,
342 .cross_section_relocs = .empty,
329343 };
330344 if (sec.last.unwrap()) |last_unit| {
331345 const last_unit_ptr = sec.getUnit(last_unit);
......@@ -385,6 +399,28 @@ pub const Section = struct {
385399 try unit_ptr.getEntry(entry).replace(unit_ptr, sec, dwarf, contents);
386400 }
387401
402 fn freeEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf) UpdateError!void {
403 const unit_ptr = sec.getUnit(unit);
404 const entry_ptr = unit_ptr.getEntry(entry);
405 if (entry_ptr.len > 0) {
406 if (entry_ptr.next.unwrap()) |next_entry| unit_ptr.getEntry(next_entry).prev = entry_ptr.prev;
407 if (entry_ptr.prev.unwrap()) |prev_entry| {
408 const prev_entry_ptr = unit_ptr.getEntry(prev_entry);
409 prev_entry_ptr.next = entry_ptr.next;
410 try prev_entry_ptr.pad(unit_ptr, sec, dwarf);
411 } else {
412 unit_ptr.trim();
413 sec.trim(dwarf);
414 }
415 } else assert(entry_ptr.prev == .none and entry_ptr.next == .none);
416 entry_ptr.prev = .none;
417 entry_ptr.next = unit_ptr.free;
418 entry_ptr.off = 0;
419 entry_ptr.len = 0;
420 entry_ptr.clear();
421 unit_ptr.free = entry.toOptional();
422 }
423
388424 fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {
389425 if (len <= sec.len) return;
390426 if (dwarf.bin_file.cast(.elf)) |elf_file| {
......@@ -449,6 +485,7 @@ const Unit = struct {
449485 next: Index.Optional,
450486 first: Entry.Index.Optional,
451487 last: Entry.Index.Optional,
488 free: Entry.Index.Optional,
452489 /// offset within containing section
453490 off: u32,
454491 header_len: u32,
......@@ -491,6 +528,12 @@ const Unit = struct {
491528 }
492529
493530 fn addEntry(unit: *Unit, gpa: std.mem.Allocator) std.mem.Allocator.Error!Entry.Index {
531 if (unit.free.unwrap()) |entry| {
532 const entry_ptr = unit.getEntry(entry);
533 unit.free = entry_ptr.next;
534 entry_ptr.next = .none;
535 return entry;
536 }
494537 const entry: Entry.Index = @enumFromInt(unit.entries.items.len);
495538 const entry_ptr = try unit.entries.addOne(gpa);
496539 entry_ptr.* = .{
......@@ -498,10 +541,10 @@ const Unit = struct {
498541 .next = .none,
499542 .off = 0,
500543 .len = 0,
501 .cross_entry_relocs = .{},
502 .cross_unit_relocs = .{},
503 .cross_section_relocs = .{},
504 .external_relocs = .{},
544 .cross_entry_relocs = .empty,
545 .cross_unit_relocs = .empty,
546 .cross_section_relocs = .empty,
547 .external_relocs = .empty,
505548 };
506549 return entry;
507550 }
......@@ -1583,7 +1626,7 @@ pub const WipNav = struct {
15831626 const dlw = wip_nav.debug_line.writer(dwarf.gpa);
15841627 if (dwarf.incremental()) {
15851628 const new_nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, new_func_info.owner_nav);
1586 errdefer _ = dwarf.navs.pop();
1629 errdefer _ = if (!new_nav_gop.found_existing) dwarf.navs.pop();
15871630 if (!new_nav_gop.found_existing) new_nav_gop.value_ptr.* = try dwarf.addCommonEntry(new_unit);
15881631
15891632 try dlw.writeByte(DW.LNS.extended_op);
......@@ -1603,10 +1646,8 @@ pub const WipNav = struct {
16031646 const old_file = zcu.navFileScopeIndex(old_func_info.owner_nav);
16041647 if (old_file != new_file) {
16051648 const mod_info = dwarf.getModInfo(wip_nav.unit);
1606 const mod_gop = try mod_info.dirs.getOrPut(dwarf.gpa, new_unit);
1607 errdefer _ = if (!mod_gop.found_existing) mod_info.dirs.pop();
1649 try mod_info.dirs.put(dwarf.gpa, new_unit, {});
16081650 const file_gop = try mod_info.files.getOrPut(dwarf.gpa, new_file);
1609 errdefer _ = if (!file_gop.found_existing) mod_info.files.pop();
16101651
16111652 try dlw.writeByte(DW.LNS.set_file);
16121653 try uleb128(dlw, file_gop.index);
......@@ -1934,6 +1975,90 @@ pub const WipNav = struct {
19341975 std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());
19351976 }
19361977
1978 fn declCommon(
1979 wip_nav: *WipNav,
1980 abbrev_code: struct {
1981 decl: AbbrevCode,
1982 generic_decl: AbbrevCode,
1983 instance: AbbrevCode,
1984 },
1985 nav: *const InternPool.Nav,
1986 file: Zcu.File.Index,
1987 decl: *const std.zig.Zir.Inst.Declaration.Unwrapped,
1988 ) UpdateError!void {
1989 const zcu = wip_nav.pt.zcu;
1990 const ip = &zcu.intern_pool;
1991 const dwarf = wip_nav.dwarf;
1992 const diw = wip_nav.debug_info.writer(dwarf.gpa);
1993
1994 const orig_entry = wip_nav.entry;
1995 defer wip_nav.entry = orig_entry;
1996 const parent_type, const is_generic_decl = if (nav.analysis) |analysis| parent_info: {
1997 const parent_type: Type = .fromInterned(zcu.namespacePtr(analysis.namespace).owner_type);
1998 const decl_gop = try dwarf.decls.getOrPut(dwarf.gpa, analysis.zir_index);
1999 errdefer _ = if (!decl_gop.found_existing) dwarf.decls.pop();
2000 const was_generic_decl = decl_gop.found_existing and
2001 switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, decl_gop.value_ptr.*)) {
2002 else => unreachable,
2003 .decl_alias,
2004 .decl_enum,
2005 .decl_empty_enum,
2006 .decl_namespace_struct,
2007 .decl_struct,
2008 .decl_packed_struct,
2009 .decl_union,
2010 .decl_var,
2011 .decl_const,
2012 .decl_const_runtime_bits,
2013 .decl_const_comptime_state,
2014 .decl_const_runtime_bits_comptime_state,
2015 .decl_func,
2016 .decl_empty_func,
2017 .decl_func_generic,
2018 .decl_empty_func_generic,
2019 => false,
2020 .generic_decl_alias,
2021 .generic_decl_enum,
2022 .generic_decl_struct,
2023 .generic_decl_union,
2024 .generic_decl_var,
2025 .generic_decl_const,
2026 .generic_decl_func,
2027 => true,
2028 };
2029 if (parent_type.getCaptures(zcu).len == 0) {
2030 if (was_generic_decl) try dwarf.freeCommonEntry(wip_nav.unit, decl_gop.value_ptr.*);
2031 decl_gop.value_ptr.* = orig_entry;
2032 break :parent_info .{ parent_type, false };
2033 } else {
2034 if (was_generic_decl)
2035 dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(decl_gop.value_ptr.*).clear()
2036 else
2037 decl_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
2038 wip_nav.entry = decl_gop.value_ptr.*;
2039 break :parent_info .{ parent_type, true };
2040 }
2041 } else .{ null, false };
2042
2043 try wip_nav.abbrevCode(if (is_generic_decl) abbrev_code.generic_decl else abbrev_code.decl);
2044 try wip_nav.refType((if (is_generic_decl) null else parent_type) orelse
2045 .fromInterned(zcu.fileRootType(file)));
2046 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2047 try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
2048 try uleb128(diw, decl.src_column + 1);
2049 try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2050 try wip_nav.strp(nav.name.toSlice(ip));
2051
2052 if (!is_generic_decl) return;
2053 const generic_decl_entry = wip_nav.entry;
2054 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, generic_decl_entry, dwarf, wip_nav.debug_info.items);
2055 wip_nav.debug_info.clearRetainingCapacity();
2056 wip_nav.entry = orig_entry;
2057 try wip_nav.abbrevCode(abbrev_code.instance);
2058 try wip_nav.refType(parent_type.?);
2059 try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, generic_decl_entry, 0);
2060 }
2061
19372062 fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) UpdateError!void {
19382063 const ip = &wip_nav.pt.zcu.intern_pool;
19392064 while (wip_nav.pending_lazy.popOrNull()) |val| switch (ip.typeOf(val)) {
......@@ -1966,10 +2091,11 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
19662091 },
19672092 .endian = target.cpu.arch.endian(),
19682093
1969 .mods = .{},
1970 .types = .{},
1971 .values = .{},
1972 .navs = .{},
2094 .mods = .empty,
2095 .types = .empty,
2096 .values = .empty,
2097 .navs = .empty,
2098 .decls = .empty,
19732099
19742100 .debug_abbrev = .{ .section = Section.init },
19752101 .debug_aranges = .{ .section = Section.init },
......@@ -2142,6 +2268,7 @@ pub fn deinit(dwarf: *Dwarf) void {
21422268 dwarf.types.deinit(gpa);
21432269 dwarf.values.deinit(gpa);
21442270 dwarf.navs.deinit(gpa);
2271 dwarf.decls.deinit(gpa);
21452272 dwarf.debug_abbrev.section.deinit(gpa);
21462273 dwarf.debug_aranges.section.deinit(gpa);
21472274 dwarf.debug_frame.section.deinit(gpa);
......@@ -2161,8 +2288,8 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
21612288 errdefer _ = dwarf.mods.pop();
21622289 mod_gop.value_ptr.* = .{
21632290 .root_dir_path = undefined,
2164 .dirs = .{},
2165 .files = .{},
2291 .dirs = .empty,
2292 .files = .empty,
21662293 };
21672294 errdefer mod_gop.value_ptr.dirs.deinit(dwarf.gpa);
21682295 try mod_gop.value_ptr.dirs.putNoClobber(dwarf.gpa, unit, {});
......@@ -2219,14 +2346,28 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
22192346 const ip = &zcu.intern_pool;
22202347
22212348 const nav = ip.getNav(nav_index);
2222 log.debug("initWipNav({})", .{nav.fqn.fmt(ip)});
2223
22242349 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
22252350 const file = zcu.fileByIndex(inst_info.file);
2351 assert(file.zir_loaded);
2352 const decl = file.zir.getDeclaration(inst_info.inst);
2353 log.debug("initWipNav({s}:{d}:{d} %{d} = {})", .{
2354 file.sub_file_path,
2355 decl.src_line + 1,
2356 decl.src_column + 1,
2357 @intFromEnum(inst_info.inst),
2358 nav.fqn.fmt(ip),
2359 });
2360
2361 const nav_val = zcu.navValue(nav_index);
2362 const nav_key = ip.indexToKey(nav_val.toIntern());
2363 switch (nav_key) {
2364 .@"extern" => return null,
2365 else => {},
2366 }
22262367
22272368 const unit = try dwarf.getUnit(file.mod);
22282369 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
2229 errdefer _ = dwarf.navs.pop();
2370 errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop();
22302371 if (nav_gop.found_existing) {
22312372 for ([_]*Section{
22322373 &dwarf.debug_aranges.section,
......@@ -2236,7 +2377,6 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
22362377 &dwarf.debug_rnglists.section,
22372378 }) |sec| sec.getUnit(unit).getEntry(nav_gop.value_ptr.*).clear();
22382379 } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
2239 const nav_val = zcu.navValue(nav_index);
22402380 var wip_nav: WipNav = .{
22412381 .dwarf = dwarf,
22422382 .pt = pt,
......@@ -2248,91 +2388,52 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
22482388 .func_high_pc = undefined,
22492389 .blocks = undefined,
22502390 .cfi = undefined,
2251 .debug_frame = .{},
2252 .debug_info = .{},
2253 .debug_line = .{},
2254 .debug_loclists = .{},
2255 .pending_lazy = .{},
2391 .debug_frame = .empty,
2392 .debug_info = .empty,
2393 .debug_line = .empty,
2394 .debug_loclists = .empty,
2395 .pending_lazy = .empty,
22562396 };
22572397 errdefer wip_nav.deinit();
22582398
2259 switch (ip.indexToKey(nav_val.toIntern())) {
2399 switch (nav_key) {
22602400 else => {
2261 assert(file.zir_loaded);
2262 const decl = file.zir.getDeclaration(inst_info.inst);
2263
2264 const parent_type, const accessibility: u8 = if (nav.analysis) |a| parent: {
2265 const parent_namespace_ptr = ip.namespacePtr(a.namespace);
2266 break :parent .{
2267 parent_namespace_ptr.owner_type,
2268 if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private,
2269 };
2270 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
2271
22722401 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2273 try wip_nav.abbrevCode(.decl_var);
2274 try wip_nav.refType(.fromInterned(parent_type));
2275 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2276 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2277 try uleb128(diw, decl.src_column + 1);
2278 try diw.writeByte(accessibility);
2279 try wip_nav.strp(nav.name.toSlice(ip));
2402 try wip_nav.declCommon(.{
2403 .decl = .decl_var,
2404 .generic_decl = .generic_decl_var,
2405 .instance = .instance_var,
2406 }, &nav, inst_info.file, &decl);
22802407 try wip_nav.strp(nav.fqn.toSlice(ip));
2281 const nav_ty = nav_val.typeOf(zcu);
2282 const nav_ty_reloc_index = try wip_nav.refForward();
2283 try wip_nav.infoExprloc(.{ .addr = .{ .sym = sym_index } });
2284 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
2285 nav_ty.abiAlignment(zcu).toByteUnits().?);
2286 try diw.writeByte(@intFromBool(false));
2287 wip_nav.finishForward(nav_ty_reloc_index);
2288 try wip_nav.abbrevCode(.is_const);
2289 try wip_nav.refType(nav_ty);
2290 },
2291 .variable => |variable| {
2292 assert(file.zir_loaded);
2293 const decl = file.zir.getDeclaration(inst_info.inst);
2294
2295 const parent_type, const accessibility: u8 = if (nav.analysis) |a| parent: {
2296 const parent_namespace_ptr = ip.namespacePtr(a.namespace);
2297 break :parent .{
2298 parent_namespace_ptr.owner_type,
2299 if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private,
2300 };
2301 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
2302
2303 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2304 try wip_nav.abbrevCode(.decl_var);
2305 try wip_nav.refType(.fromInterned(parent_type));
2306 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2307 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2308 try uleb128(diw, decl.src_column + 1);
2309 try diw.writeByte(accessibility);
2310 try wip_nav.strp(nav.name.toSlice(ip));
2311 try wip_nav.strp(nav.fqn.toSlice(ip));
2312 const ty: Type = .fromInterned(variable.ty);
2313 try wip_nav.refType(ty);
2408 const ty: Type = nav_val.typeOf(zcu);
23142409 const addr: Loc = .{ .addr = .{ .sym = sym_index } };
2315 try wip_nav.infoExprloc(if (variable.is_threadlocal) .{ .form_tls_address = &addr } else addr);
2316 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
2317 ty.abiAlignment(zcu).toByteUnits().?);
2318 try diw.writeByte(@intFromBool(false));
2410 const loc: Loc = if (decl.is_threadlocal) .{ .form_tls_address = &addr } else addr;
2411 switch (decl.kind) {
2412 .unnamed_test, .@"test", .decltest, .@"comptime", .@"usingnamespace" => unreachable,
2413 .@"const" => {
2414 const const_ty_reloc_index = try wip_nav.refForward();
2415 try wip_nav.infoExprloc(loc);
2416 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
2417 ty.abiAlignment(zcu).toByteUnits().?);
2418 try diw.writeByte(@intFromBool(decl.linkage != .normal));
2419 wip_nav.finishForward(const_ty_reloc_index);
2420 try wip_nav.abbrevCode(.is_const);
2421 try wip_nav.refType(ty);
2422 },
2423 .@"var" => {
2424 try wip_nav.refType(ty);
2425 try wip_nav.infoExprloc(loc);
2426 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
2427 ty.abiAlignment(zcu).toByteUnits().?);
2428 try diw.writeByte(@intFromBool(decl.linkage != .normal));
2429 },
2430 }
23192431 },
23202432 .func => |func| {
2321 assert(file.zir_loaded);
2322 const decl = file.zir.getDeclaration(inst_info.inst);
2323
2324 const parent_type, const accessibility: u8 = if (nav.analysis) |a| parent: {
2325 const parent_namespace_ptr = ip.namespacePtr(a.namespace);
2326 break :parent .{
2327 parent_namespace_ptr.owner_type,
2328 if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private,
2329 };
2330 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
2331
23322433 const func_type = ip.indexToKey(func.ty).func_type;
23332434 wip_nav.func = nav_val.toIntern();
23342435 wip_nav.func_sym_index = sym_index;
2335 wip_nav.blocks = .{};
2436 wip_nav.blocks = .empty;
23362437 if (dwarf.debug_frame.header.format != .none) wip_nav.cfi = .{
23372438 .loc = 0,
23382439 .cfa = dwarf.debug_frame.header.initial_instructions[0].def_cfa,
......@@ -2375,13 +2476,11 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
23752476 }
23762477
23772478 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2378 try wip_nav.abbrevCode(.decl_func);
2379 try wip_nav.refType(.fromInterned(parent_type));
2380 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2381 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2382 try uleb128(diw, decl.src_column + 1);
2383 try diw.writeByte(accessibility);
2384 try wip_nav.strp(nav.name.toSlice(ip));
2479 try wip_nav.declCommon(.{
2480 .decl = .decl_func,
2481 .generic_decl = .generic_decl_func,
2482 .instance = .instance_func,
2483 }, &nav, inst_info.file, &decl);
23852484 try wip_nav.strp(nav.fqn.toSlice(ip));
23862485 try wip_nav.refType(.fromInterned(func_type.return_type));
23872486 try wip_nav.infoAddrSym(sym_index, 0);
......@@ -2392,7 +2491,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
23922491 .none => target_info.defaultFunctionAlignment(target),
23932492 else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),
23942493 }.toByteUnits().?);
2395 try diw.writeByte(@intFromBool(false));
2494 try diw.writeByte(@intFromBool(decl.linkage != .normal));
23962495 try diw.writeByte(@intFromBool(func_type.return_type == .noreturn_type));
23972496
23982497 const dlw = wip_nav.debug_line.writer(dwarf.gpa);
......@@ -2435,97 +2534,110 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
24352534 return wip_nav;
24362535}
24372536
2438pub fn finishWipNav(
2537pub fn finishWipNavFunc(
24392538 dwarf: *Dwarf,
24402539 pt: Zcu.PerThread,
24412540 nav_index: InternPool.Nav.Index,
2442 sym: struct { index: u32, addr: u64, size: u64 },
2541 code_size: u64,
24432542 wip_nav: *WipNav,
24442543) UpdateError!void {
24452544 const zcu = pt.zcu;
24462545 const ip = &zcu.intern_pool;
24472546 const nav = ip.getNav(nav_index);
2448 log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)});
2547 assert(wip_nav.func != .none);
2548 log.debug("finishWipNavFunc({})", .{nav.fqn.fmt(ip)});
24492549
2450 if (wip_nav.func != .none) {
2451 {
2452 const external_relocs = &dwarf.debug_aranges.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
2453 try external_relocs.append(dwarf.gpa, .{ .target_sym = sym.index });
2454 var entry: [8 + 8]u8 = undefined;
2455 @memset(entry[0..@intFromEnum(dwarf.address_size)], 0);
2456 dwarf.writeInt(entry[@intFromEnum(dwarf.address_size)..][0..@intFromEnum(dwarf.address_size)], sym.size);
2457 try dwarf.debug_aranges.section.replaceEntry(
2458 wip_nav.unit,
2459 wip_nav.entry,
2460 dwarf,
2461 entry[0 .. @intFromEnum(dwarf.address_size) * 2],
2462 );
2463 }
2464 switch (dwarf.debug_frame.header.format) {
2465 .none => {},
2466 .debug_frame, .eh_frame => |format| {
2467 try wip_nav.debug_frame.appendNTimes(
2468 dwarf.gpa,
2469 DW.CFA.nop,
2470 @intCast(dwarf.debug_frame.section.alignment.forward(wip_nav.debug_frame.items.len) - wip_nav.debug_frame.items.len),
2471 );
2472 const contents = wip_nav.debug_frame.items;
2473 try dwarf.debug_frame.section.resizeEntry(wip_nav.unit, wip_nav.entry, dwarf, @intCast(contents.len));
2474 const unit = dwarf.debug_frame.section.getUnit(wip_nav.unit);
2475 const entry = unit.getEntry(wip_nav.entry);
2476 const unit_len = (if (entry.next.unwrap()) |next_entry|
2477 unit.getEntry(next_entry).off - entry.off
2478 else
2479 entry.len) - dwarf.unitLengthBytes();
2480 dwarf.writeInt(contents[dwarf.unitLengthBytes() - dwarf.sectionOffsetBytes() ..][0..dwarf.sectionOffsetBytes()], unit_len);
2481 switch (format) {
2482 .none => unreachable,
2483 .debug_frame => dwarf.writeInt(contents[dwarf.unitLengthBytes() + dwarf.sectionOffsetBytes() +
2484 @intFromEnum(dwarf.address_size) ..][0..@intFromEnum(dwarf.address_size)], sym.size),
2485 .eh_frame => {
2486 std.mem.writeInt(
2487 u32,
2488 contents[dwarf.unitLengthBytes()..][0..4],
2489 unit.header_len + entry.off + dwarf.unitLengthBytes(),
2490 dwarf.endian,
2491 );
2492 std.mem.writeInt(u32, contents[dwarf.unitLengthBytes() + 4 + 4 ..][0..4], @intCast(sym.size), dwarf.endian);
2493 },
2494 }
2495 try entry.replace(unit, &dwarf.debug_frame.section, dwarf, contents);
2496 },
2497 }
2498 {
2499 std.mem.writeInt(u32, wip_nav.debug_info.items[wip_nav.func_high_pc..][0..4], @intCast(sym.size), dwarf.endian);
2500 if (wip_nav.any_children) {
2501 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2502 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2503 } else std.leb.writeUnsignedFixed(
2504 AbbrevCode.decl_bytes,
2505 wip_nav.debug_info.items[0..AbbrevCode.decl_bytes],
2506 try dwarf.refAbbrevCode(.decl_empty_func),
2550 {
2551 const external_relocs = &dwarf.debug_aranges.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
2552 try external_relocs.append(dwarf.gpa, .{ .target_sym = wip_nav.func_sym_index });
2553 var entry: [8 + 8]u8 = undefined;
2554 @memset(entry[0..@intFromEnum(dwarf.address_size)], 0);
2555 dwarf.writeInt(entry[@intFromEnum(dwarf.address_size)..][0..@intFromEnum(dwarf.address_size)], code_size);
2556 try dwarf.debug_aranges.section.replaceEntry(
2557 wip_nav.unit,
2558 wip_nav.entry,
2559 dwarf,
2560 entry[0 .. @intFromEnum(dwarf.address_size) * 2],
2561 );
2562 }
2563 switch (dwarf.debug_frame.header.format) {
2564 .none => {},
2565 .debug_frame, .eh_frame => |format| {
2566 try wip_nav.debug_frame.appendNTimes(
2567 dwarf.gpa,
2568 DW.CFA.nop,
2569 @intCast(dwarf.debug_frame.section.alignment.forward(wip_nav.debug_frame.items.len) - wip_nav.debug_frame.items.len),
25072570 );
2508 }
2509 {
2510 try dwarf.debug_rnglists.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.appendSlice(dwarf.gpa, &.{
2511 .{
2512 .source_off = 1,
2513 .target_sym = sym.index,
2514 },
2515 .{
2516 .source_off = 1 + @intFromEnum(dwarf.address_size),
2517 .target_sym = sym.index,
2518 .target_off = sym.size,
2571 const contents = wip_nav.debug_frame.items;
2572 try dwarf.debug_frame.section.resizeEntry(wip_nav.unit, wip_nav.entry, dwarf, @intCast(contents.len));
2573 const unit = dwarf.debug_frame.section.getUnit(wip_nav.unit);
2574 const entry = unit.getEntry(wip_nav.entry);
2575 const unit_len = (if (entry.next.unwrap()) |next_entry|
2576 unit.getEntry(next_entry).off - entry.off
2577 else
2578 entry.len) - dwarf.unitLengthBytes();
2579 dwarf.writeInt(contents[dwarf.unitLengthBytes() - dwarf.sectionOffsetBytes() ..][0..dwarf.sectionOffsetBytes()], unit_len);
2580 switch (format) {
2581 .none => unreachable,
2582 .debug_frame => dwarf.writeInt(contents[dwarf.unitLengthBytes() + dwarf.sectionOffsetBytes() +
2583 @intFromEnum(dwarf.address_size) ..][0..@intFromEnum(dwarf.address_size)], code_size),
2584 .eh_frame => {
2585 std.mem.writeInt(
2586 u32,
2587 contents[dwarf.unitLengthBytes()..][0..4],
2588 unit.header_len + entry.off + dwarf.unitLengthBytes(),
2589 dwarf.endian,
2590 );
2591 std.mem.writeInt(u32, contents[dwarf.unitLengthBytes() + 4 + 4 ..][0..4], @intCast(code_size), dwarf.endian);
25192592 },
2520 });
2521 try dwarf.debug_rnglists.section.replaceEntry(
2522 wip_nav.unit,
2523 wip_nav.entry,
2524 dwarf,
2525 ([1]u8{DW.RLE.start_end} ++ [1]u8{0} ** (8 + 8))[0 .. 1 + @intFromEnum(dwarf.address_size) + @intFromEnum(dwarf.address_size)],
2526 );
2527 }
2593 }
2594 try entry.replace(unit, &dwarf.debug_frame.section, dwarf, contents);
2595 },
25282596 }
2597 {
2598 std.mem.writeInt(u32, wip_nav.debug_info.items[wip_nav.func_high_pc..][0..4], @intCast(code_size), dwarf.endian);
2599 if (wip_nav.any_children) {
2600 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2601 try uleb128(diw, @intFromEnum(AbbrevCode.null));
2602 } else std.leb.writeUnsignedFixed(
2603 AbbrevCode.decl_bytes,
2604 wip_nav.debug_info.items[0..AbbrevCode.decl_bytes],
2605 try dwarf.refAbbrevCode(.decl_empty_func),
2606 );
2607 }
2608 {
2609 try dwarf.debug_rnglists.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.appendSlice(dwarf.gpa, &.{
2610 .{
2611 .source_off = 1,
2612 .target_sym = wip_nav.func_sym_index,
2613 },
2614 .{
2615 .source_off = 1 + @intFromEnum(dwarf.address_size),
2616 .target_sym = wip_nav.func_sym_index,
2617 .target_off = code_size,
2618 },
2619 });
2620 try dwarf.debug_rnglists.section.replaceEntry(
2621 wip_nav.unit,
2622 wip_nav.entry,
2623 dwarf,
2624 ([1]u8{DW.RLE.start_end} ++ [1]u8{0} ** (8 + 8))[0 .. 1 + @intFromEnum(dwarf.address_size) + @intFromEnum(dwarf.address_size)],
2625 );
2626 }
2627
2628 try dwarf.finishWipNav(pt, nav_index, wip_nav);
2629}
2630
2631pub fn finishWipNav(
2632 dwarf: *Dwarf,
2633 pt: Zcu.PerThread,
2634 nav_index: InternPool.Nav.Index,
2635 wip_nav: *WipNav,
2636) UpdateError!void {
2637 const zcu = pt.zcu;
2638 const ip = &zcu.intern_pool;
2639 const nav = ip.getNav(nav_index);
2640 log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)});
25292641
25302642 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
25312643 if (wip_nav.debug_line.items.len > 0) {
......@@ -2547,12 +2659,17 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
25472659 const nav_val = zcu.navValue(nav_index);
25482660
25492661 const nav = ip.getNav(nav_index);
2550 log.debug("updateComptimeNav({})", .{nav.fqn.fmt(ip)});
2551
25522662 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
25532663 const file = zcu.fileByIndex(inst_info.file);
25542664 assert(file.zir_loaded);
25552665 const decl = file.zir.getDeclaration(inst_info.inst);
2666 log.debug("updateComptimeNav({s}:{d}:{d} %{d} = {})", .{
2667 file.sub_file_path,
2668 decl.src_line + 1,
2669 decl.src_column + 1,
2670 @intFromEnum(inst_info.inst),
2671 nav.fqn.fmt(ip),
2672 });
25562673
25572674 const is_test = switch (decl.kind) {
25582675 .unnamed_test, .@"test", .decltest => true,
......@@ -2563,14 +2680,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
25632680 return;
25642681 }
25652682
2566 const parent_type, const accessibility: u8 = if (nav.analysis) |a| parent: {
2567 const parent_namespace_ptr = ip.namespacePtr(a.namespace);
2568 break :parent .{
2569 parent_namespace_ptr.owner_type,
2570 if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private,
2571 };
2572 } else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
2573
25742683 var wip_nav: WipNav = .{
25752684 .dwarf = dwarf,
25762685 .pt = pt,
......@@ -2582,16 +2691,16 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
25822691 .func_high_pc = undefined,
25832692 .blocks = undefined,
25842693 .cfi = undefined,
2585 .debug_frame = .{},
2586 .debug_info = .{},
2587 .debug_line = .{},
2588 .debug_loclists = .{},
2589 .pending_lazy = .{},
2694 .debug_frame = .empty,
2695 .debug_info = .empty,
2696 .debug_line = .empty,
2697 .debug_loclists = .empty,
2698 .pending_lazy = .empty,
25902699 };
25912700 defer wip_nav.deinit();
25922701
25932702 const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
2594 errdefer _ = dwarf.navs.pop();
2703 errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop();
25952704
25962705 const tag: enum { done, decl_alias, decl_var, decl_const } = switch (ip.indexToKey(nav_val.toIntern())) {
25972706 .int_type,
......@@ -2609,9 +2718,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
26092718 => .decl_alias,
26102719 .struct_type => tag: {
26112720 const loaded_struct = ip.loadStructType(nav_val.toIntern());
2612
2613 const type_inst_info = loaded_struct.zir_index.resolveFull(ip).?;
2614 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
2721 if (loaded_struct.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
26152722
26162723 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
26172724 if (type_gop.found_existing) {
......@@ -2630,13 +2737,15 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
26302737
26312738 switch (loaded_struct.layout) {
26322739 .auto, .@"extern" => {
2633 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
2634 try wip_nav.refType(.fromInterned(parent_type));
2635 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2636 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2637 try uleb128(diw, decl.src_column + 1);
2638 try diw.writeByte(accessibility);
2639 try wip_nav.strp(nav.name.toSlice(ip));
2740 try wip_nav.declCommon(if (loaded_struct.field_types.len == 0) .{
2741 .decl = .decl_namespace_struct,
2742 .generic_decl = .generic_decl_struct,
2743 .instance = .instance_namespace_struct,
2744 } else .{
2745 .decl = .decl_struct,
2746 .generic_decl = .generic_decl_struct,
2747 .instance = .instance_struct,
2748 }, &nav, inst_info.file, &decl);
26402749 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
26412750 try uleb128(diw, nav_val.toType().abiSize(zcu));
26422751 try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);
......@@ -2688,13 +2797,11 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
26882797 }
26892798 },
26902799 .@"packed" => {
2691 try wip_nav.abbrevCode(.decl_packed_struct);
2692 try wip_nav.refType(.fromInterned(parent_type));
2693 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2694 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2695 try uleb128(diw, decl.src_column + 1);
2696 try diw.writeByte(accessibility);
2697 try wip_nav.strp(nav.name.toSlice(ip));
2800 try wip_nav.declCommon(.{
2801 .decl = .decl_packed_struct,
2802 .generic_decl = .generic_decl_struct,
2803 .instance = .instance_packed_struct,
2804 }, &nav, inst_info.file, &decl);
26982805 try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
26992806 var field_bit_offset: u16 = 0;
27002807 for (0..loaded_struct.field_types.len) |field_index| {
......@@ -2712,10 +2819,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
27122819 },
27132820 .enum_type => tag: {
27142821 const loaded_enum = ip.loadEnumType(nav_val.toIntern());
2715 if (loaded_enum.zir_index == .none) break :tag .decl_alias;
2716
2717 const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?;
2718 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
2822 const type_zir_index = loaded_enum.zir_index.unwrap() orelse break :tag .decl_alias;
2823 if (type_zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
27192824
27202825 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
27212826 if (type_gop.found_existing) {
......@@ -2730,13 +2835,15 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
27302835 }
27312836 wip_nav.entry = nav_gop.value_ptr.*;
27322837 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2733 try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
2734 try wip_nav.refType(.fromInterned(parent_type));
2735 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2736 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2737 try uleb128(diw, decl.src_column + 1);
2738 try diw.writeByte(accessibility);
2739 try wip_nav.strp(nav.name.toSlice(ip));
2838 try wip_nav.declCommon(if (loaded_enum.names.len > 0) .{
2839 .decl = .decl_enum,
2840 .generic_decl = .generic_decl_enum,
2841 .instance = .instance_enum,
2842 } else .{
2843 .decl = .decl_empty_enum,
2844 .generic_decl = .generic_decl_enum,
2845 .instance = .instance_empty_enum,
2846 }, &nav, inst_info.file, &decl);
27402847 try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
27412848 for (0..loaded_enum.names.len) |field_index| {
27422849 try wip_nav.enumConstValue(loaded_enum, .{
......@@ -2751,9 +2858,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
27512858 },
27522859 .union_type => tag: {
27532860 const loaded_union = ip.loadUnionType(nav_val.toIntern());
2754
2755 const type_inst_info = loaded_union.zir_index.resolveFull(ip).?;
2756 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
2861 if (loaded_union.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
27572862
27582863 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
27592864 if (type_gop.found_existing) {
......@@ -2768,13 +2873,11 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
27682873 }
27692874 wip_nav.entry = nav_gop.value_ptr.*;
27702875 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2771 try wip_nav.abbrevCode(.decl_union);
2772 try wip_nav.refType(.fromInterned(parent_type));
2773 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2774 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2775 try uleb128(diw, decl.src_column + 1);
2776 try diw.writeByte(accessibility);
2777 try wip_nav.strp(nav.name.toSlice(ip));
2876 try wip_nav.declCommon(.{
2877 .decl = .decl_union,
2878 .generic_decl = .generic_decl_union,
2879 .instance = .instance_union,
2880 }, &nav, inst_info.file, &decl);
27782881 const union_layout = Type.getUnionLayout(loaded_union, zcu);
27792882 try uleb128(diw, union_layout.abi_size);
27802883 try uleb128(diw, union_layout.abi_align.toByteUnits().?);
......@@ -2825,9 +2928,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
28252928 },
28262929 .opaque_type => tag: {
28272930 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
2828
2829 const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?;
2830 if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
2931 if (loaded_opaque.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
28312932
28322933 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
28332934 if (type_gop.found_existing) {
......@@ -2842,19 +2943,16 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
28422943 }
28432944 wip_nav.entry = nav_gop.value_ptr.*;
28442945 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2845 try wip_nav.abbrevCode(.decl_namespace_struct);
2846 try wip_nav.refType(.fromInterned(parent_type));
2847 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2848 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2849 try uleb128(diw, decl.src_column + 1);
2850 try diw.writeByte(accessibility);
2851 try wip_nav.strp(nav.name.toSlice(ip));
2852 try diw.writeByte(@intFromBool(false));
2946 try wip_nav.declCommon(.{
2947 .decl = .decl_namespace_struct,
2948 .generic_decl = .generic_decl_struct,
2949 .instance = .instance_namespace_struct,
2950 }, &nav, inst_info.file, &decl);
2951 try diw.writeByte(@intFromBool(true));
28532952 break :tag .done;
28542953 },
28552954 .undef,
28562955 .simple_value,
2857 .@"extern",
28582956 .int,
28592957 .err,
28602958 .error_union,
......@@ -2869,42 +2967,31 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
28692967 .un,
28702968 => .decl_const,
28712969 .variable => .decl_var,
2970 .@"extern" => unreachable,
28722971 .func => |func| tag: {
2873 if (nav_gop.found_existing) {
2874 const unit_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit);
2875 const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*);
2876 if (entry_ptr.len >= AbbrevCode.decl_bytes) {
2877 var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined;
2878 if (try dwarf.getFile().?.preadAll(
2879 &abbrev_code_buf,
2880 dwarf.debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
2881 ) != abbrev_code_buf.len) return error.InputOutput;
2882 var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
2883 const abbrev_code: AbbrevCode = @enumFromInt(
2884 std.leb.readUleb128(@typeInfo(AbbrevCode).@"enum".tag_type, abbrev_code_fbs.reader()) catch unreachable,
2885 );
2886 switch (abbrev_code) {
2887 else => unreachable,
2888 .decl_func, .decl_empty_func => return,
2889 .decl_func_generic, .decl_empty_func_generic => {},
2890 }
2891 }
2892 entry_ptr.clear();
2972 if (nav_gop.found_existing) switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, nav_gop.value_ptr.*)) {
2973 .null => {},
2974 else => unreachable,
2975 .decl_func, .decl_empty_func, .instance_func, .instance_empty_func => return,
2976 .decl_func_generic,
2977 .decl_empty_func_generic,
2978 .instance_func_generic,
2979 .instance_empty_func_generic,
2980 => dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear(),
28932981 } else nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
28942982 wip_nav.entry = nav_gop.value_ptr.*;
28952983
28962984 const func_type = ip.indexToKey(func.ty).func_type;
28972985 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2898 try wip_nav.abbrevCode(if (func_type.param_types.len > 0 or func_type.is_var_args)
2899 .decl_func_generic
2900 else
2901 .decl_empty_func_generic);
2902 try wip_nav.refType(.fromInterned(parent_type));
2903 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2904 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2905 try uleb128(diw, decl.src_column + 1);
2906 try diw.writeByte(accessibility);
2907 try wip_nav.strp(nav.name.toSlice(ip));
2986 try wip_nav.declCommon(if (func_type.param_types.len > 0 or func_type.is_var_args) .{
2987 .decl = .decl_func_generic,
2988 .generic_decl = .generic_decl_func,
2989 .instance = .instance_func_generic,
2990 } else .{
2991 .decl = .decl_empty_func_generic,
2992 .generic_decl = .generic_decl_func,
2993 .instance = .instance_empty_func_generic,
2994 }, &nav, inst_info.file, &decl);
29082995 try wip_nav.refType(.fromInterned(func_type.return_type));
29092996 if (func_type.param_types.len > 0 or func_type.is_var_args) {
29102997 for (0..func_type.param_types.len) |param_index| {
......@@ -2929,57 +3016,55 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
29293016 switch (tag) {
29303017 .done => {},
29313018 .decl_alias => {
2932 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2933 try wip_nav.abbrevCode(.decl_alias);
2934 try wip_nav.refType(.fromInterned(parent_type));
2935 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2936 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2937 try uleb128(diw, decl.src_column + 1);
2938 try diw.writeByte(accessibility);
2939 try wip_nav.strp(nav.name.toSlice(ip));
3019 try wip_nav.declCommon(.{
3020 .decl = .decl_alias,
3021 .generic_decl = .generic_decl_alias,
3022 .instance = .instance_alias,
3023 }, &nav, inst_info.file, &decl);
29403024 try wip_nav.refType(nav_val.toType());
29413025 },
29423026 .decl_var => {
29433027 const diw = wip_nav.debug_info.writer(dwarf.gpa);
2944 try wip_nav.abbrevCode(.decl_var);
2945 try wip_nav.refType(.fromInterned(parent_type));
2946 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2947 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2948 try uleb128(diw, decl.src_column + 1);
2949 try diw.writeByte(accessibility);
2950 try wip_nav.strp(nav.name.toSlice(ip));
3028 try wip_nav.declCommon(.{
3029 .decl = .decl_var,
3030 .generic_decl = .generic_decl_var,
3031 .instance = .instance_var,
3032 }, &nav, inst_info.file, &decl);
29513033 try wip_nav.strp(nav.fqn.toSlice(ip));
29523034 const nav_ty = nav_val.typeOf(zcu);
29533035 try wip_nav.refType(nav_ty);
29543036 try wip_nav.blockValue(nav_src_loc, nav_val);
29553037 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
29563038 nav_ty.abiAlignment(zcu).toByteUnits().?);
2957 try diw.writeByte(@intFromBool(false));
3039 try diw.writeByte(@intFromBool(decl.linkage != .normal));
29583040 },
29593041 .decl_const => {
29603042 const diw = wip_nav.debug_info.writer(dwarf.gpa);
29613043 const nav_ty = nav_val.typeOf(zcu);
29623044 const has_runtime_bits = nav_ty.hasRuntimeBits(zcu);
29633045 const has_comptime_state = nav_ty.comptimeOnly(zcu) and try nav_ty.onePossibleValue(pt) == null;
2964 try wip_nav.abbrevCode(if (has_runtime_bits and has_comptime_state)
2965 .decl_const_runtime_bits_comptime_state
2966 else if (has_comptime_state)
2967 .decl_const_comptime_state
2968 else if (has_runtime_bits)
2969 .decl_const_runtime_bits
2970 else
2971 .decl_const);
2972 try wip_nav.refType(.fromInterned(parent_type));
2973 assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
2974 try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
2975 try uleb128(diw, decl.src_column + 1);
2976 try diw.writeByte(accessibility);
2977 try wip_nav.strp(nav.name.toSlice(ip));
3046 try wip_nav.declCommon(if (has_runtime_bits and has_comptime_state) .{
3047 .decl = .decl_const_runtime_bits_comptime_state,
3048 .generic_decl = .generic_decl_const,
3049 .instance = .instance_const_runtime_bits_comptime_state,
3050 } else if (has_comptime_state) .{
3051 .decl = .decl_const_comptime_state,
3052 .generic_decl = .generic_decl_const,
3053 .instance = .instance_const_comptime_state,
3054 } else if (has_runtime_bits) .{
3055 .decl = .decl_const_runtime_bits,
3056 .generic_decl = .generic_decl_const,
3057 .instance = .instance_const_runtime_bits,
3058 } else .{
3059 .decl = .decl_const,
3060 .generic_decl = .generic_decl_const,
3061 .instance = .instance_const,
3062 }, &nav, inst_info.file, &decl);
29783063 try wip_nav.strp(nav.fqn.toSlice(ip));
29793064 const nav_ty_reloc_index = try wip_nav.refForward();
29803065 try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
29813066 nav_ty.abiAlignment(zcu).toByteUnits().?);
2982 try diw.writeByte(@intFromBool(false));
3067 try diw.writeByte(@intFromBool(decl.linkage != .normal));
29833068 if (has_runtime_bits) try wip_nav.blockValue(nav_src_loc, nav_val);
29843069 if (has_comptime_state) try wip_nav.refValue(nav_val);
29853070 wip_nav.finishForward(nav_ty_reloc_index);
......@@ -3017,15 +3102,15 @@ fn updateLazyType(
30173102 .func_high_pc = undefined,
30183103 .blocks = undefined,
30193104 .cfi = undefined,
3020 .debug_frame = .{},
3021 .debug_info = .{},
3022 .debug_line = .{},
3023 .debug_loclists = .{},
3105 .debug_frame = .empty,
3106 .debug_info = .empty,
3107 .debug_line = .empty,
3108 .debug_loclists = .empty,
30243109 .pending_lazy = pending_lazy.*,
30253110 };
30263111 defer {
30273112 pending_lazy.* = wip_nav.pending_lazy;
3028 wip_nav.pending_lazy = .{};
3113 wip_nav.pending_lazy = .empty;
30293114 wip_nav.deinit();
30303115 }
30313116 const diw = wip_nav.debug_info.writer(dwarf.gpa);
......@@ -3076,7 +3161,7 @@ fn updateLazyType(
30763161 }
30773162 },
30783163 .Slice => {
3079 try wip_nav.abbrevCode(.struct_type);
3164 try wip_nav.abbrevCode(.generated_struct_type);
30803165 try wip_nav.strp(name);
30813166 try uleb128(diw, ty.abiSize(zcu));
30823167 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
......@@ -3115,7 +3200,7 @@ fn updateLazyType(
31153200 },
31163201 .opt_type => |opt_child_type_index| {
31173202 const opt_child_type: Type = .fromInterned(opt_child_type_index);
3118 try wip_nav.abbrevCode(.union_type);
3203 try wip_nav.abbrevCode(.generated_union_type);
31193204 try wip_nav.strp(name);
31203205 try uleb128(diw, ty.abiSize(zcu));
31213206 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
......@@ -3199,7 +3284,7 @@ fn updateLazyType(
31993284 },
32003285 };
32013286
3202 try wip_nav.abbrevCode(.union_type);
3287 try wip_nav.abbrevCode(.generated_union_type);
32033288 try wip_nav.strp(name);
32043289 if (error_union_type.error_set_type != .generic_poison_type and
32053290 error_union_type.payload_type != .generic_poison_type)
......@@ -3308,11 +3393,11 @@ fn updateLazyType(
33083393 .opaque_type,
33093394 => unreachable,
33103395 .tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
3311 try wip_nav.abbrevCode(.namespace_struct_type);
3396 try wip_nav.abbrevCode(.generated_empty_struct_type);
33123397 try wip_nav.strp(name);
33133398 try diw.writeByte(@intFromBool(false));
33143399 } else {
3315 try wip_nav.abbrevCode(.struct_type);
3400 try wip_nav.abbrevCode(.generated_struct_type);
33163401 try wip_nav.strp(name);
33173402 try uleb128(diw, ty.abiSize(zcu));
33183403 try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
......@@ -3357,7 +3442,7 @@ fn updateLazyType(
33573442 },
33583443 .enum_type => {
33593444 const loaded_enum = ip.loadEnumType(type_index);
3360 try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .enum_type else .empty_enum_type);
3445 try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .generated_enum_type else .generated_empty_enum_type);
33613446 try wip_nav.strp(name);
33623447 try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
33633448 for (0..loaded_enum.names.len) |field_index| {
......@@ -3449,7 +3534,7 @@ fn updateLazyType(
34493534 if (!is_nullary) try uleb128(diw, @intFromEnum(AbbrevCode.null));
34503535 },
34513536 .error_set_type => |error_set_type| {
3452 try wip_nav.abbrevCode(if (error_set_type.names.len > 0) .enum_type else .empty_enum_type);
3537 try wip_nav.abbrevCode(if (error_set_type.names.len > 0) .generated_enum_type else .generated_empty_enum_type);
34533538 try wip_nav.strp(name);
34543539 try wip_nav.refType(.fromInterned(try pt.intern(.{ .int_type = .{
34553540 .signedness = .unsigned,
......@@ -3518,15 +3603,15 @@ fn updateLazyValue(
35183603 .func_high_pc = undefined,
35193604 .blocks = undefined,
35203605 .cfi = undefined,
3521 .debug_frame = .{},
3522 .debug_info = .{},
3523 .debug_line = .{},
3524 .debug_loclists = .{},
3606 .debug_frame = .empty,
3607 .debug_info = .empty,
3608 .debug_line = .empty,
3609 .debug_loclists = .empty,
35253610 .pending_lazy = pending_lazy.*,
35263611 };
35273612 defer {
35283613 pending_lazy.* = wip_nav.pending_lazy;
3529 wip_nav.pending_lazy = .{};
3614 wip_nav.pending_lazy = .empty;
35303615 wip_nav.deinit();
35313616 }
35323617 const diw = wip_nav.debug_info.writer(dwarf.gpa);
......@@ -3870,12 +3955,13 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
38703955 const ip = &zcu.intern_pool;
38713956 const ty: Type = .fromInterned(type_index);
38723957 const ty_src_loc = ty.srcLoc(zcu);
3873 log.debug("updateContainerType({}({d}))", .{ ty.fmt(pt), @intFromEnum(type_index) });
3958 log.debug("updateContainerType({})", .{ty.fmt(pt)});
38743959
38753960 const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?;
38763961 const file = zcu.fileByIndex(inst_info.file);
3962 const unit = try dwarf.getUnit(file.mod);
3963 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
38773964 if (inst_info.inst == .main_struct_inst) {
3878 const unit = try dwarf.getUnit(file.mod);
38793965 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
38803966 if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
38813967 var wip_nav: WipNav = .{
......@@ -3889,19 +3975,18 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
38893975 .func_high_pc = undefined,
38903976 .blocks = undefined,
38913977 .cfi = undefined,
3892 .debug_frame = .{},
3893 .debug_info = .{},
3894 .debug_line = .{},
3895 .debug_loclists = .{},
3896 .pending_lazy = .{},
3978 .debug_frame = .empty,
3979 .debug_info = .empty,
3980 .debug_line = .empty,
3981 .debug_loclists = .empty,
3982 .pending_lazy = .empty,
38973983 };
38983984 defer wip_nav.deinit();
38993985
39003986 const loaded_struct = ip.loadStructType(type_index);
39013987
39023988 const diw = wip_nav.debug_info.writer(dwarf.gpa);
3903 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_file else .file);
3904 const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
3989 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .empty_file else .file);
39053990 try uleb128(diw, file_gop.index);
39063991 try wip_nav.strp(loaded_struct.name.toSlice(ip));
39073992 if (loaded_struct.field_types.len > 0) {
......@@ -3978,7 +4063,6 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
39784063 if (name_strat == .parent) return;
39794064 }
39804065
3981 const unit = try dwarf.getUnit(file.mod);
39824066 const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
39834067 if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
39844068 var wip_nav: WipNav = .{
......@@ -3992,11 +4076,11 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
39924076 .func_high_pc = undefined,
39934077 .blocks = undefined,
39944078 .cfi = undefined,
3995 .debug_frame = .{},
3996 .debug_info = .{},
3997 .debug_line = .{},
3998 .debug_loclists = .{},
3999 .pending_lazy = .{},
4079 .debug_frame = .empty,
4080 .debug_info = .empty,
4081 .debug_line = .empty,
4082 .debug_loclists = .empty,
4083 .pending_lazy = .empty,
40004084 };
40014085 defer wip_nav.deinit();
40024086 const diw = wip_nav.debug_info.writer(dwarf.gpa);
......@@ -4008,7 +4092,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
40084092 const loaded_struct = ip.loadStructType(type_index);
40094093 switch (loaded_struct.layout) {
40104094 .auto, .@"extern" => {
4011 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_struct_type else .struct_type);
4095 try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .empty_struct_type else .struct_type);
4096 try uleb128(diw, file_gop.index);
40124097 try wip_nav.strp(name);
40134098 if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
40144099 try uleb128(diw, ty.abiSize(zcu));
......@@ -4062,6 +4147,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
40624147 },
40634148 .@"packed" => {
40644149 try wip_nav.abbrevCode(if (loaded_struct.field_types.len > 0) .packed_struct_type else .empty_packed_struct_type);
4150 try uleb128(diw, file_gop.index);
40654151 try wip_nav.strp(name);
40664152 try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
40674153 var field_bit_offset: u16 = 0;
......@@ -4080,6 +4166,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
40804166 .enum_type => {
40814167 const loaded_enum = ip.loadEnumType(type_index);
40824168 try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .enum_type else .empty_enum_type);
4169 try uleb128(diw, file_gop.index);
40834170 try wip_nav.strp(name);
40844171 try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
40854172 for (0..loaded_enum.names.len) |field_index| {
......@@ -4095,6 +4182,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
40954182 .union_type => {
40964183 const loaded_union = ip.loadUnionType(type_index);
40974184 try wip_nav.abbrevCode(if (loaded_union.field_types.len > 0) .union_type else .empty_union_type);
4185 try uleb128(diw, file_gop.index);
40984186 try wip_nav.strp(name);
40994187 const union_layout = Type.getUnionLayout(loaded_union, zcu);
41004188 try uleb128(diw, union_layout.abi_size);
......@@ -4144,7 +4232,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
41444232 if (loaded_union.field_types.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
41454233 },
41464234 .opaque_type => {
4147 try wip_nav.abbrevCode(.namespace_struct_type);
4235 try wip_nav.abbrevCode(.empty_struct_type);
4236 try uleb128(diw, file_gop.index);
41484237 try wip_nav.strp(name);
41494238 try diw.writeByte(@intFromBool(true));
41504239 },
......@@ -4156,11 +4245,28 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
41564245 }
41574246}
41584247
4159pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, ti_id: InternPool.TrackedInst.Index) UpdateError!void {
4160 _ = dwarf;
4161 _ = zcu;
4162 _ = ti_id;
4163 @panic("TODO: Dwarf.updateLineNumber");
4248pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedInst.Index) UpdateError!void {
4249 const ip = &zcu.intern_pool;
4250
4251 const inst_info = zir_index.resolveFull(ip).?;
4252 assert(inst_info.inst != .main_struct_inst);
4253 const file = zcu.fileByIndex(inst_info.file);
4254 assert(file.zir_loaded);
4255 const decl = file.zir.getDeclaration(inst_info.inst);
4256 log.debug("updateLineNumber({s}:{d}:{d} %{d} = {s})", .{
4257 file.sub_file_path,
4258 decl.src_line + 1,
4259 decl.src_column + 1,
4260 @intFromEnum(inst_info.inst),
4261 file.zir.nullTerminatedString(decl.name),
4262 });
4263
4264 var line_buf: [4]u8 = undefined;
4265 std.mem.writeInt(u32, &line_buf, decl.src_line + 1, dwarf.endian);
4266
4267 const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod) orelse return);
4268 const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return);
4269 try dwarf.getFile().?.pwriteAll(&line_buf, dwarf.debug_info.section.off(dwarf) + unit.off + unit.header_len + entry.off + DebugInfo.declEntryLineOff(dwarf));
41644270}
41654271
41664272pub fn freeNav(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) void {
......@@ -4203,16 +4309,16 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
42034309 .func_high_pc = undefined,
42044310 .blocks = undefined,
42054311 .cfi = undefined,
4206 .debug_frame = .{},
4207 .debug_info = .{},
4208 .debug_line = .{},
4209 .debug_loclists = .{},
4210 .pending_lazy = .{},
4312 .debug_frame = .empty,
4313 .debug_info = .empty,
4314 .debug_line = .empty,
4315 .debug_loclists = .empty,
4316 .pending_lazy = .empty,
42114317 };
42124318 defer wip_nav.deinit();
42134319 const diw = wip_nav.debug_info.writer(dwarf.gpa);
42144320 const global_error_set_names = ip.global_error_set.getNamesFromMainThread();
4215 try wip_nav.abbrevCode(if (global_error_set_names.len > 0) .enum_type else .empty_enum_type);
4321 try wip_nav.abbrevCode(if (global_error_set_names.len > 0) .generated_enum_type else .generated_empty_enum_type);
42164322 try wip_nav.strp("anyerror");
42174323 try wip_nav.refType(.fromInterned(try pt.intern(.{ .int_type = .{
42184324 .signedness = .unsigned,
......@@ -4601,7 +4707,7 @@ const AbbrevCode = enum {
46014707 // padding codes must be one byte uleb128 values to function
46024708 pad_1,
46034709 pad_n,
4604 // decl codes are assumed to all have the same uleb128 length
4710 // (generic) decl codes are assumed to all have the same uleb128 length
46054711 decl_alias,
46064712 decl_enum,
46074713 decl_empty_enum,
......@@ -4618,11 +4724,34 @@ const AbbrevCode = enum {
46184724 decl_empty_func,
46194725 decl_func_generic,
46204726 decl_empty_func_generic,
4727 generic_decl_alias,
4728 generic_decl_enum,
4729 generic_decl_struct,
4730 generic_decl_union,
4731 generic_decl_var,
4732 generic_decl_const,
4733 generic_decl_func,
46214734 // the rest are unrestricted
4735 instance_alias,
4736 instance_enum,
4737 instance_empty_enum,
4738 instance_namespace_struct,
4739 instance_struct,
4740 instance_packed_struct,
4741 instance_union,
4742 instance_var,
4743 instance_const,
4744 instance_const_runtime_bits,
4745 instance_const_comptime_state,
4746 instance_const_runtime_bits_comptime_state,
4747 instance_func,
4748 instance_empty_func,
4749 instance_func_generic,
4750 instance_empty_func_generic,
46224751 compile_unit,
46234752 module,
4624 namespace_file,
46254753 file,
4754 empty_file,
46264755 signed_enum_field,
46274756 unsigned_enum_field,
46284757 big_enum_field,
......@@ -4655,10 +4784,15 @@ const AbbrevCode = enum {
46554784 func_type,
46564785 func_type_param,
46574786 is_var_args,
4787 generated_enum_type,
4788 generated_empty_enum_type,
4789 generated_struct_type,
4790 generated_empty_struct_type,
4791 generated_union_type,
46584792 enum_type,
46594793 empty_enum_type,
4660 namespace_struct_type,
46614794 struct_type,
4795 empty_struct_type,
46624796 packed_struct_type,
46634797 empty_packed_struct_type,
46644798 union_type,
......@@ -4684,7 +4818,7 @@ const AbbrevCode = enum {
46844818 comptime_value_elem_runtime_bits,
46854819 comptime_value_elem_comptime_state,
46864820
4687 const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_empty_func_generic));
4821 const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.generic_decl_func));
46884822
46894823 const Attr = struct {
46904824 DeclValEnum(DW.AT),
......@@ -4697,6 +4831,10 @@ const AbbrevCode = enum {
46974831 .{ .accessibility, .data1 },
46984832 .{ .name, .strp },
46994833 };
4834 const instance_abbrev_common_attrs = &[_]Attr{
4835 .{ .ZIG_parent, .ref_addr },
4836 .{ .abstract_origin, .ref_addr },
4837 };
47004838 const abbrevs = std.EnumArray(AbbrevCode, struct {
47014839 tag: DeclValEnum(DW.TAG),
47024840 children: bool = false,
......@@ -4847,6 +4985,184 @@ const AbbrevCode = enum {
48474985 .{ .type, .ref_addr },
48484986 },
48494987 },
4988 .generic_decl_alias = .{
4989 .tag = .imported_declaration,
4990 .attrs = decl_abbrev_common_attrs ++ .{
4991 .{ .declaration, .flag_present },
4992 },
4993 },
4994 .generic_decl_enum = .{
4995 .tag = .enumeration_type,
4996 .attrs = decl_abbrev_common_attrs ++ .{
4997 .{ .declaration, .flag_present },
4998 },
4999 },
5000 .generic_decl_struct = .{
5001 .tag = .structure_type,
5002 .attrs = decl_abbrev_common_attrs ++ .{
5003 .{ .declaration, .flag_present },
5004 },
5005 },
5006 .generic_decl_union = .{
5007 .tag = .union_type,
5008 .attrs = decl_abbrev_common_attrs ++ .{
5009 .{ .declaration, .flag_present },
5010 },
5011 },
5012 .generic_decl_var = .{
5013 .tag = .variable,
5014 .attrs = decl_abbrev_common_attrs ++ .{
5015 .{ .declaration, .flag_present },
5016 },
5017 },
5018 .generic_decl_const = .{
5019 .tag = .constant,
5020 .attrs = decl_abbrev_common_attrs ++ .{
5021 .{ .declaration, .flag_present },
5022 },
5023 },
5024 .generic_decl_func = .{
5025 .tag = .subprogram,
5026 .attrs = decl_abbrev_common_attrs ++ .{
5027 .{ .declaration, .flag_present },
5028 },
5029 },
5030 .instance_alias = .{
5031 .tag = .imported_declaration,
5032 .attrs = instance_abbrev_common_attrs ++ .{
5033 .{ .import, .ref_addr },
5034 },
5035 },
5036 .instance_enum = .{
5037 .tag = .enumeration_type,
5038 .children = true,
5039 .attrs = instance_abbrev_common_attrs ++ .{
5040 .{ .type, .ref_addr },
5041 },
5042 },
5043 .instance_empty_enum = .{
5044 .tag = .enumeration_type,
5045 .attrs = instance_abbrev_common_attrs ++ .{
5046 .{ .type, .ref_addr },
5047 },
5048 },
5049 .instance_namespace_struct = .{
5050 .tag = .structure_type,
5051 .attrs = instance_abbrev_common_attrs ++ .{
5052 .{ .declaration, .flag },
5053 },
5054 },
5055 .instance_struct = .{
5056 .tag = .structure_type,
5057 .children = true,
5058 .attrs = instance_abbrev_common_attrs ++ .{
5059 .{ .byte_size, .udata },
5060 .{ .alignment, .udata },
5061 },
5062 },
5063 .instance_packed_struct = .{
5064 .tag = .structure_type,
5065 .children = true,
5066 .attrs = instance_abbrev_common_attrs ++ .{
5067 .{ .type, .ref_addr },
5068 },
5069 },
5070 .instance_union = .{
5071 .tag = .union_type,
5072 .children = true,
5073 .attrs = instance_abbrev_common_attrs ++ .{
5074 .{ .byte_size, .udata },
5075 .{ .alignment, .udata },
5076 },
5077 },
5078 .instance_var = .{
5079 .tag = .variable,
5080 .attrs = instance_abbrev_common_attrs ++ .{
5081 .{ .linkage_name, .strp },
5082 .{ .type, .ref_addr },
5083 .{ .location, .exprloc },
5084 .{ .alignment, .udata },
5085 .{ .external, .flag },
5086 },
5087 },
5088 .instance_const = .{
5089 .tag = .constant,
5090 .attrs = instance_abbrev_common_attrs ++ .{
5091 .{ .linkage_name, .strp },
5092 .{ .type, .ref_addr },
5093 .{ .alignment, .udata },
5094 .{ .external, .flag },
5095 },
5096 },
5097 .instance_const_runtime_bits = .{
5098 .tag = .constant,
5099 .attrs = instance_abbrev_common_attrs ++ .{
5100 .{ .linkage_name, .strp },
5101 .{ .type, .ref_addr },
5102 .{ .alignment, .udata },
5103 .{ .external, .flag },
5104 .{ .const_value, .block },
5105 },
5106 },
5107 .instance_const_comptime_state = .{
5108 .tag = .constant,
5109 .attrs = instance_abbrev_common_attrs ++ .{
5110 .{ .linkage_name, .strp },
5111 .{ .type, .ref_addr },
5112 .{ .alignment, .udata },
5113 .{ .external, .flag },
5114 .{ .ZIG_comptime_value, .ref_addr },
5115 },
5116 },
5117 .instance_const_runtime_bits_comptime_state = .{
5118 .tag = .constant,
5119 .attrs = instance_abbrev_common_attrs ++ .{
5120 .{ .linkage_name, .strp },
5121 .{ .type, .ref_addr },
5122 .{ .alignment, .udata },
5123 .{ .external, .flag },
5124 .{ .const_value, .block },
5125 .{ .ZIG_comptime_value, .ref_addr },
5126 },
5127 },
5128 .instance_func = .{
5129 .tag = .subprogram,
5130 .children = true,
5131 .attrs = instance_abbrev_common_attrs ++ .{
5132 .{ .linkage_name, .strp },
5133 .{ .type, .ref_addr },
5134 .{ .low_pc, .addr },
5135 .{ .high_pc, .data4 },
5136 .{ .alignment, .udata },
5137 .{ .external, .flag },
5138 .{ .noreturn, .flag },
5139 },
5140 },
5141 .instance_empty_func = .{
5142 .tag = .subprogram,
5143 .attrs = instance_abbrev_common_attrs ++ .{
5144 .{ .linkage_name, .strp },
5145 .{ .type, .ref_addr },
5146 .{ .low_pc, .addr },
5147 .{ .high_pc, .data4 },
5148 .{ .alignment, .udata },
5149 .{ .external, .flag },
5150 .{ .noreturn, .flag },
5151 },
5152 },
5153 .instance_func_generic = .{
5154 .tag = .subprogram,
5155 .children = true,
5156 .attrs = instance_abbrev_common_attrs ++ .{
5157 .{ .type, .ref_addr },
5158 },
5159 },
5160 .instance_empty_func_generic = .{
5161 .tag = .subprogram,
5162 .attrs = instance_abbrev_common_attrs ++ .{
5163 .{ .type, .ref_addr },
5164 },
5165 },
48505166 .compile_unit = .{
48515167 .tag = .compile_unit,
48525168 .children = true,
......@@ -4869,21 +5185,21 @@ const AbbrevCode = enum {
48695185 .{ .ranges, .rnglistx },
48705186 },
48715187 },
4872 .namespace_file = .{
5188 .file = .{
48735189 .tag = .structure_type,
5190 .children = true,
48745191 .attrs = &.{
48755192 .{ .decl_file, .udata },
48765193 .{ .name, .strp },
5194 .{ .byte_size, .udata },
5195 .{ .alignment, .udata },
48775196 },
48785197 },
4879 .file = .{
5198 .empty_file = .{
48805199 .tag = .structure_type,
4881 .children = true,
48825200 .attrs = &.{
48835201 .{ .decl_file, .udata },
48845202 .{ .name, .strp },
4885 .{ .byte_size, .udata },
4886 .{ .alignment, .udata },
48875203 },
48885204 },
48895205 .signed_enum_field = .{
......@@ -5133,7 +5449,7 @@ const AbbrevCode = enum {
51335449 .is_var_args = .{
51345450 .tag = .unspecified_parameters,
51355451 },
5136 .enum_type = .{
5452 .generated_enum_type = .{
51375453 .tag = .enumeration_type,
51385454 .children = true,
51395455 .attrs = &.{
......@@ -5141,33 +5457,78 @@ const AbbrevCode = enum {
51415457 .{ .type, .ref_addr },
51425458 },
51435459 },
5144 .empty_enum_type = .{
5460 .generated_empty_enum_type = .{
51455461 .tag = .enumeration_type,
51465462 .attrs = &.{
51475463 .{ .name, .strp },
51485464 .{ .type, .ref_addr },
51495465 },
51505466 },
5151 .namespace_struct_type = .{
5467 .generated_struct_type = .{
5468 .tag = .structure_type,
5469 .children = true,
5470 .attrs = &.{
5471 .{ .name, .strp },
5472 .{ .byte_size, .udata },
5473 .{ .alignment, .udata },
5474 },
5475 },
5476 .generated_empty_struct_type = .{
51525477 .tag = .structure_type,
51535478 .attrs = &.{
51545479 .{ .name, .strp },
51555480 .{ .declaration, .flag },
51565481 },
51575482 },
5483 .generated_union_type = .{
5484 .tag = .union_type,
5485 .children = true,
5486 .attrs = &.{
5487 .{ .name, .strp },
5488 .{ .byte_size, .udata },
5489 .{ .alignment, .udata },
5490 },
5491 },
5492 .enum_type = .{
5493 .tag = .enumeration_type,
5494 .children = true,
5495 .attrs = &.{
5496 .{ .decl_file, .udata },
5497 .{ .name, .strp },
5498 .{ .type, .ref_addr },
5499 },
5500 },
5501 .empty_enum_type = .{
5502 .tag = .enumeration_type,
5503 .attrs = &.{
5504 .{ .decl_file, .udata },
5505 .{ .name, .strp },
5506 .{ .type, .ref_addr },
5507 },
5508 },
51585509 .struct_type = .{
51595510 .tag = .structure_type,
51605511 .children = true,
51615512 .attrs = &.{
5513 .{ .decl_file, .udata },
51625514 .{ .name, .strp },
51635515 .{ .byte_size, .udata },
51645516 .{ .alignment, .udata },
51655517 },
51665518 },
5519 .empty_struct_type = .{
5520 .tag = .structure_type,
5521 .attrs = &.{
5522 .{ .decl_file, .udata },
5523 .{ .name, .strp },
5524 .{ .declaration, .flag },
5525 },
5526 },
51675527 .packed_struct_type = .{
51685528 .tag = .structure_type,
51695529 .children = true,
51705530 .attrs = &.{
5531 .{ .decl_file, .udata },
51715532 .{ .name, .strp },
51725533 .{ .type, .ref_addr },
51735534 },
......@@ -5175,6 +5536,7 @@ const AbbrevCode = enum {
51755536 .empty_packed_struct_type = .{
51765537 .tag = .structure_type,
51775538 .attrs = &.{
5539 .{ .decl_file, .udata },
51785540 .{ .name, .strp },
51795541 .{ .type, .ref_addr },
51805542 },
......@@ -5183,6 +5545,7 @@ const AbbrevCode = enum {
51835545 .tag = .union_type,
51845546 .children = true,
51855547 .attrs = &.{
5548 .{ .decl_file, .udata },
51865549 .{ .name, .strp },
51875550 .{ .byte_size, .udata },
51885551 .{ .alignment, .udata },
......@@ -5191,6 +5554,7 @@ const AbbrevCode = enum {
51915554 .empty_union_type = .{
51925555 .tag = .union_type,
51935556 .attrs = &.{
5557 .{ .decl_file, .udata },
51945558 .{ .name, .strp },
51955559 .{ .byte_size, .udata },
51965560 .{ .alignment, .udata },
......@@ -5363,6 +5727,15 @@ fn addCommonEntry(dwarf: *Dwarf, unit: Unit.Index) UpdateError!Entry.Index {
53635727 return entry;
53645728}
53655729
5730fn freeCommonEntry(dwarf: *Dwarf, unit: Unit.Index, entry: Entry.Index) UpdateError!void {
5731 try dwarf.debug_aranges.section.freeEntry(unit, entry, dwarf);
5732 try dwarf.debug_frame.section.freeEntry(unit, entry, dwarf);
5733 try dwarf.debug_info.section.freeEntry(unit, entry, dwarf);
5734 try dwarf.debug_line.section.freeEntry(unit, entry, dwarf);
5735 try dwarf.debug_loclists.section.freeEntry(unit, entry, dwarf);
5736 try dwarf.debug_rnglists.section.freeEntry(unit, entry, dwarf);
5737}
5738
53665739fn writeInt(dwarf: *Dwarf, buf: []u8, int: u64) void {
53675740 switch (buf.len) {
53685741 inline 0...8 => |len| std.mem.writeInt(@Type(.{ .int = .{
src/link/Elf/ZigObject.zig+12-28
......@@ -1463,19 +1463,7 @@ pub fn updateFunc(
14631463 break :blk .{ atom_ptr.value, atom_ptr.alignment };
14641464 };
14651465
1466 if (debug_wip_nav) |*wip_nav| {
1467 const sym = self.symbol(sym_index);
1468 try self.dwarf.?.finishWipNav(
1469 pt,
1470 func.owner_nav,
1471 .{
1472 .index = sym_index,
1473 .addr = @intCast(sym.address(.{}, elf_file)),
1474 .size = self.atom(sym.ref.index).?.size,
1475 },
1476 wip_nav,
1477 );
1478 }
1466 if (debug_wip_nav) |*wip_nav| try self.dwarf.?.finishWipNavFunc(pt, func.owner_nav, code.len, wip_nav);
14791467
14801468 // Exports will be updated by `Zcu.processExports` after the update.
14811469
......@@ -1546,13 +1534,21 @@ pub fn updateNav(
15461534 .func => .none,
15471535 .variable => |variable| variable.init,
15481536 .@"extern" => |@"extern"| {
1549 if (ip.isFunctionType(@"extern".ty)) return;
15501537 const sym_index = try self.getGlobalSymbol(
15511538 elf_file,
15521539 nav.name.toSlice(ip),
15531540 @"extern".lib_name.toSlice(ip),
15541541 );
1555 self.symbol(sym_index).flags.is_extern_ptr = true;
1542 if (!ip.isFunctionType(@"extern".ty)) {
1543 const sym = self.symbol(sym_index);
1544 sym.flags.is_extern_ptr = true;
1545 if (@"extern".is_threadlocal) sym.flags.is_tls = true;
1546 }
1547 if (self.dwarf) |*dwarf| dwarf: {
1548 var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;
1549 defer debug_wip_nav.deinit();
1550 try dwarf.finishWipNav(pt, nav_index, &debug_wip_nav);
1551 }
15561552 return;
15571553 },
15581554 else => nav.status.fully_resolved.val,
......@@ -1596,19 +1592,7 @@ pub fn updateNav(
15961592 else
15971593 try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT);
15981594
1599 if (debug_wip_nav) |*wip_nav| {
1600 const sym = self.symbol(sym_index);
1601 try self.dwarf.?.finishWipNav(
1602 pt,
1603 nav_index,
1604 .{
1605 .index = sym_index,
1606 .addr = @intCast(sym.address(.{}, elf_file)),
1607 .size = sym.atom(elf_file).?.size,
1608 },
1609 wip_nav,
1610 );
1611 }
1595 if (debug_wip_nav) |*wip_nav| try self.dwarf.?.finishWipNav(pt, nav_index, wip_nav);
16121596 } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index);
16131597
16141598 // Exports will be updated by `Zcu.processExports` after the update.
src/link/MachO/ZigObject.zig+16-33
......@@ -780,8 +780,8 @@ pub fn updateFunc(
780780 var code_buffer = std.ArrayList(u8).init(gpa);
781781 defer code_buffer.deinit();
782782
783 var dwarf_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
784 defer if (dwarf_wip_nav) |*wip_nav| wip_nav.deinit();
783 var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
784 defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
785785
786786 const res = try codegen.generateFunction(
787787 &macho_file.base,
......@@ -791,7 +791,7 @@ pub fn updateFunc(
791791 air,
792792 liveness,
793793 &code_buffer,
794 if (dwarf_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
794 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
795795 );
796796
797797 const code = switch (res) {
......@@ -813,19 +813,7 @@ pub fn updateFunc(
813813 break :blk .{ atom.value, atom.alignment };
814814 };
815815
816 if (dwarf_wip_nav) |*wip_nav| {
817 const sym = self.symbols.items[sym_index];
818 try self.dwarf.?.finishWipNav(
819 pt,
820 func.owner_nav,
821 .{
822 .index = sym_index,
823 .addr = sym.getAddress(.{}, macho_file),
824 .size = sym.getAtom(macho_file).?.size,
825 },
826 wip_nav,
827 );
828 }
816 if (debug_wip_nav) |*wip_nav| try self.dwarf.?.finishWipNavFunc(pt, func.owner_nav, code.len, wip_nav);
829817
830818 // Exports will be updated by `Zcu.processExports` after the update.
831819 if (old_rva != new_rva and old_rva > 0) {
......@@ -883,13 +871,20 @@ pub fn updateNav(
883871 .func => .none,
884872 .variable => |variable| variable.init,
885873 .@"extern" => |@"extern"| {
886 if (ip.isFunctionType(@"extern".ty)) return;
887874 // Extern variable gets a __got entry only
888875 const name = @"extern".name.toSlice(ip);
889876 const lib_name = @"extern".lib_name.toSlice(ip);
890 const index = try self.getGlobalSymbol(macho_file, name, lib_name);
891 const sym = &self.symbols.items[index];
892 sym.flags.is_extern_ptr = true;
877 const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name);
878 if (!ip.isFunctionType(@"extern".ty)) {
879 const sym = &self.symbols.items[sym_index];
880 sym.flags.is_extern_ptr = true;
881 if (@"extern".is_threadlocal) sym.flags.tlv = true;
882 }
883 if (self.dwarf) |*dwarf| dwarf: {
884 var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;
885 defer debug_wip_nav.deinit();
886 try dwarf.finishWipNav(pt, nav_index, &debug_wip_nav);
887 }
893888 return;
894889 },
895890 else => nav.status.fully_resolved.val,
......@@ -927,19 +922,7 @@ pub fn updateNav(
927922 else
928923 try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code);
929924
930 if (debug_wip_nav) |*wip_nav| {
931 const sym = self.symbols.items[sym_index];
932 try self.dwarf.?.finishWipNav(
933 pt,
934 nav_index,
935 .{
936 .index = sym_index,
937 .addr = sym.getAddress(.{}, macho_file),
938 .size = sym.getAtom(macho_file).?.size,
939 },
940 wip_nav,
941 );
942 }
925 if (debug_wip_nav) |*wip_nav| try self.dwarf.?.finishWipNav(pt, nav_index, wip_nav);
943926 } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index);
944927
945928 // Exports will be updated by `Zcu.processExports` after the update.
test/incremental/change_generic_line_number created+32
......@@ -0,0 +1,32 @@
1#target=x86_64-linux-selfhosted
2#update=initial version
3#file=main.zig
4const std = @import("std");
5fn Printer(message: []const u8) type {
6 return struct {
7 fn print() !void {
8 try std.io.getStdOut().writeAll(message);
9 }
10 };
11}
12pub fn main() !void {
13 try Printer("foo\n").print();
14 try Printer("bar\n").print();
15}
16#expect_stdout="foo\nbar\n"
17#update=change line number
18#file=main.zig
19const std = @import("std");
20
21fn Printer(message: []const u8) type {
22 return struct {
23 fn print() !void {
24 try std.io.getStdOut().writeAll(message);
25 }
26 };
27}
28pub fn main() !void {
29 try Printer("foo\n").print();
30 try Printer("bar\n").print();
31}
32#expect_stdout="foo\nbar\n"
test/incremental/change_line_number created+16
......@@ -0,0 +1,16 @@
1#target=x86_64-linux-selfhosted
2#update=initial version
3#file=main.zig
4const std = @import("std");
5pub fn main() !void {
6 try std.io.getStdOut().writeAll("foo\n");
7}
8#expect_stdout="foo\n"
9#update=change line number
10#file=main.zig
11const std = @import("std");
12
13pub fn main() !void {
14 try std.io.getStdOut().writeAll("foo\n");
15}
16#expect_stdout="foo\n"
tools/incr-check.zig+8-2
......@@ -2,7 +2,7 @@ const std = @import("std");
22const Allocator = std.mem.Allocator;
33const Cache = std.Build.Cache;
44
5const usage = "usage: incr-check <zig binary path> <input file> [--zig-lib-dir lib] [--debug-zcu] [--debug-link] [--preserve-tmp] [--zig-cc-binary /path/to/zig]";
5const usage = "usage: incr-check <zig binary path> <input file> [--zig-lib-dir lib] [--debug-zcu] [--debug-dwarf] [--debug-link] [--preserve-tmp] [--zig-cc-binary /path/to/zig]";
66
77pub fn main() !void {
88 const fatal = std.process.fatal;
......@@ -16,6 +16,7 @@ pub fn main() !void {
1616 var opt_lib_dir: ?[]const u8 = null;
1717 var opt_cc_zig: ?[]const u8 = null;
1818 var debug_zcu = false;
19 var debug_dwarf = false;
1920 var debug_link = false;
2021 var preserve_tmp = false;
2122
......@@ -27,6 +28,8 @@ pub fn main() !void {
2728 opt_lib_dir = arg_it.next() orelse fatal("expected arg after '--zig-lib-dir'\n{s}", .{usage});
2829 } else if (std.mem.eql(u8, arg, "--debug-zcu")) {
2930 debug_zcu = true;
31 } else if (std.mem.eql(u8, arg, "--debug-dwarf")) {
32 debug_dwarf = true;
3033 } else if (std.mem.eql(u8, arg, "--debug-link")) {
3134 debug_link = true;
3235 } else if (std.mem.eql(u8, arg, "--preserve-tmp")) {
......@@ -85,7 +88,7 @@ pub fn main() !void {
8588
8689 const host = try std.zig.system.resolveTargetQuery(.{});
8790
88 const debug_log_verbose = debug_zcu or debug_link;
91 const debug_log_verbose = debug_zcu or debug_dwarf or debug_link;
8992
9093 for (case.targets) |target| {
9194 const target_prog_node = node: {
......@@ -125,6 +128,9 @@ pub fn main() !void {
125128 if (debug_zcu) {
126129 try child_args.appendSlice(arena, &.{ "--debug-log", "zcu" });
127130 }
131 if (debug_dwarf) {
132 try child_args.appendSlice(arena, &.{ "--debug-log", "dwarf" });
133 }
128134 if (debug_link) {
129135 try child_args.appendSlice(arena, &.{ "--debug-log", "link", "--debug-log", "link_state", "--debug-log", "link_relocs" });
130136 }
tools/lldb_pretty_printers.py+18-17
......@@ -25,7 +25,7 @@ def create_struct(parent, name, struct_type, inits):
2525 case lldb.eByteOrderBig:
2626 byte_order = 'big'
2727 field_bytes = field_init.to_bytes(field_size, byte_order, signed=field.type.GetTypeFlags() & lldb.eTypeIsSigned != 0)
28 elif isinstance(field_init_type, lldb.SBValue):
28 elif isinstance(field_init, lldb.SBValue):
2929 field_bytes = field_init.data.uint8
3030 else: return
3131 match struct_data.byte_order:
......@@ -731,7 +731,7 @@ def root_InternPool_Index_SummaryProvider(value, _=None):
731731 if not unwrapped: return '' # .none
732732 tag = unwrapped.GetChildMemberWithName('tag')
733733 tag_value = tag.value
734 summary = tag.CreateValueFromType(tag.type).GetChildMemberWithName('encodings').GetChildMemberWithName(tag_value.removeprefix('.')).GetChildMemberWithName('summary')
734 summary = tag.CreateValueFromType(tag.type).GetChildMemberWithName('encodings').GetChildMemberWithName(tag_value.removeprefix('.').removeprefix('@"').removesuffix('"').replace(r'\"', '"')).GetChildMemberWithName('summary')
735735 if not summary: return tag_value
736736 return re.sub(
737737 expr_path_re,
......@@ -767,7 +767,7 @@ class root_InternPool_Index_Unwrapped_SynthProvider:
767767 shared = ip.GetChildMemberWithName('locals').GetSyntheticValue().child[self.value.GetChildMemberWithName('tid').unsigned].GetChildMemberWithName('shared')
768768 item = shared.GetChildMemberWithName('items').GetChildMemberWithName('view').child[index.unsigned]
769769 self.tag, item_data = item.GetChildMemberWithName('tag'), item.GetChildMemberWithName('data')
770 encoding = self.tag.CreateValueFromType(self.tag.type).GetChildMemberWithName('encodings').GetChildMemberWithName(self.tag.value.removeprefix('.'))
770 encoding = self.tag.CreateValueFromType(self.tag.type).GetChildMemberWithName('encodings').GetChildMemberWithName(self.tag.value.removeprefix('.').removeprefix('@"').removesuffix('"').replace(r'\"', '"'))
771771 encoding_index, encoding_data, encoding_payload, encoding_trailing, encoding_config = encoding.GetChildMemberWithName('index'), encoding.GetChildMemberWithName('data'), encoding.GetChildMemberWithName('payload'), encoding.GetChildMemberWithName('trailing'), encoding.GetChildMemberWithName('config')
772772 if encoding_index:
773773 index_type = encoding_index.GetValueAsType()
......@@ -869,6 +869,7 @@ class root_InternPool_Index_Unwrapped_SynthProvider:
869869
870870def root_InternPool_String_SummaryProvider(value, _=None):
871871 wrapped = value.unsigned
872 if wrapped == (1 << 32) - 1: return ''
872873 ip = value.CreateValueFromType(value.type).GetChildMemberWithName('debug_state').GetChildMemberWithName('intern_pool').GetNonSyntheticValue().GetChildMemberWithName('?')
873874 tid_shift_32 = ip.GetChildMemberWithName('tid_shift_32').unsigned
874875 locals_value = ip.GetChildMemberWithName('locals').GetSyntheticValue()
......@@ -880,24 +881,24 @@ def root_InternPool_String_SummaryProvider(value, _=None):
880881 string.format = lldb.eFormatCString
881882 return string.value
882883
883class root_InternPool_Cau_Index_SynthProvider:
884class root_InternPool_TrackedInst_Index_SynthProvider:
884885 def __init__(self, value, _=None): self.value = value
885886 def update(self):
886 self.cau = None
887 self.tracked_inst = None
887888 wrapped = self.value.unsigned
888889 if wrapped == (1 << 32) - 1: return
889890 ip = self.value.CreateValueFromType(self.value.type).GetChildMemberWithName('debug_state').GetChildMemberWithName('intern_pool').GetNonSyntheticValue().GetChildMemberWithName('?')
890 tid_shift_31 = ip.GetChildMemberWithName('tid_shift_31').unsigned
891 tid_shift_32 = ip.GetChildMemberWithName('tid_shift_32').unsigned
891892 locals_value = ip.GetChildMemberWithName('locals').GetSyntheticValue()
892 local_value = locals_value.child[wrapped >> tid_shift_31]
893 local_value = locals_value.child[wrapped >> tid_shift_32]
893894 if local_value is None:
894895 wrapped = 0
895896 local_value = locals_value.child[0]
896 self.cau = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('caus').GetChildMemberWithName('view').GetChildMemberWithName('0').child[wrapped & (1 << tid_shift_31) - 1]
897 def has_children(self): return self.cau.GetNumChildren(1) > 0
898 def num_children(self): return self.cau.GetNumChildren()
899 def get_child_index(self, name): return self.cau.GetIndexOfChildWithName(name)
900 def get_child_at_index(self, index): return self.cau.GetChildAtIndex(index)
897 self.tracked_inst = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('tracked_insts').GetChildMemberWithName('view').GetChildMemberWithName('0').child[wrapped & (1 << tid_shift_32) - 1]
898 def has_children(self): return False if self.tracked_inst is None else self.tracked_inst.GetNumChildren(1) > 0
899 def num_children(self): return 0 if self.tracked_inst is None else self.tracked_inst.GetNumChildren()
900 def get_child_index(self, name): return -1 if self.tracked_inst is None else self.tracked_inst.GetIndexOfChildWithName(name)
901 def get_child_at_index(self, index): return None if self.tracked_inst is None else self.tracked_inst.GetChildAtIndex(index)
901902
902903class root_InternPool_Nav_Index_SynthProvider:
903904 def __init__(self, value, _=None): self.value = value
......@@ -913,10 +914,10 @@ class root_InternPool_Nav_Index_SynthProvider:
913914 wrapped = 0
914915 local_value = locals_value.child[0]
915916 self.nav = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('navs').GetChildMemberWithName('view').child[wrapped & (1 << tid_shift_32) - 1]
916 def has_children(self): return self.nav.GetNumChildren(1) > 0
917 def num_children(self): return self.nav.GetNumChildren()
918 def get_child_index(self, name): return self.nav.GetIndexOfChildWithName(name)
919 def get_child_at_index(self, index): return self.nav.GetChildAtIndex(index)
917 def has_children(self): return False if self.nav is None else self.nav.GetNumChildren(1) > 0
918 def num_children(self): return 0 if self.nav is None else self.nav.GetNumChildren()
919 def get_child_index(self, name): return -1 if self.nav is None else self.nav.GetIndexOfChildWithName(name)
920 def get_child_at_index(self, index): return None if self.nav is None else self.nav.GetChildAtIndex(index)
920921
921922# Initialize
922923
......@@ -973,5 +974,5 @@ def __lldb_init_module(debugger, _=None):
973974 add(debugger, category='zig', type='root.InternPool.Index', synth=True, summary=True)
974975 add(debugger, category='zig', type='root.InternPool.Index.Unwrapped', synth=True)
975976 add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.(Optional)?(NullTerminated)?String$', identifier='root_InternPool_String', summary=True)
976 add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.Cau\.Index(\.Optional)?$', identifier='root_InternPool_Cau_Index', synth=True)
977 add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.TrackedInst\.Index(\.Optional)?$', identifier='root_InternPool_TrackedInst_Index', synth=True)
977978 add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.Nav\.Index(\.Optional)?$', identifier='root_InternPool_Nav_Index', synth=True)