mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
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();
|
||||
|
||||
+7
-1
@@ -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);
|
||||
|
||||
+25
-6
@@ -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,
|
||||
|
||||
+21
-6
@@ -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(),
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
+3
-3
@@ -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
|
||||
|
||||
+748
-385
@@ -8,6 +8,7 @@ mods: std.AutoArrayHashMapUnmanaged(*Module, ModInfo),
|
||||
types: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),
|
||||
values: std.AutoArrayHashMapUnmanaged(InternPool.Index, Entry.Index),
|
||||
navs: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, Entry.Index),
|
||||
decls: std.AutoArrayHashMapUnmanaged(InternPool.TrackedInst.Index, Entry.Index),
|
||||
|
||||
debug_abbrev: DebugAbbrev,
|
||||
debug_aranges: DebugAranges,
|
||||
@@ -51,9 +52,7 @@ pub const AddressSize = enum(u8) {
|
||||
const ModInfo = struct {
|
||||
root_dir_path: Entry.Index,
|
||||
dirs: std.AutoArrayHashMapUnmanaged(Unit.Index, void),
|
||||
files: Files,
|
||||
|
||||
const Files = std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void);
|
||||
files: std.AutoArrayHashMapUnmanaged(Zcu.File.Index, void),
|
||||
|
||||
fn deinit(mod_info: *ModInfo, gpa: std.mem.Allocator) void {
|
||||
mod_info.dirs.deinit(gpa);
|
||||
@@ -137,6 +136,20 @@ const DebugInfo = struct {
|
||||
return AbbrevCode.decl_bytes + dwarf.sectionOffsetBytes();
|
||||
}
|
||||
|
||||
fn declAbbrevCode(debug_info: *DebugInfo, unit: Unit.Index, entry: Entry.Index) !AbbrevCode {
|
||||
const dwarf: *Dwarf = @fieldParentPtr("debug_info", debug_info);
|
||||
const unit_ptr = debug_info.section.getUnit(unit);
|
||||
const entry_ptr = unit_ptr.getEntry(entry);
|
||||
if (entry_ptr.len < AbbrevCode.decl_bytes) return .null;
|
||||
var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined;
|
||||
if (try dwarf.getFile().?.preadAll(
|
||||
&abbrev_code_buf,
|
||||
debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
|
||||
) != abbrev_code_buf.len) return error.InputOutput;
|
||||
var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
|
||||
return @enumFromInt(std.leb.readUleb128(@typeInfo(AbbrevCode).@"enum".tag_type, abbrev_code_fbs.reader()) catch unreachable);
|
||||
}
|
||||
|
||||
const trailer_bytes = 1 + 1;
|
||||
};
|
||||
|
||||
@@ -206,8 +219,8 @@ const StringSection = struct {
|
||||
const unit: Unit.Index = @enumFromInt(0);
|
||||
|
||||
const init: StringSection = .{
|
||||
.contents = .{},
|
||||
.map = .{},
|
||||
.contents = .empty,
|
||||
.map = .empty,
|
||||
.section = Section.init,
|
||||
};
|
||||
|
||||
@@ -219,9 +232,9 @@ const StringSection = struct {
|
||||
|
||||
fn addString(str_sec: *StringSection, dwarf: *Dwarf, str: []const u8) UpdateError!Entry.Index {
|
||||
const gop = try str_sec.map.getOrPutAdapted(dwarf.gpa, str, Adapter{ .str_sec = str_sec });
|
||||
errdefer _ = str_sec.map.pop();
|
||||
const entry: Entry.Index = @enumFromInt(gop.index);
|
||||
if (!gop.found_existing) {
|
||||
errdefer _ = str_sec.map.pop();
|
||||
const unit_ptr = str_sec.section.getUnit(unit);
|
||||
assert(try str_sec.section.getUnit(unit).addEntry(dwarf.gpa) == entry);
|
||||
errdefer _ = unit_ptr.entries.pop();
|
||||
@@ -284,7 +297,7 @@ pub const Section = struct {
|
||||
.index = std.math.maxInt(u32),
|
||||
.first = .none,
|
||||
.last = .none,
|
||||
.units = .{},
|
||||
.units = .empty,
|
||||
.len = 0,
|
||||
};
|
||||
|
||||
@@ -319,13 +332,14 @@ pub const Section = struct {
|
||||
.next = .none,
|
||||
.first = .none,
|
||||
.last = .none,
|
||||
.free = .none,
|
||||
.header_len = aligned_header_len,
|
||||
.trailer_len = aligned_trailer_len,
|
||||
.off = 0,
|
||||
.len = aligned_header_len + aligned_trailer_len,
|
||||
.entries = .{},
|
||||
.cross_unit_relocs = .{},
|
||||
.cross_section_relocs = .{},
|
||||
.entries = .empty,
|
||||
.cross_unit_relocs = .empty,
|
||||
.cross_section_relocs = .empty,
|
||||
};
|
||||
if (sec.last.unwrap()) |last_unit| {
|
||||
const last_unit_ptr = sec.getUnit(last_unit);
|
||||
@@ -385,6 +399,28 @@ pub const Section = struct {
|
||||
try unit_ptr.getEntry(entry).replace(unit_ptr, sec, dwarf, contents);
|
||||
}
|
||||
|
||||
fn freeEntry(sec: *Section, unit: Unit.Index, entry: Entry.Index, dwarf: *Dwarf) UpdateError!void {
|
||||
const unit_ptr = sec.getUnit(unit);
|
||||
const entry_ptr = unit_ptr.getEntry(entry);
|
||||
if (entry_ptr.len > 0) {
|
||||
if (entry_ptr.next.unwrap()) |next_entry| unit_ptr.getEntry(next_entry).prev = entry_ptr.prev;
|
||||
if (entry_ptr.prev.unwrap()) |prev_entry| {
|
||||
const prev_entry_ptr = unit_ptr.getEntry(prev_entry);
|
||||
prev_entry_ptr.next = entry_ptr.next;
|
||||
try prev_entry_ptr.pad(unit_ptr, sec, dwarf);
|
||||
} else {
|
||||
unit_ptr.trim();
|
||||
sec.trim(dwarf);
|
||||
}
|
||||
} else assert(entry_ptr.prev == .none and entry_ptr.next == .none);
|
||||
entry_ptr.prev = .none;
|
||||
entry_ptr.next = unit_ptr.free;
|
||||
entry_ptr.off = 0;
|
||||
entry_ptr.len = 0;
|
||||
entry_ptr.clear();
|
||||
unit_ptr.free = entry.toOptional();
|
||||
}
|
||||
|
||||
fn resize(sec: *Section, dwarf: *Dwarf, len: u64) UpdateError!void {
|
||||
if (len <= sec.len) return;
|
||||
if (dwarf.bin_file.cast(.elf)) |elf_file| {
|
||||
@@ -449,6 +485,7 @@ const Unit = struct {
|
||||
next: Index.Optional,
|
||||
first: Entry.Index.Optional,
|
||||
last: Entry.Index.Optional,
|
||||
free: Entry.Index.Optional,
|
||||
/// offset within containing section
|
||||
off: u32,
|
||||
header_len: u32,
|
||||
@@ -491,6 +528,12 @@ const Unit = struct {
|
||||
}
|
||||
|
||||
fn addEntry(unit: *Unit, gpa: std.mem.Allocator) std.mem.Allocator.Error!Entry.Index {
|
||||
if (unit.free.unwrap()) |entry| {
|
||||
const entry_ptr = unit.getEntry(entry);
|
||||
unit.free = entry_ptr.next;
|
||||
entry_ptr.next = .none;
|
||||
return entry;
|
||||
}
|
||||
const entry: Entry.Index = @enumFromInt(unit.entries.items.len);
|
||||
const entry_ptr = try unit.entries.addOne(gpa);
|
||||
entry_ptr.* = .{
|
||||
@@ -498,10 +541,10 @@ const Unit = struct {
|
||||
.next = .none,
|
||||
.off = 0,
|
||||
.len = 0,
|
||||
.cross_entry_relocs = .{},
|
||||
.cross_unit_relocs = .{},
|
||||
.cross_section_relocs = .{},
|
||||
.external_relocs = .{},
|
||||
.cross_entry_relocs = .empty,
|
||||
.cross_unit_relocs = .empty,
|
||||
.cross_section_relocs = .empty,
|
||||
.external_relocs = .empty,
|
||||
};
|
||||
return entry;
|
||||
}
|
||||
@@ -1583,7 +1626,7 @@ pub const WipNav = struct {
|
||||
const dlw = wip_nav.debug_line.writer(dwarf.gpa);
|
||||
if (dwarf.incremental()) {
|
||||
const new_nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, new_func_info.owner_nav);
|
||||
errdefer _ = dwarf.navs.pop();
|
||||
errdefer _ = if (!new_nav_gop.found_existing) dwarf.navs.pop();
|
||||
if (!new_nav_gop.found_existing) new_nav_gop.value_ptr.* = try dwarf.addCommonEntry(new_unit);
|
||||
|
||||
try dlw.writeByte(DW.LNS.extended_op);
|
||||
@@ -1603,10 +1646,8 @@ pub const WipNav = struct {
|
||||
const old_file = zcu.navFileScopeIndex(old_func_info.owner_nav);
|
||||
if (old_file != new_file) {
|
||||
const mod_info = dwarf.getModInfo(wip_nav.unit);
|
||||
const mod_gop = try mod_info.dirs.getOrPut(dwarf.gpa, new_unit);
|
||||
errdefer _ = if (!mod_gop.found_existing) mod_info.dirs.pop();
|
||||
try mod_info.dirs.put(dwarf.gpa, new_unit, {});
|
||||
const file_gop = try mod_info.files.getOrPut(dwarf.gpa, new_file);
|
||||
errdefer _ = if (!file_gop.found_existing) mod_info.files.pop();
|
||||
|
||||
try dlw.writeByte(DW.LNS.set_file);
|
||||
try uleb128(dlw, file_gop.index);
|
||||
@@ -1934,6 +1975,90 @@ pub const WipNav = struct {
|
||||
std.math.big.int.Mutable.init(&big_int_space.limbs, field_index).toConst());
|
||||
}
|
||||
|
||||
fn declCommon(
|
||||
wip_nav: *WipNav,
|
||||
abbrev_code: struct {
|
||||
decl: AbbrevCode,
|
||||
generic_decl: AbbrevCode,
|
||||
instance: AbbrevCode,
|
||||
},
|
||||
nav: *const InternPool.Nav,
|
||||
file: Zcu.File.Index,
|
||||
decl: *const std.zig.Zir.Inst.Declaration.Unwrapped,
|
||||
) UpdateError!void {
|
||||
const zcu = wip_nav.pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const dwarf = wip_nav.dwarf;
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
|
||||
const orig_entry = wip_nav.entry;
|
||||
defer wip_nav.entry = orig_entry;
|
||||
const parent_type, const is_generic_decl = if (nav.analysis) |analysis| parent_info: {
|
||||
const parent_type: Type = .fromInterned(zcu.namespacePtr(analysis.namespace).owner_type);
|
||||
const decl_gop = try dwarf.decls.getOrPut(dwarf.gpa, analysis.zir_index);
|
||||
errdefer _ = if (!decl_gop.found_existing) dwarf.decls.pop();
|
||||
const was_generic_decl = decl_gop.found_existing and
|
||||
switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, decl_gop.value_ptr.*)) {
|
||||
else => unreachable,
|
||||
.decl_alias,
|
||||
.decl_enum,
|
||||
.decl_empty_enum,
|
||||
.decl_namespace_struct,
|
||||
.decl_struct,
|
||||
.decl_packed_struct,
|
||||
.decl_union,
|
||||
.decl_var,
|
||||
.decl_const,
|
||||
.decl_const_runtime_bits,
|
||||
.decl_const_comptime_state,
|
||||
.decl_const_runtime_bits_comptime_state,
|
||||
.decl_func,
|
||||
.decl_empty_func,
|
||||
.decl_func_generic,
|
||||
.decl_empty_func_generic,
|
||||
=> false,
|
||||
.generic_decl_alias,
|
||||
.generic_decl_enum,
|
||||
.generic_decl_struct,
|
||||
.generic_decl_union,
|
||||
.generic_decl_var,
|
||||
.generic_decl_const,
|
||||
.generic_decl_func,
|
||||
=> true,
|
||||
};
|
||||
if (parent_type.getCaptures(zcu).len == 0) {
|
||||
if (was_generic_decl) try dwarf.freeCommonEntry(wip_nav.unit, decl_gop.value_ptr.*);
|
||||
decl_gop.value_ptr.* = orig_entry;
|
||||
break :parent_info .{ parent_type, false };
|
||||
} else {
|
||||
if (was_generic_decl)
|
||||
dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(decl_gop.value_ptr.*).clear()
|
||||
else
|
||||
decl_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
|
||||
wip_nav.entry = decl_gop.value_ptr.*;
|
||||
break :parent_info .{ parent_type, true };
|
||||
}
|
||||
} else .{ null, false };
|
||||
|
||||
try wip_nav.abbrevCode(if (is_generic_decl) abbrev_code.generic_decl else abbrev_code.decl);
|
||||
try wip_nav.refType((if (is_generic_decl) null else parent_type) orelse
|
||||
.fromInterned(zcu.fileRootType(file)));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, decl.src_line + 1, dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
|
||||
if (!is_generic_decl) return;
|
||||
const generic_decl_entry = wip_nav.entry;
|
||||
try dwarf.debug_info.section.replaceEntry(wip_nav.unit, generic_decl_entry, dwarf, wip_nav.debug_info.items);
|
||||
wip_nav.debug_info.clearRetainingCapacity();
|
||||
wip_nav.entry = orig_entry;
|
||||
try wip_nav.abbrevCode(abbrev_code.instance);
|
||||
try wip_nav.refType(parent_type.?);
|
||||
try wip_nav.infoSectionOffset(.debug_info, wip_nav.unit, generic_decl_entry, 0);
|
||||
}
|
||||
|
||||
fn updateLazy(wip_nav: *WipNav, src_loc: Zcu.LazySrcLoc) UpdateError!void {
|
||||
const ip = &wip_nav.pt.zcu.intern_pool;
|
||||
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 {
|
||||
},
|
||||
.endian = target.cpu.arch.endian(),
|
||||
|
||||
.mods = .{},
|
||||
.types = .{},
|
||||
.values = .{},
|
||||
.navs = .{},
|
||||
.mods = .empty,
|
||||
.types = .empty,
|
||||
.values = .empty,
|
||||
.navs = .empty,
|
||||
.decls = .empty,
|
||||
|
||||
.debug_abbrev = .{ .section = Section.init },
|
||||
.debug_aranges = .{ .section = Section.init },
|
||||
@@ -2142,6 +2268,7 @@ pub fn deinit(dwarf: *Dwarf) void {
|
||||
dwarf.types.deinit(gpa);
|
||||
dwarf.values.deinit(gpa);
|
||||
dwarf.navs.deinit(gpa);
|
||||
dwarf.decls.deinit(gpa);
|
||||
dwarf.debug_abbrev.section.deinit(gpa);
|
||||
dwarf.debug_aranges.section.deinit(gpa);
|
||||
dwarf.debug_frame.section.deinit(gpa);
|
||||
@@ -2161,8 +2288,8 @@ fn getUnit(dwarf: *Dwarf, mod: *Module) UpdateError!Unit.Index {
|
||||
errdefer _ = dwarf.mods.pop();
|
||||
mod_gop.value_ptr.* = .{
|
||||
.root_dir_path = undefined,
|
||||
.dirs = .{},
|
||||
.files = .{},
|
||||
.dirs = .empty,
|
||||
.files = .empty,
|
||||
};
|
||||
errdefer mod_gop.value_ptr.dirs.deinit(dwarf.gpa);
|
||||
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
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const nav = ip.getNav(nav_index);
|
||||
log.debug("initWipNav({})", .{nav.fqn.fmt(ip)});
|
||||
|
||||
const inst_info = nav.srcInst(ip).resolveFull(ip).?;
|
||||
const file = zcu.fileByIndex(inst_info.file);
|
||||
assert(file.zir_loaded);
|
||||
const decl = file.zir.getDeclaration(inst_info.inst);
|
||||
log.debug("initWipNav({s}:{d}:{d} %{d} = {})", .{
|
||||
file.sub_file_path,
|
||||
decl.src_line + 1,
|
||||
decl.src_column + 1,
|
||||
@intFromEnum(inst_info.inst),
|
||||
nav.fqn.fmt(ip),
|
||||
});
|
||||
|
||||
const nav_val = zcu.navValue(nav_index);
|
||||
const nav_key = ip.indexToKey(nav_val.toIntern());
|
||||
switch (nav_key) {
|
||||
.@"extern" => return null,
|
||||
else => {},
|
||||
}
|
||||
|
||||
const unit = try dwarf.getUnit(file.mod);
|
||||
const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
|
||||
errdefer _ = dwarf.navs.pop();
|
||||
errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop();
|
||||
if (nav_gop.found_existing) {
|
||||
for ([_]*Section{
|
||||
&dwarf.debug_aranges.section,
|
||||
@@ -2236,7 +2377,6 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
|
||||
&dwarf.debug_rnglists.section,
|
||||
}) |sec| sec.getUnit(unit).getEntry(nav_gop.value_ptr.*).clear();
|
||||
} else nav_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
|
||||
const nav_val = zcu.navValue(nav_index);
|
||||
var wip_nav: WipNav = .{
|
||||
.dwarf = dwarf,
|
||||
.pt = pt,
|
||||
@@ -2248,91 +2388,52 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
|
||||
.func_high_pc = undefined,
|
||||
.blocks = undefined,
|
||||
.cfi = undefined,
|
||||
.debug_frame = .{},
|
||||
.debug_info = .{},
|
||||
.debug_line = .{},
|
||||
.debug_loclists = .{},
|
||||
.pending_lazy = .{},
|
||||
.debug_frame = .empty,
|
||||
.debug_info = .empty,
|
||||
.debug_line = .empty,
|
||||
.debug_loclists = .empty,
|
||||
.pending_lazy = .empty,
|
||||
};
|
||||
errdefer wip_nav.deinit();
|
||||
|
||||
switch (ip.indexToKey(nav_val.toIntern())) {
|
||||
switch (nav_key) {
|
||||
else => {
|
||||
assert(file.zir_loaded);
|
||||
const decl = file.zir.getDeclaration(inst_info.inst);
|
||||
|
||||
const parent_type, const accessibility: u8 = if (nav.analysis) |a| parent: {
|
||||
const parent_namespace_ptr = ip.namespacePtr(a.namespace);
|
||||
break :parent .{
|
||||
parent_namespace_ptr.owner_type,
|
||||
if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private,
|
||||
};
|
||||
} else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
|
||||
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(.decl_var);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(.{
|
||||
.decl = .decl_var,
|
||||
.generic_decl = .generic_decl_var,
|
||||
.instance = .instance_var,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try wip_nav.strp(nav.fqn.toSlice(ip));
|
||||
const nav_ty = nav_val.typeOf(zcu);
|
||||
const nav_ty_reloc_index = try wip_nav.refForward();
|
||||
try wip_nav.infoExprloc(.{ .addr = .{ .sym = sym_index } });
|
||||
try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
|
||||
nav_ty.abiAlignment(zcu).toByteUnits().?);
|
||||
try diw.writeByte(@intFromBool(false));
|
||||
wip_nav.finishForward(nav_ty_reloc_index);
|
||||
try wip_nav.abbrevCode(.is_const);
|
||||
try wip_nav.refType(nav_ty);
|
||||
},
|
||||
.variable => |variable| {
|
||||
assert(file.zir_loaded);
|
||||
const decl = file.zir.getDeclaration(inst_info.inst);
|
||||
|
||||
const parent_type, const accessibility: u8 = if (nav.analysis) |a| parent: {
|
||||
const parent_namespace_ptr = ip.namespacePtr(a.namespace);
|
||||
break :parent .{
|
||||
parent_namespace_ptr.owner_type,
|
||||
if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private,
|
||||
};
|
||||
} else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
|
||||
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(.decl_var);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.strp(nav.fqn.toSlice(ip));
|
||||
const ty: Type = .fromInterned(variable.ty);
|
||||
try wip_nav.refType(ty);
|
||||
const ty: Type = nav_val.typeOf(zcu);
|
||||
const addr: Loc = .{ .addr = .{ .sym = sym_index } };
|
||||
try wip_nav.infoExprloc(if (variable.is_threadlocal) .{ .form_tls_address = &addr } else addr);
|
||||
try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
|
||||
ty.abiAlignment(zcu).toByteUnits().?);
|
||||
try diw.writeByte(@intFromBool(false));
|
||||
const loc: Loc = if (decl.is_threadlocal) .{ .form_tls_address = &addr } else addr;
|
||||
switch (decl.kind) {
|
||||
.unnamed_test, .@"test", .decltest, .@"comptime", .@"usingnamespace" => unreachable,
|
||||
.@"const" => {
|
||||
const const_ty_reloc_index = try wip_nav.refForward();
|
||||
try wip_nav.infoExprloc(loc);
|
||||
try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
|
||||
ty.abiAlignment(zcu).toByteUnits().?);
|
||||
try diw.writeByte(@intFromBool(decl.linkage != .normal));
|
||||
wip_nav.finishForward(const_ty_reloc_index);
|
||||
try wip_nav.abbrevCode(.is_const);
|
||||
try wip_nav.refType(ty);
|
||||
},
|
||||
.@"var" => {
|
||||
try wip_nav.refType(ty);
|
||||
try wip_nav.infoExprloc(loc);
|
||||
try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
|
||||
ty.abiAlignment(zcu).toByteUnits().?);
|
||||
try diw.writeByte(@intFromBool(decl.linkage != .normal));
|
||||
},
|
||||
}
|
||||
},
|
||||
.func => |func| {
|
||||
assert(file.zir_loaded);
|
||||
const decl = file.zir.getDeclaration(inst_info.inst);
|
||||
|
||||
const parent_type, const accessibility: u8 = if (nav.analysis) |a| parent: {
|
||||
const parent_namespace_ptr = ip.namespacePtr(a.namespace);
|
||||
break :parent .{
|
||||
parent_namespace_ptr.owner_type,
|
||||
if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private,
|
||||
};
|
||||
} else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
|
||||
|
||||
const func_type = ip.indexToKey(func.ty).func_type;
|
||||
wip_nav.func = nav_val.toIntern();
|
||||
wip_nav.func_sym_index = sym_index;
|
||||
wip_nav.blocks = .{};
|
||||
wip_nav.blocks = .empty;
|
||||
if (dwarf.debug_frame.header.format != .none) wip_nav.cfi = .{
|
||||
.loc = 0,
|
||||
.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
|
||||
}
|
||||
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(.decl_func);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(.{
|
||||
.decl = .decl_func,
|
||||
.generic_decl = .generic_decl_func,
|
||||
.instance = .instance_func,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try wip_nav.strp(nav.fqn.toSlice(ip));
|
||||
try wip_nav.refType(.fromInterned(func_type.return_type));
|
||||
try wip_nav.infoAddrSym(sym_index, 0);
|
||||
@@ -2392,7 +2491,7 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
|
||||
.none => target_info.defaultFunctionAlignment(target),
|
||||
else => |a| a.maxStrict(target_info.minFunctionAlignment(target)),
|
||||
}.toByteUnits().?);
|
||||
try diw.writeByte(@intFromBool(false));
|
||||
try diw.writeByte(@intFromBool(decl.linkage != .normal));
|
||||
try diw.writeByte(@intFromBool(func_type.return_type == .noreturn_type));
|
||||
|
||||
const dlw = wip_nav.debug_line.writer(dwarf.gpa);
|
||||
@@ -2435,11 +2534,104 @@ pub fn initWipNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.In
|
||||
return wip_nav;
|
||||
}
|
||||
|
||||
pub fn finishWipNavFunc(
|
||||
dwarf: *Dwarf,
|
||||
pt: Zcu.PerThread,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
code_size: u64,
|
||||
wip_nav: *WipNav,
|
||||
) UpdateError!void {
|
||||
const zcu = pt.zcu;
|
||||
const ip = &zcu.intern_pool;
|
||||
const nav = ip.getNav(nav_index);
|
||||
assert(wip_nav.func != .none);
|
||||
log.debug("finishWipNavFunc({})", .{nav.fqn.fmt(ip)});
|
||||
|
||||
{
|
||||
const external_relocs = &dwarf.debug_aranges.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
|
||||
try external_relocs.append(dwarf.gpa, .{ .target_sym = wip_nav.func_sym_index });
|
||||
var entry: [8 + 8]u8 = undefined;
|
||||
@memset(entry[0..@intFromEnum(dwarf.address_size)], 0);
|
||||
dwarf.writeInt(entry[@intFromEnum(dwarf.address_size)..][0..@intFromEnum(dwarf.address_size)], code_size);
|
||||
try dwarf.debug_aranges.section.replaceEntry(
|
||||
wip_nav.unit,
|
||||
wip_nav.entry,
|
||||
dwarf,
|
||||
entry[0 .. @intFromEnum(dwarf.address_size) * 2],
|
||||
);
|
||||
}
|
||||
switch (dwarf.debug_frame.header.format) {
|
||||
.none => {},
|
||||
.debug_frame, .eh_frame => |format| {
|
||||
try wip_nav.debug_frame.appendNTimes(
|
||||
dwarf.gpa,
|
||||
DW.CFA.nop,
|
||||
@intCast(dwarf.debug_frame.section.alignment.forward(wip_nav.debug_frame.items.len) - wip_nav.debug_frame.items.len),
|
||||
);
|
||||
const contents = wip_nav.debug_frame.items;
|
||||
try dwarf.debug_frame.section.resizeEntry(wip_nav.unit, wip_nav.entry, dwarf, @intCast(contents.len));
|
||||
const unit = dwarf.debug_frame.section.getUnit(wip_nav.unit);
|
||||
const entry = unit.getEntry(wip_nav.entry);
|
||||
const unit_len = (if (entry.next.unwrap()) |next_entry|
|
||||
unit.getEntry(next_entry).off - entry.off
|
||||
else
|
||||
entry.len) - dwarf.unitLengthBytes();
|
||||
dwarf.writeInt(contents[dwarf.unitLengthBytes() - dwarf.sectionOffsetBytes() ..][0..dwarf.sectionOffsetBytes()], unit_len);
|
||||
switch (format) {
|
||||
.none => unreachable,
|
||||
.debug_frame => dwarf.writeInt(contents[dwarf.unitLengthBytes() + dwarf.sectionOffsetBytes() +
|
||||
@intFromEnum(dwarf.address_size) ..][0..@intFromEnum(dwarf.address_size)], code_size),
|
||||
.eh_frame => {
|
||||
std.mem.writeInt(
|
||||
u32,
|
||||
contents[dwarf.unitLengthBytes()..][0..4],
|
||||
unit.header_len + entry.off + dwarf.unitLengthBytes(),
|
||||
dwarf.endian,
|
||||
);
|
||||
std.mem.writeInt(u32, contents[dwarf.unitLengthBytes() + 4 + 4 ..][0..4], @intCast(code_size), dwarf.endian);
|
||||
},
|
||||
}
|
||||
try entry.replace(unit, &dwarf.debug_frame.section, dwarf, contents);
|
||||
},
|
||||
}
|
||||
{
|
||||
std.mem.writeInt(u32, wip_nav.debug_info.items[wip_nav.func_high_pc..][0..4], @intCast(code_size), dwarf.endian);
|
||||
if (wip_nav.any_children) {
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try uleb128(diw, @intFromEnum(AbbrevCode.null));
|
||||
} else std.leb.writeUnsignedFixed(
|
||||
AbbrevCode.decl_bytes,
|
||||
wip_nav.debug_info.items[0..AbbrevCode.decl_bytes],
|
||||
try dwarf.refAbbrevCode(.decl_empty_func),
|
||||
);
|
||||
}
|
||||
{
|
||||
try dwarf.debug_rnglists.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.appendSlice(dwarf.gpa, &.{
|
||||
.{
|
||||
.source_off = 1,
|
||||
.target_sym = wip_nav.func_sym_index,
|
||||
},
|
||||
.{
|
||||
.source_off = 1 + @intFromEnum(dwarf.address_size),
|
||||
.target_sym = wip_nav.func_sym_index,
|
||||
.target_off = code_size,
|
||||
},
|
||||
});
|
||||
try dwarf.debug_rnglists.section.replaceEntry(
|
||||
wip_nav.unit,
|
||||
wip_nav.entry,
|
||||
dwarf,
|
||||
([1]u8{DW.RLE.start_end} ++ [1]u8{0} ** (8 + 8))[0 .. 1 + @intFromEnum(dwarf.address_size) + @intFromEnum(dwarf.address_size)],
|
||||
);
|
||||
}
|
||||
|
||||
try dwarf.finishWipNav(pt, nav_index, wip_nav);
|
||||
}
|
||||
|
||||
pub fn finishWipNav(
|
||||
dwarf: *Dwarf,
|
||||
pt: Zcu.PerThread,
|
||||
nav_index: InternPool.Nav.Index,
|
||||
sym: struct { index: u32, addr: u64, size: u64 },
|
||||
wip_nav: *WipNav,
|
||||
) UpdateError!void {
|
||||
const zcu = pt.zcu;
|
||||
@@ -2447,86 +2639,6 @@ pub fn finishWipNav(
|
||||
const nav = ip.getNav(nav_index);
|
||||
log.debug("finishWipNav({})", .{nav.fqn.fmt(ip)});
|
||||
|
||||
if (wip_nav.func != .none) {
|
||||
{
|
||||
const external_relocs = &dwarf.debug_aranges.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs;
|
||||
try external_relocs.append(dwarf.gpa, .{ .target_sym = sym.index });
|
||||
var entry: [8 + 8]u8 = undefined;
|
||||
@memset(entry[0..@intFromEnum(dwarf.address_size)], 0);
|
||||
dwarf.writeInt(entry[@intFromEnum(dwarf.address_size)..][0..@intFromEnum(dwarf.address_size)], sym.size);
|
||||
try dwarf.debug_aranges.section.replaceEntry(
|
||||
wip_nav.unit,
|
||||
wip_nav.entry,
|
||||
dwarf,
|
||||
entry[0 .. @intFromEnum(dwarf.address_size) * 2],
|
||||
);
|
||||
}
|
||||
switch (dwarf.debug_frame.header.format) {
|
||||
.none => {},
|
||||
.debug_frame, .eh_frame => |format| {
|
||||
try wip_nav.debug_frame.appendNTimes(
|
||||
dwarf.gpa,
|
||||
DW.CFA.nop,
|
||||
@intCast(dwarf.debug_frame.section.alignment.forward(wip_nav.debug_frame.items.len) - wip_nav.debug_frame.items.len),
|
||||
);
|
||||
const contents = wip_nav.debug_frame.items;
|
||||
try dwarf.debug_frame.section.resizeEntry(wip_nav.unit, wip_nav.entry, dwarf, @intCast(contents.len));
|
||||
const unit = dwarf.debug_frame.section.getUnit(wip_nav.unit);
|
||||
const entry = unit.getEntry(wip_nav.entry);
|
||||
const unit_len = (if (entry.next.unwrap()) |next_entry|
|
||||
unit.getEntry(next_entry).off - entry.off
|
||||
else
|
||||
entry.len) - dwarf.unitLengthBytes();
|
||||
dwarf.writeInt(contents[dwarf.unitLengthBytes() - dwarf.sectionOffsetBytes() ..][0..dwarf.sectionOffsetBytes()], unit_len);
|
||||
switch (format) {
|
||||
.none => unreachable,
|
||||
.debug_frame => dwarf.writeInt(contents[dwarf.unitLengthBytes() + dwarf.sectionOffsetBytes() +
|
||||
@intFromEnum(dwarf.address_size) ..][0..@intFromEnum(dwarf.address_size)], sym.size),
|
||||
.eh_frame => {
|
||||
std.mem.writeInt(
|
||||
u32,
|
||||
contents[dwarf.unitLengthBytes()..][0..4],
|
||||
unit.header_len + entry.off + dwarf.unitLengthBytes(),
|
||||
dwarf.endian,
|
||||
);
|
||||
std.mem.writeInt(u32, contents[dwarf.unitLengthBytes() + 4 + 4 ..][0..4], @intCast(sym.size), dwarf.endian);
|
||||
},
|
||||
}
|
||||
try entry.replace(unit, &dwarf.debug_frame.section, dwarf, contents);
|
||||
},
|
||||
}
|
||||
{
|
||||
std.mem.writeInt(u32, wip_nav.debug_info.items[wip_nav.func_high_pc..][0..4], @intCast(sym.size), dwarf.endian);
|
||||
if (wip_nav.any_children) {
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try uleb128(diw, @intFromEnum(AbbrevCode.null));
|
||||
} else std.leb.writeUnsignedFixed(
|
||||
AbbrevCode.decl_bytes,
|
||||
wip_nav.debug_info.items[0..AbbrevCode.decl_bytes],
|
||||
try dwarf.refAbbrevCode(.decl_empty_func),
|
||||
);
|
||||
}
|
||||
{
|
||||
try dwarf.debug_rnglists.section.getUnit(wip_nav.unit).getEntry(wip_nav.entry).external_relocs.appendSlice(dwarf.gpa, &.{
|
||||
.{
|
||||
.source_off = 1,
|
||||
.target_sym = sym.index,
|
||||
},
|
||||
.{
|
||||
.source_off = 1 + @intFromEnum(dwarf.address_size),
|
||||
.target_sym = sym.index,
|
||||
.target_off = sym.size,
|
||||
},
|
||||
});
|
||||
try dwarf.debug_rnglists.section.replaceEntry(
|
||||
wip_nav.unit,
|
||||
wip_nav.entry,
|
||||
dwarf,
|
||||
([1]u8{DW.RLE.start_end} ++ [1]u8{0} ** (8 + 8))[0 .. 1 + @intFromEnum(dwarf.address_size) + @intFromEnum(dwarf.address_size)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.items);
|
||||
if (wip_nav.debug_line.items.len > 0) {
|
||||
const dlw = wip_nav.debug_line.writer(dwarf.gpa);
|
||||
@@ -2547,12 +2659,17 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
const nav_val = zcu.navValue(nav_index);
|
||||
|
||||
const nav = ip.getNav(nav_index);
|
||||
log.debug("updateComptimeNav({})", .{nav.fqn.fmt(ip)});
|
||||
|
||||
const inst_info = nav.srcInst(ip).resolveFull(ip).?;
|
||||
const file = zcu.fileByIndex(inst_info.file);
|
||||
assert(file.zir_loaded);
|
||||
const decl = file.zir.getDeclaration(inst_info.inst);
|
||||
log.debug("updateComptimeNav({s}:{d}:{d} %{d} = {})", .{
|
||||
file.sub_file_path,
|
||||
decl.src_line + 1,
|
||||
decl.src_column + 1,
|
||||
@intFromEnum(inst_info.inst),
|
||||
nav.fqn.fmt(ip),
|
||||
});
|
||||
|
||||
const is_test = switch (decl.kind) {
|
||||
.unnamed_test, .@"test", .decltest => true,
|
||||
@@ -2563,14 +2680,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
return;
|
||||
}
|
||||
|
||||
const parent_type, const accessibility: u8 = if (nav.analysis) |a| parent: {
|
||||
const parent_namespace_ptr = ip.namespacePtr(a.namespace);
|
||||
break :parent .{
|
||||
parent_namespace_ptr.owner_type,
|
||||
if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private,
|
||||
};
|
||||
} else .{ zcu.fileRootType(inst_info.file), DW.ACCESS.private };
|
||||
|
||||
var wip_nav: WipNav = .{
|
||||
.dwarf = dwarf,
|
||||
.pt = pt,
|
||||
@@ -2582,16 +2691,16 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
.func_high_pc = undefined,
|
||||
.blocks = undefined,
|
||||
.cfi = undefined,
|
||||
.debug_frame = .{},
|
||||
.debug_info = .{},
|
||||
.debug_line = .{},
|
||||
.debug_loclists = .{},
|
||||
.pending_lazy = .{},
|
||||
.debug_frame = .empty,
|
||||
.debug_info = .empty,
|
||||
.debug_line = .empty,
|
||||
.debug_loclists = .empty,
|
||||
.pending_lazy = .empty,
|
||||
};
|
||||
defer wip_nav.deinit();
|
||||
|
||||
const nav_gop = try dwarf.navs.getOrPut(dwarf.gpa, nav_index);
|
||||
errdefer _ = dwarf.navs.pop();
|
||||
errdefer _ = if (!nav_gop.found_existing) dwarf.navs.pop();
|
||||
|
||||
const tag: enum { done, decl_alias, decl_var, decl_const } = switch (ip.indexToKey(nav_val.toIntern())) {
|
||||
.int_type,
|
||||
@@ -2609,9 +2718,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
=> .decl_alias,
|
||||
.struct_type => tag: {
|
||||
const loaded_struct = ip.loadStructType(nav_val.toIntern());
|
||||
|
||||
const type_inst_info = loaded_struct.zir_index.resolveFull(ip).?;
|
||||
if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
|
||||
if (loaded_struct.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
|
||||
|
||||
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
|
||||
if (type_gop.found_existing) {
|
||||
@@ -2630,13 +2737,15 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
|
||||
switch (loaded_struct.layout) {
|
||||
.auto, .@"extern" => {
|
||||
try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .decl_namespace_struct else .decl_struct);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(if (loaded_struct.field_types.len == 0) .{
|
||||
.decl = .decl_namespace_struct,
|
||||
.generic_decl = .generic_decl_struct,
|
||||
.instance = .instance_namespace_struct,
|
||||
} else .{
|
||||
.decl = .decl_struct,
|
||||
.generic_decl = .generic_decl_struct,
|
||||
.instance = .instance_struct,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
|
||||
try uleb128(diw, nav_val.toType().abiSize(zcu));
|
||||
try uleb128(diw, nav_val.toType().abiAlignment(zcu).toByteUnits().?);
|
||||
@@ -2688,13 +2797,11 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
}
|
||||
},
|
||||
.@"packed" => {
|
||||
try wip_nav.abbrevCode(.decl_packed_struct);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(.{
|
||||
.decl = .decl_packed_struct,
|
||||
.generic_decl = .generic_decl_struct,
|
||||
.instance = .instance_packed_struct,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
|
||||
var field_bit_offset: u16 = 0;
|
||||
for (0..loaded_struct.field_types.len) |field_index| {
|
||||
@@ -2712,10 +2819,8 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
},
|
||||
.enum_type => tag: {
|
||||
const loaded_enum = ip.loadEnumType(nav_val.toIntern());
|
||||
if (loaded_enum.zir_index == .none) break :tag .decl_alias;
|
||||
|
||||
const type_inst_info = loaded_enum.zir_index.unwrap().?.resolveFull(ip).?;
|
||||
if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
|
||||
const type_zir_index = loaded_enum.zir_index.unwrap() orelse break :tag .decl_alias;
|
||||
if (type_zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
|
||||
|
||||
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
|
||||
if (type_gop.found_existing) {
|
||||
@@ -2730,13 +2835,15 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
}
|
||||
wip_nav.entry = nav_gop.value_ptr.*;
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .decl_enum else .decl_empty_enum);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(if (loaded_enum.names.len > 0) .{
|
||||
.decl = .decl_enum,
|
||||
.generic_decl = .generic_decl_enum,
|
||||
.instance = .instance_enum,
|
||||
} else .{
|
||||
.decl = .decl_empty_enum,
|
||||
.generic_decl = .generic_decl_enum,
|
||||
.instance = .instance_empty_enum,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
|
||||
for (0..loaded_enum.names.len) |field_index| {
|
||||
try wip_nav.enumConstValue(loaded_enum, .{
|
||||
@@ -2751,9 +2858,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
},
|
||||
.union_type => tag: {
|
||||
const loaded_union = ip.loadUnionType(nav_val.toIntern());
|
||||
|
||||
const type_inst_info = loaded_union.zir_index.resolveFull(ip).?;
|
||||
if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
|
||||
if (loaded_union.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
|
||||
|
||||
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
|
||||
if (type_gop.found_existing) {
|
||||
@@ -2768,13 +2873,11 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
}
|
||||
wip_nav.entry = nav_gop.value_ptr.*;
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(.decl_union);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(.{
|
||||
.decl = .decl_union,
|
||||
.generic_decl = .generic_decl_union,
|
||||
.instance = .instance_union,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
const union_layout = Type.getUnionLayout(loaded_union, zcu);
|
||||
try uleb128(diw, union_layout.abi_size);
|
||||
try uleb128(diw, union_layout.abi_align.toByteUnits().?);
|
||||
@@ -2825,9 +2928,7 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
},
|
||||
.opaque_type => tag: {
|
||||
const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
|
||||
|
||||
const type_inst_info = loaded_opaque.zir_index.resolveFull(ip).?;
|
||||
if (type_inst_info.file != inst_info.file) break :tag .decl_alias;
|
||||
if (loaded_opaque.zir_index.resolveFile(ip) != inst_info.file) break :tag .decl_alias;
|
||||
|
||||
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, nav_val.toIntern());
|
||||
if (type_gop.found_existing) {
|
||||
@@ -2842,19 +2943,16 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
}
|
||||
wip_nav.entry = nav_gop.value_ptr.*;
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(.decl_namespace_struct);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try diw.writeByte(@intFromBool(false));
|
||||
try wip_nav.declCommon(.{
|
||||
.decl = .decl_namespace_struct,
|
||||
.generic_decl = .generic_decl_struct,
|
||||
.instance = .instance_namespace_struct,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try diw.writeByte(@intFromBool(true));
|
||||
break :tag .done;
|
||||
},
|
||||
.undef,
|
||||
.simple_value,
|
||||
.@"extern",
|
||||
.int,
|
||||
.err,
|
||||
.error_union,
|
||||
@@ -2869,42 +2967,31 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
.un,
|
||||
=> .decl_const,
|
||||
.variable => .decl_var,
|
||||
.@"extern" => unreachable,
|
||||
.func => |func| tag: {
|
||||
if (nav_gop.found_existing) {
|
||||
const unit_ptr = dwarf.debug_info.section.getUnit(wip_nav.unit);
|
||||
const entry_ptr = unit_ptr.getEntry(nav_gop.value_ptr.*);
|
||||
if (entry_ptr.len >= AbbrevCode.decl_bytes) {
|
||||
var abbrev_code_buf: [AbbrevCode.decl_bytes]u8 = undefined;
|
||||
if (try dwarf.getFile().?.preadAll(
|
||||
&abbrev_code_buf,
|
||||
dwarf.debug_info.section.off(dwarf) + unit_ptr.off + unit_ptr.header_len + entry_ptr.off,
|
||||
) != abbrev_code_buf.len) return error.InputOutput;
|
||||
var abbrev_code_fbs = std.io.fixedBufferStream(&abbrev_code_buf);
|
||||
const abbrev_code: AbbrevCode = @enumFromInt(
|
||||
std.leb.readUleb128(@typeInfo(AbbrevCode).@"enum".tag_type, abbrev_code_fbs.reader()) catch unreachable,
|
||||
);
|
||||
switch (abbrev_code) {
|
||||
else => unreachable,
|
||||
.decl_func, .decl_empty_func => return,
|
||||
.decl_func_generic, .decl_empty_func_generic => {},
|
||||
}
|
||||
}
|
||||
entry_ptr.clear();
|
||||
if (nav_gop.found_existing) switch (try dwarf.debug_info.declAbbrevCode(wip_nav.unit, nav_gop.value_ptr.*)) {
|
||||
.null => {},
|
||||
else => unreachable,
|
||||
.decl_func, .decl_empty_func, .instance_func, .instance_empty_func => return,
|
||||
.decl_func_generic,
|
||||
.decl_empty_func_generic,
|
||||
.instance_func_generic,
|
||||
.instance_empty_func_generic,
|
||||
=> dwarf.debug_info.section.getUnit(wip_nav.unit).getEntry(nav_gop.value_ptr.*).clear(),
|
||||
} else nav_gop.value_ptr.* = try dwarf.addCommonEntry(wip_nav.unit);
|
||||
wip_nav.entry = nav_gop.value_ptr.*;
|
||||
|
||||
const func_type = ip.indexToKey(func.ty).func_type;
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(if (func_type.param_types.len > 0 or func_type.is_var_args)
|
||||
.decl_func_generic
|
||||
else
|
||||
.decl_empty_func_generic);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(if (func_type.param_types.len > 0 or func_type.is_var_args) .{
|
||||
.decl = .decl_func_generic,
|
||||
.generic_decl = .generic_decl_func,
|
||||
.instance = .instance_func_generic,
|
||||
} else .{
|
||||
.decl = .decl_empty_func_generic,
|
||||
.generic_decl = .generic_decl_func,
|
||||
.instance = .instance_empty_func_generic,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try wip_nav.refType(.fromInterned(func_type.return_type));
|
||||
if (func_type.param_types.len > 0 or func_type.is_var_args) {
|
||||
for (0..func_type.param_types.len) |param_index| {
|
||||
@@ -2929,57 +3016,55 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
|
||||
switch (tag) {
|
||||
.done => {},
|
||||
.decl_alias => {
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(.decl_alias);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(.{
|
||||
.decl = .decl_alias,
|
||||
.generic_decl = .generic_decl_alias,
|
||||
.instance = .instance_alias,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try wip_nav.refType(nav_val.toType());
|
||||
},
|
||||
.decl_var => {
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(.decl_var);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(.{
|
||||
.decl = .decl_var,
|
||||
.generic_decl = .generic_decl_var,
|
||||
.instance = .instance_var,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try wip_nav.strp(nav.fqn.toSlice(ip));
|
||||
const nav_ty = nav_val.typeOf(zcu);
|
||||
try wip_nav.refType(nav_ty);
|
||||
try wip_nav.blockValue(nav_src_loc, nav_val);
|
||||
try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
|
||||
nav_ty.abiAlignment(zcu).toByteUnits().?);
|
||||
try diw.writeByte(@intFromBool(false));
|
||||
try diw.writeByte(@intFromBool(decl.linkage != .normal));
|
||||
},
|
||||
.decl_const => {
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
const nav_ty = nav_val.typeOf(zcu);
|
||||
const has_runtime_bits = nav_ty.hasRuntimeBits(zcu);
|
||||
const has_comptime_state = nav_ty.comptimeOnly(zcu) and try nav_ty.onePossibleValue(pt) == null;
|
||||
try wip_nav.abbrevCode(if (has_runtime_bits and has_comptime_state)
|
||||
.decl_const_runtime_bits_comptime_state
|
||||
else if (has_comptime_state)
|
||||
.decl_const_comptime_state
|
||||
else if (has_runtime_bits)
|
||||
.decl_const_runtime_bits
|
||||
else
|
||||
.decl_const);
|
||||
try wip_nav.refType(.fromInterned(parent_type));
|
||||
assert(wip_nav.debug_info.items.len == DebugInfo.declEntryLineOff(dwarf));
|
||||
try diw.writeInt(u32, @intCast(decl.src_line + 1), dwarf.endian);
|
||||
try uleb128(diw, decl.src_column + 1);
|
||||
try diw.writeByte(accessibility);
|
||||
try wip_nav.strp(nav.name.toSlice(ip));
|
||||
try wip_nav.declCommon(if (has_runtime_bits and has_comptime_state) .{
|
||||
.decl = .decl_const_runtime_bits_comptime_state,
|
||||
.generic_decl = .generic_decl_const,
|
||||
.instance = .instance_const_runtime_bits_comptime_state,
|
||||
} else if (has_comptime_state) .{
|
||||
.decl = .decl_const_comptime_state,
|
||||
.generic_decl = .generic_decl_const,
|
||||
.instance = .instance_const_comptime_state,
|
||||
} else if (has_runtime_bits) .{
|
||||
.decl = .decl_const_runtime_bits,
|
||||
.generic_decl = .generic_decl_const,
|
||||
.instance = .instance_const_runtime_bits,
|
||||
} else .{
|
||||
.decl = .decl_const,
|
||||
.generic_decl = .generic_decl_const,
|
||||
.instance = .instance_const,
|
||||
}, &nav, inst_info.file, &decl);
|
||||
try wip_nav.strp(nav.fqn.toSlice(ip));
|
||||
const nav_ty_reloc_index = try wip_nav.refForward();
|
||||
try uleb128(diw, nav.status.fully_resolved.alignment.toByteUnits() orelse
|
||||
nav_ty.abiAlignment(zcu).toByteUnits().?);
|
||||
try diw.writeByte(@intFromBool(false));
|
||||
try diw.writeByte(@intFromBool(decl.linkage != .normal));
|
||||
if (has_runtime_bits) try wip_nav.blockValue(nav_src_loc, nav_val);
|
||||
if (has_comptime_state) try wip_nav.refValue(nav_val);
|
||||
wip_nav.finishForward(nav_ty_reloc_index);
|
||||
@@ -3017,15 +3102,15 @@ fn updateLazyType(
|
||||
.func_high_pc = undefined,
|
||||
.blocks = undefined,
|
||||
.cfi = undefined,
|
||||
.debug_frame = .{},
|
||||
.debug_info = .{},
|
||||
.debug_line = .{},
|
||||
.debug_loclists = .{},
|
||||
.debug_frame = .empty,
|
||||
.debug_info = .empty,
|
||||
.debug_line = .empty,
|
||||
.debug_loclists = .empty,
|
||||
.pending_lazy = pending_lazy.*,
|
||||
};
|
||||
defer {
|
||||
pending_lazy.* = wip_nav.pending_lazy;
|
||||
wip_nav.pending_lazy = .{};
|
||||
wip_nav.pending_lazy = .empty;
|
||||
wip_nav.deinit();
|
||||
}
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
@@ -3076,7 +3161,7 @@ fn updateLazyType(
|
||||
}
|
||||
},
|
||||
.Slice => {
|
||||
try wip_nav.abbrevCode(.struct_type);
|
||||
try wip_nav.abbrevCode(.generated_struct_type);
|
||||
try wip_nav.strp(name);
|
||||
try uleb128(diw, ty.abiSize(zcu));
|
||||
try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
|
||||
@@ -3115,7 +3200,7 @@ fn updateLazyType(
|
||||
},
|
||||
.opt_type => |opt_child_type_index| {
|
||||
const opt_child_type: Type = .fromInterned(opt_child_type_index);
|
||||
try wip_nav.abbrevCode(.union_type);
|
||||
try wip_nav.abbrevCode(.generated_union_type);
|
||||
try wip_nav.strp(name);
|
||||
try uleb128(diw, ty.abiSize(zcu));
|
||||
try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
|
||||
@@ -3199,7 +3284,7 @@ fn updateLazyType(
|
||||
},
|
||||
};
|
||||
|
||||
try wip_nav.abbrevCode(.union_type);
|
||||
try wip_nav.abbrevCode(.generated_union_type);
|
||||
try wip_nav.strp(name);
|
||||
if (error_union_type.error_set_type != .generic_poison_type and
|
||||
error_union_type.payload_type != .generic_poison_type)
|
||||
@@ -3308,11 +3393,11 @@ fn updateLazyType(
|
||||
.opaque_type,
|
||||
=> unreachable,
|
||||
.tuple_type => |tuple_type| if (tuple_type.types.len == 0) {
|
||||
try wip_nav.abbrevCode(.namespace_struct_type);
|
||||
try wip_nav.abbrevCode(.generated_empty_struct_type);
|
||||
try wip_nav.strp(name);
|
||||
try diw.writeByte(@intFromBool(false));
|
||||
} else {
|
||||
try wip_nav.abbrevCode(.struct_type);
|
||||
try wip_nav.abbrevCode(.generated_struct_type);
|
||||
try wip_nav.strp(name);
|
||||
try uleb128(diw, ty.abiSize(zcu));
|
||||
try uleb128(diw, ty.abiAlignment(zcu).toByteUnits().?);
|
||||
@@ -3357,7 +3442,7 @@ fn updateLazyType(
|
||||
},
|
||||
.enum_type => {
|
||||
const loaded_enum = ip.loadEnumType(type_index);
|
||||
try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .enum_type else .empty_enum_type);
|
||||
try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .generated_enum_type else .generated_empty_enum_type);
|
||||
try wip_nav.strp(name);
|
||||
try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
|
||||
for (0..loaded_enum.names.len) |field_index| {
|
||||
@@ -3449,7 +3534,7 @@ fn updateLazyType(
|
||||
if (!is_nullary) try uleb128(diw, @intFromEnum(AbbrevCode.null));
|
||||
},
|
||||
.error_set_type => |error_set_type| {
|
||||
try wip_nav.abbrevCode(if (error_set_type.names.len > 0) .enum_type else .empty_enum_type);
|
||||
try wip_nav.abbrevCode(if (error_set_type.names.len > 0) .generated_enum_type else .generated_empty_enum_type);
|
||||
try wip_nav.strp(name);
|
||||
try wip_nav.refType(.fromInterned(try pt.intern(.{ .int_type = .{
|
||||
.signedness = .unsigned,
|
||||
@@ -3518,15 +3603,15 @@ fn updateLazyValue(
|
||||
.func_high_pc = undefined,
|
||||
.blocks = undefined,
|
||||
.cfi = undefined,
|
||||
.debug_frame = .{},
|
||||
.debug_info = .{},
|
||||
.debug_line = .{},
|
||||
.debug_loclists = .{},
|
||||
.debug_frame = .empty,
|
||||
.debug_info = .empty,
|
||||
.debug_line = .empty,
|
||||
.debug_loclists = .empty,
|
||||
.pending_lazy = pending_lazy.*,
|
||||
};
|
||||
defer {
|
||||
pending_lazy.* = wip_nav.pending_lazy;
|
||||
wip_nav.pending_lazy = .{};
|
||||
wip_nav.pending_lazy = .empty;
|
||||
wip_nav.deinit();
|
||||
}
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
@@ -3870,12 +3955,13 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
const ip = &zcu.intern_pool;
|
||||
const ty: Type = .fromInterned(type_index);
|
||||
const ty_src_loc = ty.srcLoc(zcu);
|
||||
log.debug("updateContainerType({}({d}))", .{ ty.fmt(pt), @intFromEnum(type_index) });
|
||||
log.debug("updateContainerType({})", .{ty.fmt(pt)});
|
||||
|
||||
const inst_info = ty.typeDeclInst(zcu).?.resolveFull(ip).?;
|
||||
const file = zcu.fileByIndex(inst_info.file);
|
||||
const unit = try dwarf.getUnit(file.mod);
|
||||
const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
|
||||
if (inst_info.inst == .main_struct_inst) {
|
||||
const unit = try dwarf.getUnit(file.mod);
|
||||
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
|
||||
if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
|
||||
var wip_nav: WipNav = .{
|
||||
@@ -3889,19 +3975,18 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
.func_high_pc = undefined,
|
||||
.blocks = undefined,
|
||||
.cfi = undefined,
|
||||
.debug_frame = .{},
|
||||
.debug_info = .{},
|
||||
.debug_line = .{},
|
||||
.debug_loclists = .{},
|
||||
.pending_lazy = .{},
|
||||
.debug_frame = .empty,
|
||||
.debug_info = .empty,
|
||||
.debug_line = .empty,
|
||||
.debug_loclists = .empty,
|
||||
.pending_lazy = .empty,
|
||||
};
|
||||
defer wip_nav.deinit();
|
||||
|
||||
const loaded_struct = ip.loadStructType(type_index);
|
||||
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_file else .file);
|
||||
const file_gop = try dwarf.getModInfo(unit).files.getOrPut(dwarf.gpa, inst_info.file);
|
||||
try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .empty_file else .file);
|
||||
try uleb128(diw, file_gop.index);
|
||||
try wip_nav.strp(loaded_struct.name.toSlice(ip));
|
||||
if (loaded_struct.field_types.len > 0) {
|
||||
@@ -3978,7 +4063,6 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
if (name_strat == .parent) return;
|
||||
}
|
||||
|
||||
const unit = try dwarf.getUnit(file.mod);
|
||||
const type_gop = try dwarf.types.getOrPut(dwarf.gpa, type_index);
|
||||
if (!type_gop.found_existing) type_gop.value_ptr.* = try dwarf.addCommonEntry(unit);
|
||||
var wip_nav: WipNav = .{
|
||||
@@ -3992,11 +4076,11 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
.func_high_pc = undefined,
|
||||
.blocks = undefined,
|
||||
.cfi = undefined,
|
||||
.debug_frame = .{},
|
||||
.debug_info = .{},
|
||||
.debug_line = .{},
|
||||
.debug_loclists = .{},
|
||||
.pending_lazy = .{},
|
||||
.debug_frame = .empty,
|
||||
.debug_info = .empty,
|
||||
.debug_line = .empty,
|
||||
.debug_loclists = .empty,
|
||||
.pending_lazy = .empty,
|
||||
};
|
||||
defer wip_nav.deinit();
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
@@ -4008,7 +4092,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
const loaded_struct = ip.loadStructType(type_index);
|
||||
switch (loaded_struct.layout) {
|
||||
.auto, .@"extern" => {
|
||||
try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .namespace_struct_type else .struct_type);
|
||||
try wip_nav.abbrevCode(if (loaded_struct.field_types.len == 0) .empty_struct_type else .struct_type);
|
||||
try uleb128(diw, file_gop.index);
|
||||
try wip_nav.strp(name);
|
||||
if (loaded_struct.field_types.len == 0) try diw.writeByte(@intFromBool(false)) else {
|
||||
try uleb128(diw, ty.abiSize(zcu));
|
||||
@@ -4062,6 +4147,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
},
|
||||
.@"packed" => {
|
||||
try wip_nav.abbrevCode(if (loaded_struct.field_types.len > 0) .packed_struct_type else .empty_packed_struct_type);
|
||||
try uleb128(diw, file_gop.index);
|
||||
try wip_nav.strp(name);
|
||||
try wip_nav.refType(.fromInterned(loaded_struct.backingIntTypeUnordered(ip)));
|
||||
var field_bit_offset: u16 = 0;
|
||||
@@ -4080,6 +4166,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
.enum_type => {
|
||||
const loaded_enum = ip.loadEnumType(type_index);
|
||||
try wip_nav.abbrevCode(if (loaded_enum.names.len > 0) .enum_type else .empty_enum_type);
|
||||
try uleb128(diw, file_gop.index);
|
||||
try wip_nav.strp(name);
|
||||
try wip_nav.refType(.fromInterned(loaded_enum.tag_ty));
|
||||
for (0..loaded_enum.names.len) |field_index| {
|
||||
@@ -4095,6 +4182,7 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
.union_type => {
|
||||
const loaded_union = ip.loadUnionType(type_index);
|
||||
try wip_nav.abbrevCode(if (loaded_union.field_types.len > 0) .union_type else .empty_union_type);
|
||||
try uleb128(diw, file_gop.index);
|
||||
try wip_nav.strp(name);
|
||||
const union_layout = Type.getUnionLayout(loaded_union, zcu);
|
||||
try uleb128(diw, union_layout.abi_size);
|
||||
@@ -4144,7 +4232,8 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
if (loaded_union.field_types.len > 0) try uleb128(diw, @intFromEnum(AbbrevCode.null));
|
||||
},
|
||||
.opaque_type => {
|
||||
try wip_nav.abbrevCode(.namespace_struct_type);
|
||||
try wip_nav.abbrevCode(.empty_struct_type);
|
||||
try uleb128(diw, file_gop.index);
|
||||
try wip_nav.strp(name);
|
||||
try diw.writeByte(@intFromBool(true));
|
||||
},
|
||||
@@ -4156,21 +4245,28 @@ pub fn updateContainerType(dwarf: *Dwarf, pt: Zcu.PerThread, type_index: InternP
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updateNavLineNumber(dwarf: *Dwarf, zcu: *Zcu, nav_index: InternPool.Nav.Index) UpdateError!void {
|
||||
pub fn updateLineNumber(dwarf: *Dwarf, zcu: *Zcu, zir_index: InternPool.TrackedInst.Index) UpdateError!void {
|
||||
const ip = &zcu.intern_pool;
|
||||
|
||||
const zir_index = ip.getCau(ip.getNav(nav_index).analysis_owner.unwrap() orelse return).zir_index;
|
||||
const inst_info = zir_index.resolveFull(ip).?;
|
||||
assert(inst_info.inst != .main_struct_inst);
|
||||
const file = zcu.fileByIndex(inst_info.file);
|
||||
assert(file.zir_loaded);
|
||||
const decl = file.zir.getDeclaration(inst_info.inst);
|
||||
log.debug("updateLineNumber({s}:{d}:{d} %{d} = {s})", .{
|
||||
file.sub_file_path,
|
||||
decl.src_line + 1,
|
||||
decl.src_column + 1,
|
||||
@intFromEnum(inst_info.inst),
|
||||
file.zir.nullTerminatedString(decl.name),
|
||||
});
|
||||
|
||||
const line = file.zir.getDeclaration(inst_info.inst).src_line;
|
||||
var line_buf: [4]u8 = undefined;
|
||||
std.mem.writeInt(u32, &line_buf, line, dwarf.endian);
|
||||
std.mem.writeInt(u32, &line_buf, decl.src_line + 1, dwarf.endian);
|
||||
|
||||
const unit = dwarf.debug_line.section.getUnit(dwarf.mods.get(file.mod).?);
|
||||
const entry = unit.getEntry(dwarf.navs.get(nav_index).?);
|
||||
try dwarf.getFile().?.pwriteAll(&line, dwarf.debug_line.section.off + unit.off + unit.header_len + entry.off + DebugInfo.declEntryLineOff(dwarf));
|
||||
const unit = dwarf.debug_info.section.getUnit(dwarf.getUnitIfExists(file.mod) orelse return);
|
||||
const entry = unit.getEntry(dwarf.decls.get(zir_index) orelse return);
|
||||
try dwarf.getFile().?.pwriteAll(&line_buf, dwarf.debug_info.section.off(dwarf) + unit.off + unit.header_len + entry.off + DebugInfo.declEntryLineOff(dwarf));
|
||||
}
|
||||
|
||||
pub fn freeNav(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) void {
|
||||
@@ -4213,16 +4309,16 @@ pub fn flushModule(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
|
||||
.func_high_pc = undefined,
|
||||
.blocks = undefined,
|
||||
.cfi = undefined,
|
||||
.debug_frame = .{},
|
||||
.debug_info = .{},
|
||||
.debug_line = .{},
|
||||
.debug_loclists = .{},
|
||||
.pending_lazy = .{},
|
||||
.debug_frame = .empty,
|
||||
.debug_info = .empty,
|
||||
.debug_line = .empty,
|
||||
.debug_loclists = .empty,
|
||||
.pending_lazy = .empty,
|
||||
};
|
||||
defer wip_nav.deinit();
|
||||
const diw = wip_nav.debug_info.writer(dwarf.gpa);
|
||||
const global_error_set_names = ip.global_error_set.getNamesFromMainThread();
|
||||
try wip_nav.abbrevCode(if (global_error_set_names.len > 0) .enum_type else .empty_enum_type);
|
||||
try wip_nav.abbrevCode(if (global_error_set_names.len > 0) .generated_enum_type else .generated_empty_enum_type);
|
||||
try wip_nav.strp("anyerror");
|
||||
try wip_nav.refType(.fromInterned(try pt.intern(.{ .int_type = .{
|
||||
.signedness = .unsigned,
|
||||
@@ -4611,7 +4707,7 @@ const AbbrevCode = enum {
|
||||
// padding codes must be one byte uleb128 values to function
|
||||
pad_1,
|
||||
pad_n,
|
||||
// decl codes are assumed to all have the same uleb128 length
|
||||
// (generic) decl codes are assumed to all have the same uleb128 length
|
||||
decl_alias,
|
||||
decl_enum,
|
||||
decl_empty_enum,
|
||||
@@ -4628,11 +4724,34 @@ const AbbrevCode = enum {
|
||||
decl_empty_func,
|
||||
decl_func_generic,
|
||||
decl_empty_func_generic,
|
||||
generic_decl_alias,
|
||||
generic_decl_enum,
|
||||
generic_decl_struct,
|
||||
generic_decl_union,
|
||||
generic_decl_var,
|
||||
generic_decl_const,
|
||||
generic_decl_func,
|
||||
// the rest are unrestricted
|
||||
instance_alias,
|
||||
instance_enum,
|
||||
instance_empty_enum,
|
||||
instance_namespace_struct,
|
||||
instance_struct,
|
||||
instance_packed_struct,
|
||||
instance_union,
|
||||
instance_var,
|
||||
instance_const,
|
||||
instance_const_runtime_bits,
|
||||
instance_const_comptime_state,
|
||||
instance_const_runtime_bits_comptime_state,
|
||||
instance_func,
|
||||
instance_empty_func,
|
||||
instance_func_generic,
|
||||
instance_empty_func_generic,
|
||||
compile_unit,
|
||||
module,
|
||||
namespace_file,
|
||||
file,
|
||||
empty_file,
|
||||
signed_enum_field,
|
||||
unsigned_enum_field,
|
||||
big_enum_field,
|
||||
@@ -4665,10 +4784,15 @@ const AbbrevCode = enum {
|
||||
func_type,
|
||||
func_type_param,
|
||||
is_var_args,
|
||||
generated_enum_type,
|
||||
generated_empty_enum_type,
|
||||
generated_struct_type,
|
||||
generated_empty_struct_type,
|
||||
generated_union_type,
|
||||
enum_type,
|
||||
empty_enum_type,
|
||||
namespace_struct_type,
|
||||
struct_type,
|
||||
empty_struct_type,
|
||||
packed_struct_type,
|
||||
empty_packed_struct_type,
|
||||
union_type,
|
||||
@@ -4694,7 +4818,7 @@ const AbbrevCode = enum {
|
||||
comptime_value_elem_runtime_bits,
|
||||
comptime_value_elem_comptime_state,
|
||||
|
||||
const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.decl_empty_func_generic));
|
||||
const decl_bytes = uleb128Bytes(@intFromEnum(AbbrevCode.generic_decl_func));
|
||||
|
||||
const Attr = struct {
|
||||
DeclValEnum(DW.AT),
|
||||
@@ -4707,6 +4831,10 @@ const AbbrevCode = enum {
|
||||
.{ .accessibility, .data1 },
|
||||
.{ .name, .strp },
|
||||
};
|
||||
const instance_abbrev_common_attrs = &[_]Attr{
|
||||
.{ .ZIG_parent, .ref_addr },
|
||||
.{ .abstract_origin, .ref_addr },
|
||||
};
|
||||
const abbrevs = std.EnumArray(AbbrevCode, struct {
|
||||
tag: DeclValEnum(DW.TAG),
|
||||
children: bool = false,
|
||||
@@ -4857,6 +4985,184 @@ const AbbrevCode = enum {
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.generic_decl_alias = .{
|
||||
.tag = .imported_declaration,
|
||||
.attrs = decl_abbrev_common_attrs ++ .{
|
||||
.{ .declaration, .flag_present },
|
||||
},
|
||||
},
|
||||
.generic_decl_enum = .{
|
||||
.tag = .enumeration_type,
|
||||
.attrs = decl_abbrev_common_attrs ++ .{
|
||||
.{ .declaration, .flag_present },
|
||||
},
|
||||
},
|
||||
.generic_decl_struct = .{
|
||||
.tag = .structure_type,
|
||||
.attrs = decl_abbrev_common_attrs ++ .{
|
||||
.{ .declaration, .flag_present },
|
||||
},
|
||||
},
|
||||
.generic_decl_union = .{
|
||||
.tag = .union_type,
|
||||
.attrs = decl_abbrev_common_attrs ++ .{
|
||||
.{ .declaration, .flag_present },
|
||||
},
|
||||
},
|
||||
.generic_decl_var = .{
|
||||
.tag = .variable,
|
||||
.attrs = decl_abbrev_common_attrs ++ .{
|
||||
.{ .declaration, .flag_present },
|
||||
},
|
||||
},
|
||||
.generic_decl_const = .{
|
||||
.tag = .constant,
|
||||
.attrs = decl_abbrev_common_attrs ++ .{
|
||||
.{ .declaration, .flag_present },
|
||||
},
|
||||
},
|
||||
.generic_decl_func = .{
|
||||
.tag = .subprogram,
|
||||
.attrs = decl_abbrev_common_attrs ++ .{
|
||||
.{ .declaration, .flag_present },
|
||||
},
|
||||
},
|
||||
.instance_alias = .{
|
||||
.tag = .imported_declaration,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .import, .ref_addr },
|
||||
},
|
||||
},
|
||||
.instance_enum = .{
|
||||
.tag = .enumeration_type,
|
||||
.children = true,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.instance_empty_enum = .{
|
||||
.tag = .enumeration_type,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.instance_namespace_struct = .{
|
||||
.tag = .structure_type,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .declaration, .flag },
|
||||
},
|
||||
},
|
||||
.instance_struct = .{
|
||||
.tag = .structure_type,
|
||||
.children = true,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .byte_size, .udata },
|
||||
.{ .alignment, .udata },
|
||||
},
|
||||
},
|
||||
.instance_packed_struct = .{
|
||||
.tag = .structure_type,
|
||||
.children = true,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.instance_union = .{
|
||||
.tag = .union_type,
|
||||
.children = true,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .byte_size, .udata },
|
||||
.{ .alignment, .udata },
|
||||
},
|
||||
},
|
||||
.instance_var = .{
|
||||
.tag = .variable,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .linkage_name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
.{ .location, .exprloc },
|
||||
.{ .alignment, .udata },
|
||||
.{ .external, .flag },
|
||||
},
|
||||
},
|
||||
.instance_const = .{
|
||||
.tag = .constant,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .linkage_name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
.{ .alignment, .udata },
|
||||
.{ .external, .flag },
|
||||
},
|
||||
},
|
||||
.instance_const_runtime_bits = .{
|
||||
.tag = .constant,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .linkage_name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
.{ .alignment, .udata },
|
||||
.{ .external, .flag },
|
||||
.{ .const_value, .block },
|
||||
},
|
||||
},
|
||||
.instance_const_comptime_state = .{
|
||||
.tag = .constant,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .linkage_name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
.{ .alignment, .udata },
|
||||
.{ .external, .flag },
|
||||
.{ .ZIG_comptime_value, .ref_addr },
|
||||
},
|
||||
},
|
||||
.instance_const_runtime_bits_comptime_state = .{
|
||||
.tag = .constant,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .linkage_name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
.{ .alignment, .udata },
|
||||
.{ .external, .flag },
|
||||
.{ .const_value, .block },
|
||||
.{ .ZIG_comptime_value, .ref_addr },
|
||||
},
|
||||
},
|
||||
.instance_func = .{
|
||||
.tag = .subprogram,
|
||||
.children = true,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .linkage_name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
.{ .low_pc, .addr },
|
||||
.{ .high_pc, .data4 },
|
||||
.{ .alignment, .udata },
|
||||
.{ .external, .flag },
|
||||
.{ .noreturn, .flag },
|
||||
},
|
||||
},
|
||||
.instance_empty_func = .{
|
||||
.tag = .subprogram,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .linkage_name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
.{ .low_pc, .addr },
|
||||
.{ .high_pc, .data4 },
|
||||
.{ .alignment, .udata },
|
||||
.{ .external, .flag },
|
||||
.{ .noreturn, .flag },
|
||||
},
|
||||
},
|
||||
.instance_func_generic = .{
|
||||
.tag = .subprogram,
|
||||
.children = true,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.instance_empty_func_generic = .{
|
||||
.tag = .subprogram,
|
||||
.attrs = instance_abbrev_common_attrs ++ .{
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.compile_unit = .{
|
||||
.tag = .compile_unit,
|
||||
.children = true,
|
||||
@@ -4879,13 +5185,6 @@ const AbbrevCode = enum {
|
||||
.{ .ranges, .rnglistx },
|
||||
},
|
||||
},
|
||||
.namespace_file = .{
|
||||
.tag = .structure_type,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
},
|
||||
},
|
||||
.file = .{
|
||||
.tag = .structure_type,
|
||||
.children = true,
|
||||
@@ -4896,6 +5195,13 @@ const AbbrevCode = enum {
|
||||
.{ .alignment, .udata },
|
||||
},
|
||||
},
|
||||
.empty_file = .{
|
||||
.tag = .structure_type,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
},
|
||||
},
|
||||
.signed_enum_field = .{
|
||||
.tag = .enumerator,
|
||||
.attrs = &.{
|
||||
@@ -5143,7 +5449,7 @@ const AbbrevCode = enum {
|
||||
.is_var_args = .{
|
||||
.tag = .unspecified_parameters,
|
||||
},
|
||||
.enum_type = .{
|
||||
.generated_enum_type = .{
|
||||
.tag = .enumeration_type,
|
||||
.children = true,
|
||||
.attrs = &.{
|
||||
@@ -5151,21 +5457,14 @@ const AbbrevCode = enum {
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.empty_enum_type = .{
|
||||
.generated_empty_enum_type = .{
|
||||
.tag = .enumeration_type,
|
||||
.attrs = &.{
|
||||
.{ .name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.namespace_struct_type = .{
|
||||
.tag = .structure_type,
|
||||
.attrs = &.{
|
||||
.{ .name, .strp },
|
||||
.{ .declaration, .flag },
|
||||
},
|
||||
},
|
||||
.struct_type = .{
|
||||
.generated_struct_type = .{
|
||||
.tag = .structure_type,
|
||||
.children = true,
|
||||
.attrs = &.{
|
||||
@@ -5174,10 +5473,62 @@ const AbbrevCode = enum {
|
||||
.{ .alignment, .udata },
|
||||
},
|
||||
},
|
||||
.generated_empty_struct_type = .{
|
||||
.tag = .structure_type,
|
||||
.attrs = &.{
|
||||
.{ .name, .strp },
|
||||
.{ .declaration, .flag },
|
||||
},
|
||||
},
|
||||
.generated_union_type = .{
|
||||
.tag = .union_type,
|
||||
.children = true,
|
||||
.attrs = &.{
|
||||
.{ .name, .strp },
|
||||
.{ .byte_size, .udata },
|
||||
.{ .alignment, .udata },
|
||||
},
|
||||
},
|
||||
.enum_type = .{
|
||||
.tag = .enumeration_type,
|
||||
.children = true,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.empty_enum_type = .{
|
||||
.tag = .enumeration_type,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
},
|
||||
.struct_type = .{
|
||||
.tag = .structure_type,
|
||||
.children = true,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
.{ .byte_size, .udata },
|
||||
.{ .alignment, .udata },
|
||||
},
|
||||
},
|
||||
.empty_struct_type = .{
|
||||
.tag = .structure_type,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
.{ .declaration, .flag },
|
||||
},
|
||||
},
|
||||
.packed_struct_type = .{
|
||||
.tag = .structure_type,
|
||||
.children = true,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
@@ -5185,6 +5536,7 @@ const AbbrevCode = enum {
|
||||
.empty_packed_struct_type = .{
|
||||
.tag = .structure_type,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
.{ .type, .ref_addr },
|
||||
},
|
||||
@@ -5193,6 +5545,7 @@ const AbbrevCode = enum {
|
||||
.tag = .union_type,
|
||||
.children = true,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
.{ .byte_size, .udata },
|
||||
.{ .alignment, .udata },
|
||||
@@ -5201,6 +5554,7 @@ const AbbrevCode = enum {
|
||||
.empty_union_type = .{
|
||||
.tag = .union_type,
|
||||
.attrs = &.{
|
||||
.{ .decl_file, .udata },
|
||||
.{ .name, .strp },
|
||||
.{ .byte_size, .udata },
|
||||
.{ .alignment, .udata },
|
||||
@@ -5373,6 +5727,15 @@ fn addCommonEntry(dwarf: *Dwarf, unit: Unit.Index) UpdateError!Entry.Index {
|
||||
return entry;
|
||||
}
|
||||
|
||||
fn freeCommonEntry(dwarf: *Dwarf, unit: Unit.Index, entry: Entry.Index) UpdateError!void {
|
||||
try dwarf.debug_aranges.section.freeEntry(unit, entry, dwarf);
|
||||
try dwarf.debug_frame.section.freeEntry(unit, entry, dwarf);
|
||||
try dwarf.debug_info.section.freeEntry(unit, entry, dwarf);
|
||||
try dwarf.debug_line.section.freeEntry(unit, entry, dwarf);
|
||||
try dwarf.debug_loclists.section.freeEntry(unit, entry, dwarf);
|
||||
try dwarf.debug_rnglists.section.freeEntry(unit, entry, dwarf);
|
||||
}
|
||||
|
||||
fn writeInt(dwarf: *Dwarf, buf: []u8, int: u64) void {
|
||||
switch (buf.len) {
|
||||
inline 0...8 => |len| std.mem.writeInt(@Type(.{ .int = .{
|
||||
|
||||
+2
-2
@@ -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(
|
||||
|
||||
+14
-43
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -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(
|
||||
|
||||
+2
-2
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
@@ -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