authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-25 03:51:58+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-25 15:05:52+00:00
log31a7f22b800c091962726de2dd29f10a8eb25b78
tree2cfbb25b0ed73eecb17c976777df08765237a4be
parent5c628312b16ce972cc3108ed44eed47960e17af7

llvm: update current debug location scope when entering debug scope

This issue was causing debug information to sometimes not function correctly for some local variables, with debuggers simply reporting that the variable does not exist. What was happening was that after an AIR body - and thus debug lexical scope - begins, but before any `dbg_stmt` within it, the `scope` on `self.wip.debug_location` refers to the parent scope, but the `scope` field on the `DILocalVariable` metadata passed to `@llvm.dbg.declare` points, correctly, to the nested scope. I haven't looked into precisely what happens here, but in short, it would appear that LLVM Doesn't Like It (tm). The fix is simple: when we change `self.scope` at the start or end of an AIR body, also modify the scope on `self.wip.debug_location`. This is correct as we always want the debug info for an instruction to be associated with the block it is within, even if the line/column are slightly outdated for any reason.

1 files changed, 10 insertions(+), 0 deletions(-)

src/codegen/llvm.zig+10
...@@ -5202,6 +5202,16 @@ pub const FuncGen = struct {...@@ -5202,6 +5202,16 @@ pub const FuncGen = struct {
5202 self.prev_dbg_line,5202 self.prev_dbg_line,
5203 self.prev_dbg_column,5203 self.prev_dbg_column,
5204 );5204 );
5205
5206 switch (self.wip.debug_location) {
5207 .location => |*l| l.scope = self.scope,
5208 .no_location => {},
5209 }
5210 defer switch (self.wip.debug_location) {
5211 .location => |*l| l.scope = old_scope,
5212 .no_location => {},
5213 };
5214
5205 try self.genBody(body);5215 try self.genBody(body);
5206 }5216 }
52075217