diff --git a/src/Module.zig b/src/Module.zig index 4eef536fcd..9a0134c797 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -923,6 +923,20 @@ pub const Scope = struct { try block.instructions.append(block.sema.gpa, &inst.base); return &inst.base; } + + pub fn addDbgStmt(block: *Scope.Block, src: LazySrcLoc, abs_byte_off: u32) !*ir.Inst { + const inst = try block.sema.arena.create(ir.Inst.DbgStmt); + inst.* = .{ + .base = .{ + .tag = .dbg_stmt, + .ty = Type.initTag(.void), + .src = src, + }, + .byte_offset = abs_byte_off, + }; + try block.instructions.append(block.sema.gpa, &inst.base); + return &inst.base; + } }; /// This is a temporary structure; references to it are valid only @@ -1330,14 +1344,12 @@ pub const SrcLoc = struct { .byte_abs => |byte_index| return byte_index, .token_abs => |tok_index| { - const file_scope = src_loc.container.file_scope; - const tree = try mod.getAstTree(file_scope); + const tree = src_loc.container.file_scope.base.tree(); const token_starts = tree.tokens.items(.start); return token_starts[tok_index]; }, .node_abs => |node_index| { - const file_scope = src_loc.container.file_scope; - const tree = try mod.getAstTree(file_scope); + const tree = src_loc.container.file_scope.base.tree(); const token_starts = tree.tokens.items(.start); const tok_index = tree.firstToken(node_index); return token_starts[tok_index]; @@ -1349,14 +1361,14 @@ pub const SrcLoc = struct { .token_offset => |tok_off| { const decl = src_loc.container.decl; const tok_index = decl.srcToken() + tok_off; - const tree = try mod.getAstTree(decl.container.file_scope); + const tree = src_loc.container.file_scope.base.tree(); const token_starts = tree.tokens.items(.start); return token_starts[tok_index]; }, .node_offset => |node_off| { const decl = src_loc.container.decl; const node_index = decl.srcNode() + node_off; - const tree = try mod.getAstTree(decl.container.file_scope); + const tree = src_loc.container.file_scope.base.tree(); const tok_index = tree.firstToken(node_index); const token_starts = tree.tokens.items(.start); return token_starts[tok_index]; diff --git a/src/Sema.zig b/src/Sema.zig index 88aa82eaec..ed3b441e61 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1003,7 +1003,9 @@ fn zirDbgStmtNode(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerE const src_node = sema.code.instructions.items(.data)[inst].node; const src: LazySrcLoc = .{ .node_offset = src_node }; - return block.addNoOp(src, Type.initTag(.void), .dbg_stmt); + const src_loc = src.toSrcLoc(&block.base); + const abs_byte_off = try src_loc.byteOffset(sema.mod); + return block.addDbgStmt(src, abs_byte_off); } fn zirDeclRef(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { diff --git a/src/codegen.zig b/src/codegen.zig index 45d66b2767..6649226426 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -792,8 +792,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { } } - fn dbgAdvancePCAndLine(self: *Self, src: usize) InnerError!void { - self.prev_di_src = src; + fn dbgAdvancePCAndLine(self: *Self, abs_byte_off: usize) InnerError!void { + self.prev_di_src = abs_byte_off; self.prev_di_pc = self.code.items.len; switch (self.debug_output) { .dwarf => |dbg_out| { @@ -801,7 +801,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { // lookup table, and changing ir.Inst from storing byte offset to token. Currently // this involves scanning over the source code for newlines // (but only from the previous byte offset to the new one). - const delta_line = std.zig.lineDelta(self.source, self.prev_di_src, src); + const delta_line = std.zig.lineDelta(self.source, self.prev_di_src, abs_byte_off); const delta_pc = self.code.items.len - self.prev_di_pc; // TODO Look into using the DWARF special opcodes to compress this data. It lets you emit // single-byte opcodes that add different numbers to both the PC and the line number @@ -2315,8 +2315,12 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { } } - fn genDbgStmt(self: *Self, inst: *ir.Inst.NoOp) !MCValue { - try self.dbgAdvancePCAndLine(inst.base.src); + fn genDbgStmt(self: *Self, inst: *ir.Inst.DbgStmt) !MCValue { + // TODO when reworking tzir memory layout, rework source locations here as + // well to be more efficient, as well as support inlined function calls correctly. + // For now we convert LazySrcLoc to absolute byte offset, to match what the + // existing codegen code expects. + try self.dbgAdvancePCAndLine(inst.byte_offset); assert(inst.base.isUnused()); return MCValue.dead; } diff --git a/src/codegen/c.zig b/src/codegen/c.zig index dc5c29716b..02d44f53c3 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -760,7 +760,7 @@ fn genCall(o: *Object, inst: *Inst.Call) !CValue { } } -fn genDbgStmt(o: *Object, inst: *Inst.NoOp) !CValue { +fn genDbgStmt(o: *Object, inst: *Inst.DbgStmt) !CValue { // TODO emit #line directive here with line number and filename return CValue.none; } diff --git a/src/ir.zig b/src/ir.zig index 9a96f4bcb1..bbcd30d620 100644 --- a/src/ir.zig +++ b/src/ir.zig @@ -138,7 +138,6 @@ pub const Inst = struct { .retvoid, .unreach, .breakpoint, - .dbg_stmt, => NoOp, .ref, @@ -198,6 +197,7 @@ pub const Inst = struct { .loop => Loop, .varptr => VarPtr, .switchbr => SwitchBr, + .dbg_stmt => DbgStmt, }; } @@ -584,6 +584,20 @@ pub const Inst = struct { return (self.deaths + self.else_index)[0..self.else_deaths]; } }; + + pub const DbgStmt = struct { + pub const base_tag = Tag.dbg_stmt; + + base: Inst, + byte_offset: u32, + + pub fn operandCount(self: *const DbgStmt) usize { + return 0; + } + pub fn getOperand(self: *const DbgStmt, index: usize) ?*Inst { + return null; + } + }; }; pub const Body = struct {