aboutsummaryrefslogtreecommitdiff
path: root/src-self-hosted/link.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-08-04 00:22:11 -0700
committerAndrew Kelley <andrew@ziglang.org>2020-08-04 00:22:11 -0700
commit0d696a48dadffbb3dcd3f7ada6867129da4d70c8 (patch)
tree963b8e3b841189b720e77770afc6dfa3c3c6da83 /src-self-hosted/link.zig
parent30ee08dfc2236a9c25826dbde82f9865bae5cf30 (diff)
downloadzig-0d696a48dadffbb3dcd3f7ada6867129da4d70c8.tar.gz
zig-0d696a48dadffbb3dcd3f7ada6867129da4d70c8.zip
stage2 .debug_line: handle Decl line numbers changing
Diffstat (limited to 'src-self-hosted/link.zig')
-rw-r--r--src-self-hosted/link.zig33
1 files changed, 31 insertions, 2 deletions
diff --git a/src-self-hosted/link.zig b/src-self-hosted/link.zig
index b96c1ae3a0..c3f5146113 100644
--- a/src-self-hosted/link.zig
+++ b/src-self-hosted/link.zig
@@ -85,6 +85,13 @@ pub const File = struct {
}
}
+ pub fn updateDeclLineNumber(base: *File, module: *Module, decl: *Module.Decl) !void {
+ switch (base.tag) {
+ .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl),
+ .c => {},
+ }
+ }
+
pub fn allocateDeclIndexes(base: *File, decl: *Module.Decl) !void {
switch (base.tag) {
.elf => return @fieldParentPtr(Elf, "base", base).allocateDeclIndexes(decl),
@@ -203,7 +210,7 @@ pub const File = struct {
pub fn fail(self: *C, src: usize, comptime format: []const u8, args: anytype) !void {
self.error_msg = try Module.ErrorMsg.create(self.allocator, src, format, args);
- return error.CGenFailure;
+ return error.AnalysisFail;
}
pub fn deinit(self: *File.C) void {
@@ -217,7 +224,7 @@ pub const File = struct {
pub fn updateDecl(self: *File.C, module: *Module, decl: *Module.Decl) !void {
c_codegen.generate(self, decl) catch |err| {
- if (err == error.CGenFailure) {
+ if (err == error.AnalysisFail) {
try module.failed_decls.put(module.gpa, decl, self.error_msg);
}
return err;
@@ -2088,6 +2095,28 @@ pub const File = struct {
}
}
+ /// Must be called only after a successful call to `updateDecl`.
+ pub fn updateDeclLineNumber(self: *Elf, module: *Module, decl: *const Module.Decl) !void {
+ const tracy = trace(@src());
+ defer tracy.end();
+
+ const scope_file = decl.scope.cast(Module.Scope.File).?;
+ const tree = scope_file.contents.tree;
+ const file_ast_decls = tree.root_node.decls();
+ // TODO Look into improving the performance here by adding a token-index-to-line
+ // lookup table. Currently this involves scanning over the source code for newlines.
+ const fn_proto = file_ast_decls[decl.src_index].castTag(.FnProto).?;
+ const block = fn_proto.body().?.castTag(.Block).?;
+ const line_delta = std.zig.lineDelta(tree.source, 0, tree.token_locs[block.lbrace].start);
+ const casted_line_off = @intCast(u28, line_delta);
+
+ const shdr = &self.sections.items[self.debug_line_section_index.?];
+ const file_pos = shdr.sh_offset + decl.fn_link.off + self.getRelocDbgLineOff();
+ var data: [4]u8 = undefined;
+ leb128.writeUnsignedFixed(4, &data, casted_line_off);
+ try self.file.?.pwriteAll(&data, file_pos);
+ }
+
pub fn deleteExport(self: *Elf, exp: Export) void {
const sym_index = exp.sym_index orelse return;
self.global_symbol_free_list.append(self.allocator, sym_index) catch {};