Merge pull request #22412 from mlugg/line-number-incremental
incremental: debug line number updates
This commit is contained in:
@@ -64,7 +64,7 @@ stage3-debug/bin/zig build \
|
||||
|
||||
stage3-debug/bin/zig build test docs \
|
||||
--maxrss 21000000000 \
|
||||
-Dlldb=$HOME/deps/lldb-zig/Debug-bfeada333/bin/lldb \
|
||||
-Dlldb=$HOME/deps/lldb-zig/Debug-e0a42bb34/bin/lldb \
|
||||
-fqemu \
|
||||
-fwasmtime \
|
||||
-Dstatic-llvm \
|
||||
|
||||
@@ -64,7 +64,7 @@ stage3-release/bin/zig build \
|
||||
|
||||
stage3-release/bin/zig build test docs \
|
||||
--maxrss 21000000000 \
|
||||
-Dlldb=$HOME/deps/lldb-zig/Release-bfeada333/bin/lldb \
|
||||
-Dlldb=$HOME/deps/lldb-zig/Release-e0a42bb34/bin/lldb \
|
||||
-fqemu \
|
||||
-fwasmtime \
|
||||
-Dstatic-llvm \
|
||||
|
||||
@@ -348,6 +348,7 @@ const Job = union(enum) {
|
||||
/// Corresponds to the task in `link.Task`.
|
||||
/// Only needed for backends that haven't yet been updated to not race against Sema.
|
||||
codegen_type: InternPool.Index,
|
||||
update_line_number: InternPool.TrackedInst.Index,
|
||||
/// The `AnalUnit`, which is *not* a `func`, must be semantically analyzed.
|
||||
/// This may be its first time being analyzed, or it may be outdated.
|
||||
/// If the unit is a function, a `codegen_func` job will then be queued.
|
||||
@@ -3718,6 +3719,9 @@ fn processOneJob(tid: usize, comp: *Compilation, job: Job, prog_node: std.Progre
|
||||
.codegen_type => |ty| {
|
||||
comp.dispatchCodegenTask(tid, .{ .codegen_type = ty });
|
||||
},
|
||||
.update_line_number => |ti| {
|
||||
comp.dispatchCodegenTask(tid, .{ .update_line_number = ti });
|
||||
},
|
||||
.analyze_func => |func| {
|
||||
const named_frame = tracy.namedFrame("analyze_func");
|
||||
defer named_frame.end();
|
||||
|
||||
@@ -168,6 +168,8 @@ pub const TrackedInst = extern struct {
|
||||
_ => @enumFromInt(@intFromEnum(opt)),
|
||||
};
|
||||
}
|
||||
|
||||
const debug_state = InternPool.debug_state;
|
||||
};
|
||||
|
||||
pub const Unwrapped = struct {
|
||||
@@ -187,6 +189,8 @@ pub const TrackedInst = extern struct {
|
||||
.index = @intFromEnum(tracked_inst_index) & ip.getIndexMask(u32),
|
||||
};
|
||||
}
|
||||
|
||||
const debug_state = InternPool.debug_state;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -508,7 +512,7 @@ pub const Nav = struct {
|
||||
/// The fully-qualified name of this `Nav`.
|
||||
fqn: NullTerminatedString,
|
||||
/// This field is populated iff this `Nav` is resolved by semantic analysis.
|
||||
/// If this is `null`, then `status == .resolved` always.
|
||||
/// If this is `null`, then `status == .fully_resolved` always.
|
||||
analysis: ?struct {
|
||||
namespace: NamespaceIndex,
|
||||
zir_index: TrackedInst.Index,
|
||||
@@ -6631,6 +6635,8 @@ pub fn activate(ip: *const InternPool) void {
|
||||
_ = OptionalString.debug_state;
|
||||
_ = NullTerminatedString.debug_state;
|
||||
_ = OptionalNullTerminatedString.debug_state;
|
||||
_ = TrackedInst.Index.debug_state;
|
||||
_ = TrackedInst.Index.Optional.debug_state;
|
||||
_ = Nav.Index.debug_state;
|
||||
_ = Nav.Index.Optional.debug_state;
|
||||
std.debug.assert(debug_state.intern_pool == null);
|
||||
|
||||
@@ -379,6 +379,7 @@ fn cleanupUpdatedFiles(gpa: Allocator, updated_files: *std.AutoArrayHashMapUnman
|
||||
pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
|
||||
assert(pt.tid == .main);
|
||||
const zcu = pt.zcu;
|
||||
const comp = zcu.comp;
|
||||
const ip = &zcu.intern_pool;
|
||||
const gpa = zcu.gpa;
|
||||
|
||||
@@ -435,8 +436,19 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
|
||||
|
||||
const old_zir = file.prev_zir.?.*;
|
||||
const new_zir = file.zir;
|
||||
const old_tag = old_zir.instructions.items(.tag);
|
||||
const old_data = old_zir.instructions.items(.data);
|
||||
const old_tag = old_zir.instructions.items(.tag)[@intFromEnum(old_inst)];
|
||||
const old_data = old_zir.instructions.items(.data)[@intFromEnum(old_inst)];
|
||||
|
||||
switch (old_tag) {
|
||||
.declaration => {
|
||||
const old_line = old_zir.getDeclaration(old_inst).src_line;
|
||||
const new_line = new_zir.getDeclaration(new_inst).src_line;
|
||||
if (old_line != new_line) {
|
||||
try comp.queueJob(.{ .update_line_number = tracked_inst_index });
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
|
||||
if (new_zir.getAssociatedSrcHash(new_inst)) |new_hash| {
|
||||
@@ -455,8 +467,8 @@ pub fn updateZirRefs(pt: Zcu.PerThread) Allocator.Error!void {
|
||||
}
|
||||
|
||||
// If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
|
||||
const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
|
||||
.extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
|
||||
const has_namespace = switch (old_tag) {
|
||||
.extended => switch (old_data.extended.opcode) {
|
||||
.struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
|
||||
else => false,
|
||||
},
|
||||
@@ -2517,8 +2529,6 @@ const ScanDeclIter = struct {
|
||||
);
|
||||
try comp.queueJob(.{ .analyze_comptime_unit = unit });
|
||||
}
|
||||
|
||||
// TODO: we used to do line number updates here, but this is an inappropriate place for this logic to live.
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3152,6 +3162,15 @@ pub fn linkerUpdateContainerType(pt: Zcu.PerThread, ty: InternPool.Index) !void
|
||||
}
|
||||
}
|
||||
|
||||
pub fn linkerUpdateLineNumber(pt: Zcu.PerThread, ti: InternPool.TrackedInst.Index) !void {
|
||||
if (pt.zcu.comp.bin_file) |lf| {
|
||||
lf.updateLineNumber(pt, ti) catch |err| switch (err) {
|
||||
error.OutOfMemory => return error.OutOfMemory,
|
||||
else => |e| log.err("update line number failed: {s}", .{@errorName(e)}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reportRetryableAstGenError(
|
||||
pt: Zcu.PerThread,
|
||||
src: Zcu.AstGenSrc,
|
||||
|
||||
27
src/link.zig
27
src/link.zig
@@ -727,16 +727,22 @@ pub const File = struct {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateNavLineNumber(
|
||||
base: *File,
|
||||
pt: Zcu.PerThread,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
) UpdateNavError!void {
|
||||
/// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because
|
||||
/// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`.
|
||||
pub fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) UpdateNavError!void {
|
||||
{
|
||||
const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?;
|
||||
const file = pt.zcu.fileByIndex(ti.file);
|
||||
assert(file.zir_loaded);
|
||||
const inst = file.zir.instructions.get(@intFromEnum(ti.inst));
|
||||
assert(inst.tag == .declaration);
|
||||
}
|
||||
|
||||
switch (base.tag) {
|
||||
.spirv, .nvptx => {},
|
||||
inline else => |tag| {
|
||||
dev.check(tag.devFeature());
|
||||
return @as(*tag.Type(), @fieldParentPtr("base", base)).updateNavineNumber(pt, nav_index);
|
||||
return @as(*tag.Type(), @fieldParentPtr("base", base)).updateLineNumber(pt, ti_id);
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1407,6 +1413,8 @@ pub const Task = union(enum) {
|
||||
codegen_func: CodegenFunc,
|
||||
codegen_type: InternPool.Index,
|
||||
|
||||
update_line_number: InternPool.TrackedInst.Index,
|
||||
|
||||
pub const CodegenFunc = struct {
|
||||
/// This will either be a non-generic `func_decl` or a `func_instance`.
|
||||
func: InternPool.Index,
|
||||
@@ -1558,6 +1566,13 @@ pub fn doTask(comp: *Compilation, tid: usize, task: Task) void {
|
||||
error.OutOfMemory => diags.setAllocFailure(),
|
||||
};
|
||||
},
|
||||
.update_line_number => |ti| {
|
||||
const pt: Zcu.PerThread = .activate(comp.zcu.?, @enumFromInt(tid));
|
||||
defer pt.deactivate();
|
||||
pt.linkerUpdateLineNumber(ti) catch |err| switch (err) {
|
||||
error.OutOfMemory => diags.setAllocFailure(),
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -379,12 +379,12 @@ pub fn updateNav(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !
|
||||
gop.value_ptr.fwd_decl = try self.addString(object.dg.fwd_decl.items);
|
||||
}
|
||||
|
||||
pub fn updateNavLineNumber(self: *C, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
|
||||
pub fn updateLineNumber(self: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
// The C backend does not have the ability to fix line numbers without re-generating
|
||||
// the entire Decl.
|
||||
_ = self;
|
||||
_ = pt;
|
||||
_ = nav_index;
|
||||
_ = ti_id;
|
||||
}
|
||||
|
||||
pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) !void {
|
||||
|
||||
@@ -2484,11 +2484,11 @@ pub fn getGlobalSymbol(coff: *Coff, name: []const u8, lib_name_name: ?[]const u8
|
||||
return global_index;
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(coff: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateLineNumber(coff: *Coff, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
_ = coff;
|
||||
_ = pt;
|
||||
_ = decl_index;
|
||||
log.debug("TODO implement updateDeclLineNumber", .{});
|
||||
_ = ti_id;
|
||||
log.debug("TODO implement updateLineNumber", .{});
|
||||
}
|
||||
|
||||
/// TODO: note if we need to rewrite base relocations by dirtying any of the entries in the global table
|
||||
|
||||
1133
src/link/Dwarf.zig
1133
src/link/Dwarf.zig
File diff suppressed because it is too large
Load Diff
@@ -2372,9 +2372,9 @@ pub fn updateExports(
|
||||
return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);
|
||||
}
|
||||
|
||||
pub fn updateNavLineNumber(self: *Elf, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
|
||||
pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
if (self.llvm_object) |_| return;
|
||||
return self.zigObjectPtr().?.updateNavLineNumber(pt, nav);
|
||||
return self.zigObjectPtr().?.updateLineNumber(pt, ti_id);
|
||||
}
|
||||
|
||||
pub fn deleteExport(
|
||||
|
||||
@@ -1463,19 +1463,7 @@ pub fn updateFunc(
|
||||
break :blk .{ atom_ptr.value, atom_ptr.alignment };
|
||||
};
|
||||
|
||||
if (debug_wip_nav) |*wip_nav| {
|
||||
const sym = self.symbol(sym_index);
|
||||
try self.dwarf.?.finishWipNav(
|
||||
pt,
|
||||
func.owner_nav,
|
||||
.{
|
||||
.index = sym_index,
|
||||
.addr = @intCast(sym.address(.{}, elf_file)),
|
||||
.size = self.atom(sym.ref.index).?.size,
|
||||
},
|
||||
wip_nav,
|
||||
);
|
||||
}
|
||||
if (debug_wip_nav) |*wip_nav| try self.dwarf.?.finishWipNavFunc(pt, func.owner_nav, code.len, wip_nav);
|
||||
|
||||
// Exports will be updated by `Zcu.processExports` after the update.
|
||||
|
||||
@@ -1546,13 +1534,21 @@ pub fn updateNav(
|
||||
.func => .none,
|
||||
.variable => |variable| variable.init,
|
||||
.@"extern" => |@"extern"| {
|
||||
if (ip.isFunctionType(@"extern".ty)) return;
|
||||
const sym_index = try self.getGlobalSymbol(
|
||||
elf_file,
|
||||
nav.name.toSlice(ip),
|
||||
@"extern".lib_name.toSlice(ip),
|
||||
);
|
||||
self.symbol(sym_index).flags.is_extern_ptr = true;
|
||||
if (!ip.isFunctionType(@"extern".ty)) {
|
||||
const sym = self.symbol(sym_index);
|
||||
sym.flags.is_extern_ptr = true;
|
||||
if (@"extern".is_threadlocal) sym.flags.is_tls = true;
|
||||
}
|
||||
if (self.dwarf) |*dwarf| dwarf: {
|
||||
var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;
|
||||
defer debug_wip_nav.deinit();
|
||||
try dwarf.finishWipNav(pt, nav_index, &debug_wip_nav);
|
||||
}
|
||||
return;
|
||||
},
|
||||
else => nav.status.fully_resolved.val,
|
||||
@@ -1596,19 +1592,7 @@ pub fn updateNav(
|
||||
else
|
||||
try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT);
|
||||
|
||||
if (debug_wip_nav) |*wip_nav| {
|
||||
const sym = self.symbol(sym_index);
|
||||
try self.dwarf.?.finishWipNav(
|
||||
pt,
|
||||
nav_index,
|
||||
.{
|
||||
.index = sym_index,
|
||||
.addr = @intCast(sym.address(.{}, elf_file)),
|
||||
.size = sym.atom(elf_file).?.size,
|
||||
},
|
||||
wip_nav,
|
||||
);
|
||||
}
|
||||
if (debug_wip_nav) |*wip_nav| try self.dwarf.?.finishWipNav(pt, nav_index, wip_nav);
|
||||
} else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index);
|
||||
|
||||
// Exports will be updated by `Zcu.processExports` after the update.
|
||||
@@ -1863,22 +1847,9 @@ pub fn updateExports(
|
||||
}
|
||||
}
|
||||
|
||||
/// Must be called only after a successful call to `updateNav`.
|
||||
pub fn updateNavLineNumber(
|
||||
self: *ZigObject,
|
||||
pt: Zcu.PerThread,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const ip = &pt.zcu.intern_pool;
|
||||
const nav = ip.getNav(nav_index);
|
||||
|
||||
log.debug("updateNavLineNumber {}({d})", .{ nav.fqn.fmt(ip), nav_index });
|
||||
|
||||
pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
if (self.dwarf) |*dwarf| {
|
||||
try dwarf.updateNavLineNumber(pt.zcu, nav_index);
|
||||
try dwarf.updateLineNumber(pt.zcu, ti_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3014,9 +3014,9 @@ pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !vo
|
||||
return self.getZigObject().?.updateNav(self, pt, nav);
|
||||
}
|
||||
|
||||
pub fn updateNavLineNumber(self: *MachO, pt: Zcu.PerThread, nav: InternPool.NavIndex) !void {
|
||||
pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
if (self.llvm_object) |_| return;
|
||||
return self.getZigObject().?.updateNavLineNumber(pt, nav);
|
||||
return self.getZigObject().?.updateLineNumber(pt, ti_id);
|
||||
}
|
||||
|
||||
pub fn updateExports(
|
||||
|
||||
@@ -780,8 +780,8 @@ pub fn updateFunc(
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
var dwarf_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
|
||||
defer if (dwarf_wip_nav) |*wip_nav| wip_nav.deinit();
|
||||
var debug_wip_nav = if (self.dwarf) |*dwarf| try dwarf.initWipNav(pt, func.owner_nav, sym_index) else null;
|
||||
defer if (debug_wip_nav) |*wip_nav| wip_nav.deinit();
|
||||
|
||||
const res = try codegen.generateFunction(
|
||||
&macho_file.base,
|
||||
@@ -791,7 +791,7 @@ pub fn updateFunc(
|
||||
air,
|
||||
liveness,
|
||||
&code_buffer,
|
||||
if (dwarf_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
|
||||
if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
|
||||
);
|
||||
|
||||
const code = switch (res) {
|
||||
@@ -813,19 +813,7 @@ pub fn updateFunc(
|
||||
break :blk .{ atom.value, atom.alignment };
|
||||
};
|
||||
|
||||
if (dwarf_wip_nav) |*wip_nav| {
|
||||
const sym = self.symbols.items[sym_index];
|
||||
try self.dwarf.?.finishWipNav(
|
||||
pt,
|
||||
func.owner_nav,
|
||||
.{
|
||||
.index = sym_index,
|
||||
.addr = sym.getAddress(.{}, macho_file),
|
||||
.size = sym.getAtom(macho_file).?.size,
|
||||
},
|
||||
wip_nav,
|
||||
);
|
||||
}
|
||||
if (debug_wip_nav) |*wip_nav| try self.dwarf.?.finishWipNavFunc(pt, func.owner_nav, code.len, wip_nav);
|
||||
|
||||
// Exports will be updated by `Zcu.processExports` after the update.
|
||||
if (old_rva != new_rva and old_rva > 0) {
|
||||
@@ -883,13 +871,20 @@ pub fn updateNav(
|
||||
.func => .none,
|
||||
.variable => |variable| variable.init,
|
||||
.@"extern" => |@"extern"| {
|
||||
if (ip.isFunctionType(@"extern".ty)) return;
|
||||
// Extern variable gets a __got entry only
|
||||
const name = @"extern".name.toSlice(ip);
|
||||
const lib_name = @"extern".lib_name.toSlice(ip);
|
||||
const index = try self.getGlobalSymbol(macho_file, name, lib_name);
|
||||
const sym = &self.symbols.items[index];
|
||||
sym.flags.is_extern_ptr = true;
|
||||
const sym_index = try self.getGlobalSymbol(macho_file, name, lib_name);
|
||||
if (!ip.isFunctionType(@"extern".ty)) {
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
sym.flags.is_extern_ptr = true;
|
||||
if (@"extern".is_threadlocal) sym.flags.tlv = true;
|
||||
}
|
||||
if (self.dwarf) |*dwarf| dwarf: {
|
||||
var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, sym_index) orelse break :dwarf;
|
||||
defer debug_wip_nav.deinit();
|
||||
try dwarf.finishWipNav(pt, nav_index, &debug_wip_nav);
|
||||
}
|
||||
return;
|
||||
},
|
||||
else => nav.status.fully_resolved.val,
|
||||
@@ -927,19 +922,7 @@ pub fn updateNav(
|
||||
else
|
||||
try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code);
|
||||
|
||||
if (debug_wip_nav) |*wip_nav| {
|
||||
const sym = self.symbols.items[sym_index];
|
||||
try self.dwarf.?.finishWipNav(
|
||||
pt,
|
||||
nav_index,
|
||||
.{
|
||||
.index = sym_index,
|
||||
.addr = sym.getAddress(.{}, macho_file),
|
||||
.size = sym.getAtom(macho_file).?.size,
|
||||
},
|
||||
wip_nav,
|
||||
);
|
||||
}
|
||||
if (debug_wip_nav) |*wip_nav| try self.dwarf.?.finishWipNav(pt, nav_index, wip_nav);
|
||||
} else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index);
|
||||
|
||||
// Exports will be updated by `Zcu.processExports` after the update.
|
||||
@@ -1432,14 +1415,9 @@ fn updateLazySymbol(
|
||||
try macho_file.base.file.?.pwriteAll(code, file_offset);
|
||||
}
|
||||
|
||||
/// Must be called only after a successful call to `updateNav`.
|
||||
pub fn updateNavLineNumber(
|
||||
self: *ZigObject,
|
||||
pt: Zcu.PerThread,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
) !void {
|
||||
pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
if (self.dwarf) |*dwarf| {
|
||||
try dwarf.updateNavLineNumber(pt.zcu, nav_index);
|
||||
try dwarf.updateLineNumber(pt.zcu, ti_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1354,11 +1354,10 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void {
|
||||
}
|
||||
}
|
||||
|
||||
/// Must be called only after a successful call to `updateDecl`.
|
||||
pub fn updateDeclLineNumber(self: *Plan9, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex) !void {
|
||||
pub fn updateLineNumber(self: *Plan9, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
_ = self;
|
||||
_ = pt;
|
||||
_ = decl_index;
|
||||
_ = ti_id;
|
||||
}
|
||||
|
||||
pub fn getNavVAddr(
|
||||
|
||||
@@ -1574,9 +1574,9 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !voi
|
||||
try wasm.zig_object.?.updateNav(wasm, pt, nav);
|
||||
}
|
||||
|
||||
pub fn updateNavLineNumber(wasm: *Wasm, pt: Zcu.PerThread, nav: InternPool.Nav.Index) !void {
|
||||
pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
if (wasm.llvm_object) |_| return;
|
||||
try wasm.zig_object.?.updateNavLineNumber(pt, nav);
|
||||
try wasm.zig_object.?.updateLineNumber(pt, ti_id);
|
||||
}
|
||||
|
||||
/// From a given symbol location, returns its `wasm.GlobalType`.
|
||||
|
||||
@@ -1074,15 +1074,9 @@ pub fn createDebugSectionForIndex(zig_object: *ZigObject, wasm: *Wasm, index: *?
|
||||
return atom_index;
|
||||
}
|
||||
|
||||
pub fn updateDeclLineNumber(
|
||||
zig_object: *ZigObject,
|
||||
pt: Zcu.PerThread,
|
||||
decl_index: InternPool.DeclIndex,
|
||||
) !void {
|
||||
pub fn updateLineNumber(zig_object: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
|
||||
if (zig_object.dwarf) |*dw| {
|
||||
const decl = pt.zcu.declPtr(decl_index);
|
||||
log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
|
||||
try dw.updateDeclLineNumber(pt.zcu, decl_index);
|
||||
try dw.updateLineNumber(pt.zcu, ti_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
32
test/incremental/change_generic_line_number
Normal file
32
test/incremental/change_generic_line_number
Normal file
@@ -0,0 +1,32 @@
|
||||
#target=x86_64-linux-selfhosted
|
||||
#update=initial version
|
||||
#file=main.zig
|
||||
const std = @import("std");
|
||||
fn Printer(message: []const u8) type {
|
||||
return struct {
|
||||
fn print() !void {
|
||||
try std.io.getStdOut().writeAll(message);
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn main() !void {
|
||||
try Printer("foo\n").print();
|
||||
try Printer("bar\n").print();
|
||||
}
|
||||
#expect_stdout="foo\nbar\n"
|
||||
#update=change line number
|
||||
#file=main.zig
|
||||
const std = @import("std");
|
||||
|
||||
fn Printer(message: []const u8) type {
|
||||
return struct {
|
||||
fn print() !void {
|
||||
try std.io.getStdOut().writeAll(message);
|
||||
}
|
||||
};
|
||||
}
|
||||
pub fn main() !void {
|
||||
try Printer("foo\n").print();
|
||||
try Printer("bar\n").print();
|
||||
}
|
||||
#expect_stdout="foo\nbar\n"
|
||||
16
test/incremental/change_line_number
Normal file
16
test/incremental/change_line_number
Normal file
@@ -0,0 +1,16 @@
|
||||
#target=x86_64-linux-selfhosted
|
||||
#update=initial version
|
||||
#file=main.zig
|
||||
const std = @import("std");
|
||||
pub fn main() !void {
|
||||
try std.io.getStdOut().writeAll("foo\n");
|
||||
}
|
||||
#expect_stdout="foo\n"
|
||||
#update=change line number
|
||||
#file=main.zig
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
try std.io.getStdOut().writeAll("foo\n");
|
||||
}
|
||||
#expect_stdout="foo\n"
|
||||
@@ -2,7 +2,7 @@ const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
const Cache = std.Build.Cache;
|
||||
|
||||
const 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]";
|
||||
const 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]";
|
||||
|
||||
pub fn main() !void {
|
||||
const fatal = std.process.fatal;
|
||||
@@ -16,6 +16,7 @@ pub fn main() !void {
|
||||
var opt_lib_dir: ?[]const u8 = null;
|
||||
var opt_cc_zig: ?[]const u8 = null;
|
||||
var debug_zcu = false;
|
||||
var debug_dwarf = false;
|
||||
var debug_link = false;
|
||||
var preserve_tmp = false;
|
||||
|
||||
@@ -27,6 +28,8 @@ pub fn main() !void {
|
||||
opt_lib_dir = arg_it.next() orelse fatal("expected arg after '--zig-lib-dir'\n{s}", .{usage});
|
||||
} else if (std.mem.eql(u8, arg, "--debug-zcu")) {
|
||||
debug_zcu = true;
|
||||
} else if (std.mem.eql(u8, arg, "--debug-dwarf")) {
|
||||
debug_dwarf = true;
|
||||
} else if (std.mem.eql(u8, arg, "--debug-link")) {
|
||||
debug_link = true;
|
||||
} else if (std.mem.eql(u8, arg, "--preserve-tmp")) {
|
||||
@@ -85,7 +88,7 @@ pub fn main() !void {
|
||||
|
||||
const host = try std.zig.system.resolveTargetQuery(.{});
|
||||
|
||||
const debug_log_verbose = debug_zcu or debug_link;
|
||||
const debug_log_verbose = debug_zcu or debug_dwarf or debug_link;
|
||||
|
||||
for (case.targets) |target| {
|
||||
const target_prog_node = node: {
|
||||
@@ -125,6 +128,9 @@ pub fn main() !void {
|
||||
if (debug_zcu) {
|
||||
try child_args.appendSlice(arena, &.{ "--debug-log", "zcu" });
|
||||
}
|
||||
if (debug_dwarf) {
|
||||
try child_args.appendSlice(arena, &.{ "--debug-log", "dwarf" });
|
||||
}
|
||||
if (debug_link) {
|
||||
try child_args.appendSlice(arena, &.{ "--debug-log", "link", "--debug-log", "link_state", "--debug-log", "link_relocs" });
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ def create_struct(parent, name, struct_type, inits):
|
||||
case lldb.eByteOrderBig:
|
||||
byte_order = 'big'
|
||||
field_bytes = field_init.to_bytes(field_size, byte_order, signed=field.type.GetTypeFlags() & lldb.eTypeIsSigned != 0)
|
||||
elif isinstance(field_init_type, lldb.SBValue):
|
||||
elif isinstance(field_init, lldb.SBValue):
|
||||
field_bytes = field_init.data.uint8
|
||||
else: return
|
||||
match struct_data.byte_order:
|
||||
@@ -731,7 +731,7 @@ def root_InternPool_Index_SummaryProvider(value, _=None):
|
||||
if not unwrapped: return '' # .none
|
||||
tag = unwrapped.GetChildMemberWithName('tag')
|
||||
tag_value = tag.value
|
||||
summary = tag.CreateValueFromType(tag.type).GetChildMemberWithName('encodings').GetChildMemberWithName(tag_value.removeprefix('.')).GetChildMemberWithName('summary')
|
||||
summary = tag.CreateValueFromType(tag.type).GetChildMemberWithName('encodings').GetChildMemberWithName(tag_value.removeprefix('.').removeprefix('@"').removesuffix('"').replace(r'\"', '"')).GetChildMemberWithName('summary')
|
||||
if not summary: return tag_value
|
||||
return re.sub(
|
||||
expr_path_re,
|
||||
@@ -767,7 +767,7 @@ class root_InternPool_Index_Unwrapped_SynthProvider:
|
||||
shared = ip.GetChildMemberWithName('locals').GetSyntheticValue().child[self.value.GetChildMemberWithName('tid').unsigned].GetChildMemberWithName('shared')
|
||||
item = shared.GetChildMemberWithName('items').GetChildMemberWithName('view').child[index.unsigned]
|
||||
self.tag, item_data = item.GetChildMemberWithName('tag'), item.GetChildMemberWithName('data')
|
||||
encoding = self.tag.CreateValueFromType(self.tag.type).GetChildMemberWithName('encodings').GetChildMemberWithName(self.tag.value.removeprefix('.'))
|
||||
encoding = self.tag.CreateValueFromType(self.tag.type).GetChildMemberWithName('encodings').GetChildMemberWithName(self.tag.value.removeprefix('.').removeprefix('@"').removesuffix('"').replace(r'\"', '"'))
|
||||
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')
|
||||
if encoding_index:
|
||||
index_type = encoding_index.GetValueAsType()
|
||||
@@ -869,6 +869,7 @@ class root_InternPool_Index_Unwrapped_SynthProvider:
|
||||
|
||||
def root_InternPool_String_SummaryProvider(value, _=None):
|
||||
wrapped = value.unsigned
|
||||
if wrapped == (1 << 32) - 1: return ''
|
||||
ip = value.CreateValueFromType(value.type).GetChildMemberWithName('debug_state').GetChildMemberWithName('intern_pool').GetNonSyntheticValue().GetChildMemberWithName('?')
|
||||
tid_shift_32 = ip.GetChildMemberWithName('tid_shift_32').unsigned
|
||||
locals_value = ip.GetChildMemberWithName('locals').GetSyntheticValue()
|
||||
@@ -880,24 +881,24 @@ def root_InternPool_String_SummaryProvider(value, _=None):
|
||||
string.format = lldb.eFormatCString
|
||||
return string.value
|
||||
|
||||
class root_InternPool_Cau_Index_SynthProvider:
|
||||
class root_InternPool_TrackedInst_Index_SynthProvider:
|
||||
def __init__(self, value, _=None): self.value = value
|
||||
def update(self):
|
||||
self.cau = None
|
||||
self.tracked_inst = None
|
||||
wrapped = self.value.unsigned
|
||||
if wrapped == (1 << 32) - 1: return
|
||||
ip = self.value.CreateValueFromType(self.value.type).GetChildMemberWithName('debug_state').GetChildMemberWithName('intern_pool').GetNonSyntheticValue().GetChildMemberWithName('?')
|
||||
tid_shift_31 = ip.GetChildMemberWithName('tid_shift_31').unsigned
|
||||
tid_shift_32 = ip.GetChildMemberWithName('tid_shift_32').unsigned
|
||||
locals_value = ip.GetChildMemberWithName('locals').GetSyntheticValue()
|
||||
local_value = locals_value.child[wrapped >> tid_shift_31]
|
||||
local_value = locals_value.child[wrapped >> tid_shift_32]
|
||||
if local_value is None:
|
||||
wrapped = 0
|
||||
local_value = locals_value.child[0]
|
||||
self.cau = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('caus').GetChildMemberWithName('view').GetChildMemberWithName('0').child[wrapped & (1 << tid_shift_31) - 1]
|
||||
def has_children(self): return self.cau.GetNumChildren(1) > 0
|
||||
def num_children(self): return self.cau.GetNumChildren()
|
||||
def get_child_index(self, name): return self.cau.GetIndexOfChildWithName(name)
|
||||
def get_child_at_index(self, index): return self.cau.GetChildAtIndex(index)
|
||||
self.tracked_inst = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('tracked_insts').GetChildMemberWithName('view').GetChildMemberWithName('0').child[wrapped & (1 << tid_shift_32) - 1]
|
||||
def has_children(self): return False if self.tracked_inst is None else self.tracked_inst.GetNumChildren(1) > 0
|
||||
def num_children(self): return 0 if self.tracked_inst is None else self.tracked_inst.GetNumChildren()
|
||||
def get_child_index(self, name): return -1 if self.tracked_inst is None else self.tracked_inst.GetIndexOfChildWithName(name)
|
||||
def get_child_at_index(self, index): return None if self.tracked_inst is None else self.tracked_inst.GetChildAtIndex(index)
|
||||
|
||||
class root_InternPool_Nav_Index_SynthProvider:
|
||||
def __init__(self, value, _=None): self.value = value
|
||||
@@ -913,10 +914,10 @@ class root_InternPool_Nav_Index_SynthProvider:
|
||||
wrapped = 0
|
||||
local_value = locals_value.child[0]
|
||||
self.nav = local_value.GetChildMemberWithName('shared').GetChildMemberWithName('navs').GetChildMemberWithName('view').child[wrapped & (1 << tid_shift_32) - 1]
|
||||
def has_children(self): return self.nav.GetNumChildren(1) > 0
|
||||
def num_children(self): return self.nav.GetNumChildren()
|
||||
def get_child_index(self, name): return self.nav.GetIndexOfChildWithName(name)
|
||||
def get_child_at_index(self, index): return self.nav.GetChildAtIndex(index)
|
||||
def has_children(self): return False if self.nav is None else self.nav.GetNumChildren(1) > 0
|
||||
def num_children(self): return 0 if self.nav is None else self.nav.GetNumChildren()
|
||||
def get_child_index(self, name): return -1 if self.nav is None else self.nav.GetIndexOfChildWithName(name)
|
||||
def get_child_at_index(self, index): return None if self.nav is None else self.nav.GetChildAtIndex(index)
|
||||
|
||||
# Initialize
|
||||
|
||||
@@ -973,5 +974,5 @@ def __lldb_init_module(debugger, _=None):
|
||||
add(debugger, category='zig', type='root.InternPool.Index', synth=True, summary=True)
|
||||
add(debugger, category='zig', type='root.InternPool.Index.Unwrapped', synth=True)
|
||||
add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.(Optional)?(NullTerminated)?String$', identifier='root_InternPool_String', summary=True)
|
||||
add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.Cau\.Index(\.Optional)?$', identifier='root_InternPool_Cau_Index', synth=True)
|
||||
add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.TrackedInst\.Index(\.Optional)?$', identifier='root_InternPool_TrackedInst_Index', synth=True)
|
||||
add(debugger, category='zig', regex=True, type=r'^root\.InternPool\.Nav\.Index(\.Optional)?$', identifier='root_InternPool_Nav_Index', synth=True)
|
||||
|
||||
Reference in New Issue
Block a user