Commit c894ac09a3
Changed files (25)
lib
std
src
arch
aarch64
arm
riscv64
sparc64
wasm
link
Liveness
test
src
lib/std/zig/AstGen.zig
@@ -6024,7 +6024,7 @@ fn tryExpr(
if (!parent_gz.is_comptime) {
try emitDbgNode(parent_gz, node);
}
- const try_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
+ const try_lc: LineColumn = .{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
const operand_rl: ResultInfo.Loc, const block_tag: Zir.Inst.Tag = switch (ri.rl) {
.ref => .{ .ref, .try_ptr },
@@ -6577,6 +6577,7 @@ fn whileExpr(
const astgen = parent_gz.astgen;
const tree = astgen.tree;
const token_tags = tree.tokens.items(.tag);
+ const token_starts = tree.tokens.items(.start);
const need_rl = astgen.nodes_need_rl.contains(node);
const block_ri: ResultInfo = if (need_rl) ri else .{
@@ -6774,6 +6775,16 @@ fn whileExpr(
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
if (!continue_scope.endsWithNoReturn()) {
+ astgen.advanceSourceCursor(token_starts[tree.lastToken(then_node)]);
+ try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column });
+ _ = try parent_gz.add(.{
+ .tag = .extended,
+ .data = .{ .extended = .{
+ .opcode = .dbg_empty_stmt,
+ .small = undefined,
+ .operand = undefined,
+ } },
+ });
_ = try continue_scope.addBreak(break_tag, continue_block, .void_value);
}
try continue_scope.setBlockBody(continue_block);
@@ -6882,6 +6893,7 @@ fn forExpr(
}
const tree = astgen.tree;
const token_tags = tree.tokens.items(.tag);
+ const token_starts = tree.tokens.items(.start);
const node_tags = tree.nodes.items(.tag);
const node_data = tree.nodes.items(.data);
const gpa = astgen.gpa;
@@ -7087,8 +7099,18 @@ fn forExpr(
try checkUsed(parent_gz, &then_scope.base, then_sub_scope);
- const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
+ astgen.advanceSourceCursor(token_starts[tree.lastToken(then_node)]);
+ try emitDbgStmt(parent_gz, .{ astgen.source_line - parent_gz.decl_line, astgen.source_column });
+ _ = try parent_gz.add(.{
+ .tag = .extended,
+ .data = .{ .extended = .{
+ .opcode = .dbg_empty_stmt,
+ .small = undefined,
+ .operand = undefined,
+ } },
+ });
+ const break_tag: Zir.Inst.Tag = if (is_inline) .break_inline else .@"break";
_ = try then_scope.addBreak(break_tag, cond_block, .void_value);
var else_scope = parent_gz.makeSubBlock(&cond_scope.base);
@@ -7135,6 +7157,7 @@ fn forExpr(
.lhs = index_ptr,
.rhs = index_plus_one,
});
+
const repeat_tag: Zir.Inst.Tag = if (is_inline) .repeat_inline else .repeat;
_ = try loop_scope.addNode(repeat_tag, node);
@@ -7279,7 +7302,7 @@ fn switchExprErrUnion(
};
astgen.advanceSourceCursorToNode(operand_node);
- const operand_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
+ const operand_lc: LineColumn = .{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
const raw_operand = try reachableExpr(parent_gz, scope, operand_ri, operand_node, switch_node);
const item_ri: ResultInfo = .{ .rl = .none };
@@ -7868,7 +7891,7 @@ fn switchExpr(
const operand_ri: ResultInfo = .{ .rl = if (any_payload_is_ref) .ref else .none };
astgen.advanceSourceCursorToNode(operand_node);
- const operand_lc = LineColumn{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
+ const operand_lc: LineColumn = .{ astgen.source_line - parent_gz.decl_line, astgen.source_column };
const raw_operand = try expr(parent_gz, scope, operand_ri, operand_node);
const item_ri: ResultInfo = .{ .rl = .none };
@@ -8214,7 +8237,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
if (!gz.is_comptime) {
try emitDbgNode(gz, node);
}
- const ret_lc = LineColumn{ astgen.source_line - gz.decl_line, astgen.source_column };
+ const ret_lc: LineColumn = .{ astgen.source_line - gz.decl_line, astgen.source_column };
const defer_outer = &astgen.fn_block.?.base;
lib/std/zig/Zir.zig
@@ -2088,6 +2088,8 @@ pub const Inst = struct {
/// `operand` is `Zir.Inst.Ref` of the loaded LHS (*not* its type).
/// `small` is an `Inst.InplaceOp`.
inplace_arith_result_ty,
+ /// Marks a statement that can be stepped to but produces no code.
+ dbg_empty_stmt,
pub const InstData = struct {
opcode: Extended,
@@ -4062,6 +4064,7 @@ fn findDeclsInner(
.branch_hint,
.inplace_arith_result_ty,
.tuple_decl,
+ .dbg_empty_stmt,
=> return,
// `@TypeOf` has a body.
src/Air/types_resolved.zig
@@ -417,6 +417,7 @@ fn checkBody(air: Air, body: []const Air.Inst.Index, zcu: *Zcu) bool {
.work_group_size,
.work_group_id,
.dbg_stmt,
+ .dbg_empty_stmt,
.err_return_trace,
.save_err_return_trace_index,
.repeat,
src/arch/aarch64/CodeGen.zig
@@ -800,6 +800,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.try_ptr_cold => try self.airTryPtr(inst),
.dbg_stmt => try self.airDbgStmt(inst),
+ .dbg_empty_stmt => self.finishAirBookkeeping(),
.dbg_inline_block => try self.airDbgInlineBlock(inst),
.dbg_var_ptr,
.dbg_var_val,
src/arch/arm/CodeGen.zig
@@ -787,6 +787,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.try_ptr_cold => try self.airTryPtr(inst),
.dbg_stmt => try self.airDbgStmt(inst),
+ .dbg_empty_stmt => self.finishAirBookkeeping(),
.dbg_inline_block => try self.airDbgInlineBlock(inst),
.dbg_var_ptr,
.dbg_var_val,
src/arch/riscv64/CodeGen.zig
@@ -1593,6 +1593,7 @@ fn genBody(func: *Func, body: []const Air.Inst.Index) InnerError!void {
.frame_addr => try func.airFrameAddress(inst),
.cond_br => try func.airCondBr(inst),
.dbg_stmt => try func.airDbgStmt(inst),
+ .dbg_empty_stmt => func.finishAirBookkeeping(),
.fptrunc => try func.airFptrunc(inst),
.fpext => try func.airFpext(inst),
.intcast => try func.airIntCast(inst),
src/arch/sparc64/CodeGen.zig
@@ -642,6 +642,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.try_ptr_cold => @panic("TODO try self.airTryPtrCold(inst)"),
.dbg_stmt => try self.airDbgStmt(inst),
+ .dbg_empty_stmt => self.finishAirBookkeeping(),
.dbg_inline_block => try self.airDbgInlineBlock(inst),
.dbg_var_ptr,
.dbg_var_val,
src/arch/wasm/CodeGen.zig
@@ -1924,6 +1924,7 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
.try_ptr_cold => func.airTryPtr(inst),
.dbg_stmt => func.airDbgStmt(inst),
+ .dbg_empty_stmt => try func.finishAir(inst, .none, &.{}),
.dbg_inline_block => func.airDbgInlineBlock(inst),
.dbg_var_ptr => func.airDbgVar(inst, .local_var, true),
.dbg_var_val => func.airDbgVar(inst, .local_var, false),
src/arch/x86_64/CodeGen.zig
@@ -961,9 +961,16 @@ pub fn generate(
},
.debug_output = debug_output,
.code = code,
+ .prev_di_loc = .{
+ .line = func.lbrace_line,
+ .column = func.lbrace_column,
+ .is_stmt = switch (debug_output) {
+ .dwarf => |dwarf| dwarf.dwarf.debug_line.header.default_is_stmt,
+ .plan9 => undefined,
+ .none => undefined,
+ },
+ },
.prev_di_pc = 0,
- .prev_di_line = func.lbrace_line,
- .prev_di_column = func.lbrace_column,
};
defer emit.deinit();
emit.emitMir() catch |err| switch (err) {
@@ -1066,9 +1073,8 @@ pub fn generateLazy(
},
.debug_output = debug_output,
.code = code,
+ .prev_di_loc = undefined, // no debug info yet
.prev_di_pc = undefined, // no debug info yet
- .prev_di_line = undefined, // no debug info yet
- .prev_di_column = undefined, // no debug info yet
};
defer emit.deinit();
emit.emitMir() catch |err| switch (err) {
@@ -1194,13 +1200,16 @@ fn formatWipMir(
switch (mir_inst.ops) {
else => unreachable,
.pseudo_dbg_prologue_end_none,
- .pseudo_dbg_line_line_column,
.pseudo_dbg_epilogue_begin_none,
.pseudo_dbg_enter_block_none,
.pseudo_dbg_leave_block_none,
.pseudo_dbg_var_args_none,
.pseudo_dead_none,
=> {},
+ .pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try writer.print(
+ " {[line]d}, {[column]d}",
+ mir_inst.data.line_column,
+ ),
.pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try writer.print(" {}", .{
ip.getNav(ip.indexToKey(mir_inst.data.func).func.owner_nav).name.fmt(ip),
}),
@@ -1281,14 +1290,7 @@ fn addInst(self: *Self, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index {
try self.mir_instructions.ensureUnusedCapacity(gpa, 1);
const result_index: Mir.Inst.Index = @intCast(self.mir_instructions.len);
self.mir_instructions.appendAssumeCapacity(inst);
- if (inst.tag != .pseudo or switch (inst.ops) {
- else => true,
- .pseudo_dbg_prologue_end_none,
- .pseudo_dbg_line_line_column,
- .pseudo_dbg_epilogue_begin_none,
- .pseudo_dead_none,
- => false,
- }) wip_mir_log.debug("{}", .{self.fmtWipMir(result_index)});
+ wip_mir_log.debug("{}", .{self.fmtWipMir(result_index)});
return result_index;
}
@@ -2218,7 +2220,7 @@ fn gen(self: *Self) InnerError!void {
// Drop them off at the rbrace.
_ = try self.addInst(.{
.tag = .pseudo,
- .ops = .pseudo_dbg_line_line_column,
+ .ops = .pseudo_dbg_line_stmt_line_column,
.data = .{ .line_column = .{
.line = self.end_di_line,
.column = self.end_di_column,
@@ -2426,6 +2428,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
.try_ptr_cold => try self.airTryPtr(inst), // TODO
.dbg_stmt => try self.airDbgStmt(inst),
+ .dbg_empty_stmt => try self.airDbgEmptyStmt(),
.dbg_inline_block => try self.airDbgInlineBlock(inst),
.dbg_var_ptr,
.dbg_var_val,
@@ -13281,7 +13284,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
const dbg_stmt = self.air.instructions.items(.data)[@intFromEnum(inst)].dbg_stmt;
_ = try self.addInst(.{
.tag = .pseudo,
- .ops = .pseudo_dbg_line_line_column,
+ .ops = .pseudo_dbg_line_stmt_line_column,
.data = .{ .line_column = .{
.line = dbg_stmt.line,
.column = dbg_stmt.column,
@@ -13290,6 +13293,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
self.finishAirBookkeeping();
}
+fn airDbgEmptyStmt(self: *Self) !void {
+ if (self.mir_instructions.len > 0 and
+ self.mir_instructions.items(.ops)[self.mir_instructions.len - 1] == .pseudo_dbg_line_stmt_line_column)
+ self.mir_instructions.items(.ops)[self.mir_instructions.len - 1] = .pseudo_dbg_line_line_column;
+ try self.asmOpOnly(.{ ._, .nop });
+ self.finishAirBookkeeping();
+}
+
fn airDbgInlineBlock(self: *Self, inst: Air.Inst.Index) !void {
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
src/arch/x86_64/Emit.zig
@@ -6,8 +6,7 @@ atom_index: u32,
debug_output: link.File.DebugInfoOutput,
code: *std.ArrayList(u8),
-prev_di_line: u32,
-prev_di_column: u32,
+prev_di_loc: Loc,
/// Relative to the beginning of `code`.
prev_di_pc: usize,
@@ -263,77 +262,71 @@ pub fn emitMir(emit: *Emit) Error!void {
else => unreachable,
.pseudo => switch (mir_inst.ops) {
else => unreachable,
- .pseudo_dbg_prologue_end_none => {
- switch (emit.debug_output) {
- .dwarf => |dw| try dw.setPrologueEnd(),
- .plan9 => {},
- .none => {},
- }
+ .pseudo_dbg_prologue_end_none => switch (emit.debug_output) {
+ .dwarf => |dwarf| try dwarf.setPrologueEnd(),
+ .plan9 => {},
+ .none => {},
},
- .pseudo_dbg_line_line_column => try emit.dbgAdvancePCAndLine(
- mir_inst.data.line_column.line,
- mir_inst.data.line_column.column,
- ),
- .pseudo_dbg_epilogue_begin_none => {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- try dw.setEpilogueBegin();
- log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
- emit.prev_di_line, emit.prev_di_column,
- });
- try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
- },
- .plan9 => {},
- .none => {},
- }
+ .pseudo_dbg_line_stmt_line_column => try emit.dbgAdvancePCAndLine(.{
+ .line = mir_inst.data.line_column.line,
+ .column = mir_inst.data.line_column.column,
+ .is_stmt = true,
+ }),
+ .pseudo_dbg_line_line_column => try emit.dbgAdvancePCAndLine(.{
+ .line = mir_inst.data.line_column.line,
+ .column = mir_inst.data.line_column.column,
+ .is_stmt = false,
+ }),
+ .pseudo_dbg_epilogue_begin_none => switch (emit.debug_output) {
+ .dwarf => |dwarf| {
+ try dwarf.setEpilogueBegin();
+ log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
+ emit.prev_di_loc.line, emit.prev_di_loc.column,
+ });
+ try emit.dbgAdvancePCAndLine(emit.prev_di_loc);
+ },
+ .plan9 => {},
+ .none => {},
},
- .pseudo_dbg_enter_block_none => {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- log.debug("mirDbgEnterBlock (line={d}, col={d})", .{
- emit.prev_di_line, emit.prev_di_column,
- });
- try dw.enterBlock(emit.code.items.len);
- },
- .plan9 => {},
- .none => {},
- }
+ .pseudo_dbg_enter_block_none => switch (emit.debug_output) {
+ .dwarf => |dwarf| {
+ log.debug("mirDbgEnterBlock (line={d}, col={d})", .{
+ emit.prev_di_loc.line, emit.prev_di_loc.column,
+ });
+ try dwarf.enterBlock(emit.code.items.len);
+ },
+ .plan9 => {},
+ .none => {},
},
- .pseudo_dbg_leave_block_none => {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- log.debug("mirDbgLeaveBlock (line={d}, col={d})", .{
- emit.prev_di_line, emit.prev_di_column,
- });
- try dw.leaveBlock(emit.code.items.len);
- },
- .plan9 => {},
- .none => {},
- }
+ .pseudo_dbg_leave_block_none => switch (emit.debug_output) {
+ .dwarf => |dwarf| {
+ log.debug("mirDbgLeaveBlock (line={d}, col={d})", .{
+ emit.prev_di_loc.line, emit.prev_di_loc.column,
+ });
+ try dwarf.leaveBlock(emit.code.items.len);
+ },
+ .plan9 => {},
+ .none => {},
},
- .pseudo_dbg_enter_inline_func => {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- log.debug("mirDbgEnterInline (line={d}, col={d})", .{
- emit.prev_di_line, emit.prev_di_column,
- });
- try dw.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_line, emit.prev_di_column);
- },
- .plan9 => {},
- .none => {},
- }
+ .pseudo_dbg_enter_inline_func => switch (emit.debug_output) {
+ .dwarf => |dwarf| {
+ log.debug("mirDbgEnterInline (line={d}, col={d})", .{
+ emit.prev_di_loc.line, emit.prev_di_loc.column,
+ });
+ try dwarf.enterInlineFunc(mir_inst.data.func, emit.code.items.len, emit.prev_di_loc.line, emit.prev_di_loc.column);
+ },
+ .plan9 => {},
+ .none => {},
},
- .pseudo_dbg_leave_inline_func => {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
- emit.prev_di_line, emit.prev_di_column,
- });
- try dw.leaveInlineFunc(mir_inst.data.func, emit.code.items.len);
- },
- .plan9 => {},
- .none => {},
- }
+ .pseudo_dbg_leave_inline_func => switch (emit.debug_output) {
+ .dwarf => |dwarf| {
+ log.debug("mirDbgLeaveInline (line={d}, col={d})", .{
+ emit.prev_di_loc.line, emit.prev_di_loc.column,
+ });
+ try dwarf.leaveInlineFunc(mir_inst.data.func, emit.code.items.len);
+ },
+ .plan9 => {},
+ .none => {},
},
.pseudo_dbg_local_a,
.pseudo_dbg_local_ai_s,
@@ -344,129 +337,125 @@ pub fn emitMir(emit: *Emit) Error!void {
.pseudo_dbg_local_aro,
.pseudo_dbg_local_af,
.pseudo_dbg_local_am,
- => {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- var loc_buf: [2]link.File.Dwarf.Loc = undefined;
- const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) {
+ => switch (emit.debug_output) {
+ .dwarf => |dwarf| {
+ var loc_buf: [2]link.File.Dwarf.Loc = undefined;
+ const air_inst_index, const loc: link.File.Dwarf.Loc = switch (mir_inst.ops) {
+ else => unreachable,
+ .pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty },
+ .pseudo_dbg_local_ai_s,
+ .pseudo_dbg_local_ai_u,
+ .pseudo_dbg_local_ai_64,
+ => .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: {
+ loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) {
+ .signed => |s| .{ .consts = s },
+ .unsigned => |u| .{ .constu = u },
+ };
+ break :stack_value &loc_buf[0];
+ } } },
+ .pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{ .addr = .{
+ .sym = mir_inst.data.as.sym_index,
+ } } },
+ .pseudo_dbg_local_aso => loc: {
+ const sym_off = emit.lower.mir.extraData(
+ bits.SymbolOffset,
+ mir_inst.data.ax.payload,
+ ).data;
+ break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
+ sym: {
+ loc_buf[0] = .{ .addr = .{ .sym = sym_off.sym_index } };
+ break :sym &loc_buf[0];
+ },
+ off: {
+ loc_buf[1] = .{ .consts = sym_off.off };
+ break :off &loc_buf[1];
+ },
+ } } };
+ },
+ .pseudo_dbg_local_aro => loc: {
+ const air_off = emit.lower.mir.extraData(
+ Mir.AirOffset,
+ mir_inst.data.rx.payload,
+ ).data;
+ break :loc .{ air_off.air_inst, .{ .plus = .{
+ reg: {
+ loc_buf[0] = .{ .breg = mir_inst.data.rx.r1.dwarfNum() };
+ break :reg &loc_buf[0];
+ },
+ off: {
+ loc_buf[1] = .{ .consts = air_off.off };
+ break :off &loc_buf[1];
+ },
+ } } };
+ },
+ .pseudo_dbg_local_af => loc: {
+ const reg_off = emit.lower.mir.resolveFrameAddr(emit.lower.mir.extraData(
+ bits.FrameAddr,
+ mir_inst.data.ax.payload,
+ ).data);
+ break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
+ reg: {
+ loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };
+ break :reg &loc_buf[0];
+ },
+ off: {
+ loc_buf[1] = .{ .consts = reg_off.off };
+ break :off &loc_buf[1];
+ },
+ } } };
+ },
+ .pseudo_dbg_local_am => loc: {
+ const mem = emit.lower.mem(mir_inst.data.ax.payload);
+ break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
+ base: {
+ loc_buf[0] = switch (mem.base()) {
+ .none => .{ .constu = 0 },
+ .reg => |reg| .{ .breg = reg.dwarfNum() },
+ .frame => unreachable,
+ .reloc => |sym_index| .{ .addr = .{ .sym = sym_index } },
+ };
+ break :base &loc_buf[0];
+ },
+ disp: {
+ loc_buf[1] = switch (mem.disp()) {
+ .signed => |s| .{ .consts = s },
+ .unsigned => |u| .{ .constu = u },
+ };
+ break :disp &loc_buf[1];
+ },
+ } } };
+ },
+ };
+ const ip = &emit.lower.bin_file.comp.zcu.?.intern_pool;
+ const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index));
+ const name: Air.NullTerminatedString = switch (air_inst.tag) {
+ else => unreachable,
+ .arg => air_inst.data.arg.name,
+ .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload),
+ };
+ try dwarf.genLocalDebugInfo(
+ switch (air_inst.tag) {
else => unreachable,
- .pseudo_dbg_local_a => .{ mir_inst.data.a.air_inst, .empty },
- .pseudo_dbg_local_ai_s,
- .pseudo_dbg_local_ai_u,
- .pseudo_dbg_local_ai_64,
- => .{ mir_inst.data.ai.air_inst, .{ .stack_value = stack_value: {
- loc_buf[0] = switch (emit.lower.imm(mir_inst.ops, mir_inst.data.ai.i)) {
- .signed => |s| .{ .consts = s },
- .unsigned => |u| .{ .constu = u },
- };
- break :stack_value &loc_buf[0];
- } } },
- .pseudo_dbg_local_as => .{ mir_inst.data.as.air_inst, .{ .addr = .{
- .sym = mir_inst.data.as.sym_index,
- } } },
- .pseudo_dbg_local_aso => loc: {
- const sym_off = emit.lower.mir.extraData(
- bits.SymbolOffset,
- mir_inst.data.ax.payload,
- ).data;
- break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
- sym: {
- loc_buf[0] = .{ .addr = .{ .sym = sym_off.sym_index } };
- break :sym &loc_buf[0];
- },
- off: {
- loc_buf[1] = .{ .consts = sym_off.off };
- break :off &loc_buf[1];
- },
- } } };
- },
- .pseudo_dbg_local_aro => loc: {
- const air_off = emit.lower.mir.extraData(
- Mir.AirOffset,
- mir_inst.data.rx.payload,
- ).data;
- break :loc .{ air_off.air_inst, .{ .plus = .{
- reg: {
- loc_buf[0] = .{ .breg = mir_inst.data.rx.r1.dwarfNum() };
- break :reg &loc_buf[0];
- },
- off: {
- loc_buf[1] = .{ .consts = air_off.off };
- break :off &loc_buf[1];
- },
- } } };
- },
- .pseudo_dbg_local_af => loc: {
- const reg_off = emit.lower.mir.resolveFrameAddr(emit.lower.mir.extraData(
- bits.FrameAddr,
- mir_inst.data.ax.payload,
- ).data);
- break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
- reg: {
- loc_buf[0] = .{ .breg = reg_off.reg.dwarfNum() };
- break :reg &loc_buf[0];
- },
- off: {
- loc_buf[1] = .{ .consts = reg_off.off };
- break :off &loc_buf[1];
- },
- } } };
- },
- .pseudo_dbg_local_am => loc: {
- const mem = emit.lower.mem(mir_inst.data.ax.payload);
- break :loc .{ mir_inst.data.ax.air_inst, .{ .plus = .{
- base: {
- loc_buf[0] = switch (mem.base()) {
- .none => .{ .constu = 0 },
- .reg => |reg| .{ .breg = reg.dwarfNum() },
- .frame => unreachable,
- .reloc => |sym_index| .{ .addr = .{ .sym = sym_index } },
- };
- break :base &loc_buf[0];
- },
- disp: {
- loc_buf[1] = switch (mem.disp()) {
- .signed => |s| .{ .consts = s },
- .unsigned => |u| .{ .constu = u },
- };
- break :disp &loc_buf[1];
- },
- } } };
- },
- };
- const ip = &emit.lower.bin_file.comp.zcu.?.intern_pool;
- const air_inst = emit.air.instructions.get(@intFromEnum(air_inst_index));
- const name: Air.NullTerminatedString = switch (air_inst.tag) {
+ .arg, .dbg_arg_inline => .local_arg,
+ .dbg_var_ptr, .dbg_var_val => .local_var,
+ },
+ name.toSlice(emit.air),
+ switch (air_inst.tag) {
else => unreachable,
- .arg => air_inst.data.arg.name,
- .dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => @enumFromInt(air_inst.data.pl_op.payload),
- };
- try dw.genLocalDebugInfo(
- switch (air_inst.tag) {
- else => unreachable,
- .arg, .dbg_arg_inline => .local_arg,
- .dbg_var_ptr, .dbg_var_val => .local_var,
- },
- name.toSlice(emit.air),
- switch (air_inst.tag) {
- else => unreachable,
- .arg => emit.air.typeOfIndex(air_inst_index, ip),
- .dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip),
- .dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip),
- },
- loc,
- );
- },
- .plan9 => {},
- .none => {},
- }
+ .arg => emit.air.typeOfIndex(air_inst_index, ip),
+ .dbg_var_ptr => emit.air.typeOf(air_inst.data.pl_op.operand, ip).childTypeIp(ip),
+ .dbg_var_val, .dbg_arg_inline => emit.air.typeOf(air_inst.data.pl_op.operand, ip),
+ },
+ loc,
+ );
+ },
+ .plan9 => {},
+ .none => {},
},
- .pseudo_dbg_var_args_none => {
- switch (emit.debug_output) {
- .dwarf => |dw| try dw.genVarArgsDebugInfo(),
- .plan9 => {},
- .none => {},
- }
+ .pseudo_dbg_var_args_none => switch (emit.debug_output) {
+ .dwarf => |dwarf| try dwarf.genVarArgsDebugInfo(),
+ .plan9 => {},
+ .none => {},
},
.pseudo_dead_none => {},
},
@@ -515,16 +504,22 @@ fn fixupRelocs(emit: *Emit) Error!void {
}
}
-fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
- const delta_line = @as(i33, line) - @as(i33, emit.prev_di_line);
+const Loc = struct {
+ line: u32,
+ column: u32,
+ is_stmt: bool,
+};
+
+fn dbgAdvancePCAndLine(emit: *Emit, loc: Loc) Error!void {
+ const delta_line = @as(i33, loc.line) - @as(i33, emit.prev_di_loc.line);
const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
switch (emit.debug_output) {
- .dwarf => |dw| {
- if (column != emit.prev_di_column) try dw.setColumn(column);
- try dw.advancePCAndLine(delta_line, delta_pc);
- emit.prev_di_line = line;
- emit.prev_di_column = column;
+ .dwarf => |dwarf| {
+ if (loc.is_stmt != emit.prev_di_loc.is_stmt) try dwarf.negateStmt();
+ if (loc.column != emit.prev_di_loc.column) try dwarf.setColumn(loc.column);
+ try dwarf.advancePCAndLine(delta_line, delta_pc);
+ emit.prev_di_loc = loc;
emit.prev_di_pc = emit.code.items.len;
},
.plan9 => |dbg_out| {
@@ -553,11 +548,10 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
// we don't need to do anything, because adding the pc quanta does it for us
} else unreachable;
if (dbg_out.start_line == null)
- dbg_out.start_line = emit.prev_di_line;
- dbg_out.end_line = line;
+ dbg_out.start_line = emit.prev_di_loc.line;
+ dbg_out.end_line = loc.line;
// only do this if the pc changed
- emit.prev_di_line = line;
- emit.prev_di_column = column;
+ emit.prev_di_loc = loc;
emit.prev_di_pc = emit.code.items.len;
},
.none => {},
src/arch/x86_64/Lower.zig
@@ -310,6 +310,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
}),
.pseudo_dbg_prologue_end_none,
+ .pseudo_dbg_line_stmt_line_column,
.pseudo_dbg_line_line_column,
.pseudo_dbg_epilogue_begin_none,
.pseudo_dbg_enter_block_none,
src/arch/x86_64/Mir.zig
@@ -930,7 +930,10 @@ pub const Inst = struct {
/// End of prologue
pseudo_dbg_prologue_end_none,
- /// Update debug line
+ /// Update debug line with is_stmt register set
+ /// Uses `line_column` payload.
+ pseudo_dbg_line_stmt_line_column,
+ /// Update debug line with is_stmt register clear
/// Uses `line_column` payload.
pseudo_dbg_line_line_column,
/// Start of epilogue
src/codegen/c.zig
@@ -3289,6 +3289,7 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail,
.try_ptr_cold => try airTryPtr(f, inst),
.dbg_stmt => try airDbgStmt(f, inst),
+ .dbg_empty_stmt => try airDbgEmptyStmt(f, inst),
.dbg_var_ptr, .dbg_var_val, .dbg_arg_inline => try airDbgVar(f, inst),
.float_from_int,
@@ -4601,6 +4602,11 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
return .none;
}
+fn airDbgEmptyStmt(f: *Function, _: Air.Inst.Index) !CValue {
+ try f.object.writer().writeAll("(void)0;\n");
+ return .none;
+}
+
fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
const pt = f.object.dg.pt;
const zcu = pt.zcu;
src/codegen/llvm.zig
@@ -5391,6 +5391,7 @@ pub const FuncGen = struct {
.inferred_alloc, .inferred_alloc_comptime => unreachable,
.dbg_stmt => try self.airDbgStmt(inst),
+ .dbg_empty_stmt => try self.airDbgEmptyStmt(inst),
.dbg_var_ptr => try self.airDbgVarPtr(inst),
.dbg_var_val => try self.airDbgVarVal(inst, false),
.dbg_arg_inline => try self.airDbgVarVal(inst, true),
@@ -7433,6 +7434,12 @@ pub const FuncGen = struct {
return .none;
}
+ fn airDbgEmptyStmt(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
+ _ = self;
+ _ = inst;
+ return .none;
+ }
+
fn airDbgInlineBlock(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl;
const extra = self.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
src/link/Elf/ZigObject.zig
@@ -1496,7 +1496,7 @@ pub fn updateFunc(
});
defer gpa.free(name);
const osec = if (self.text_index) |sect_sym_index|
- self.symbol(sect_sym_index).output_section_index
+ self.symbol(sect_sym_index).outputShndx(elf_file).?
else osec: {
const osec = try elf_file.addSection(.{
.name = try elf_file.insertShString(".text"),
src/link/Dwarf.zig
@@ -1474,6 +1474,11 @@ pub const WipNav = struct {
try uleb128(dlw, column + 1);
}
+ pub fn negateStmt(wip_nav: *WipNav) error{OutOfMemory}!void {
+ const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
+ try dlw.writeByte(DW.LNS.negate_stmt);
+ }
+
pub fn setPrologueEnd(wip_nav: *WipNav) error{OutOfMemory}!void {
const dlw = wip_nav.debug_line.writer(wip_nav.dwarf.gpa);
try dlw.writeByte(DW.LNS.set_prologue_end);
src/Liveness/Verify.zig
@@ -56,6 +56,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
.ret_ptr,
.breakpoint,
.dbg_stmt,
+ .dbg_empty_stmt,
.ret_addr,
.frame_addr,
.wasm_memory_size,
src/Air.zig
@@ -460,6 +460,8 @@ pub const Inst = struct {
/// Result type is always void.
/// Uses the `dbg_stmt` field.
dbg_stmt,
+ /// Marks a statement that can be stepped to but produces no code.
+ dbg_empty_stmt,
/// A block that represents an inlined function call.
/// Uses the `ty_pl` field. Payload is `DbgInlineBlock`.
dbg_inline_block,
@@ -1468,6 +1470,7 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool)
.breakpoint,
.dbg_stmt,
+ .dbg_empty_stmt,
.dbg_var_ptr,
.dbg_var_val,
.dbg_arg_inline,
@@ -1629,6 +1632,7 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool {
.try_ptr,
.try_ptr_cold,
.dbg_stmt,
+ .dbg_empty_stmt,
.dbg_inline_block,
.dbg_var_ptr,
.dbg_var_val,
src/dev.zig
@@ -81,6 +81,7 @@ pub const Env = enum {
=> true,
.cc_command,
.translate_c_command,
+ .fmt_command,
.jit_command,
.fetch_command,
.init_command,
@@ -168,6 +169,7 @@ pub const Feature = enum {
clang_command,
cc_command,
translate_c_command,
+ fmt_command,
jit_command,
fetch_command,
init_command,
src/Liveness.zig
@@ -334,6 +334,7 @@ pub fn categorizeOperand(
.repeat,
.switch_dispatch,
.dbg_stmt,
+ .dbg_empty_stmt,
.unreach,
.ret_addr,
.frame_addr,
@@ -973,6 +974,7 @@ fn analyzeInst(
.ret_ptr,
.breakpoint,
.dbg_stmt,
+ .dbg_empty_stmt,
.ret_addr,
.frame_addr,
.wasm_memory_size,
src/main.zig
@@ -309,6 +309,7 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
.server = use_server,
});
} else if (mem.eql(u8, cmd, "fmt")) {
+ dev.check(.fmt_command);
return @import("fmt.zig").run(gpa, arena, cmd_args);
} else if (mem.eql(u8, cmd, "objcopy")) {
return jitCmd(gpa, arena, cmd_args, .{
src/print_air.zig
@@ -202,6 +202,7 @@ const Writer = struct {
.trap,
.breakpoint,
+ .dbg_empty_stmt,
.unreach,
.ret_addr,
.frame_addr,
src/print_zir.zig
@@ -621,6 +621,8 @@ const Writer = struct {
.field_parent_ptr => try self.writeFieldParentPtr(stream, extended),
.builtin_value => try self.writeBuiltinValue(stream, extended),
.inplace_arith_result_ty => try self.writeInplaceArithResultTy(stream, extended),
+
+ .dbg_empty_stmt => try stream.writeAll("))"),
}
}
src/Sema.zig
@@ -1355,6 +1355,11 @@ fn analyzeBodyInner(
.field_parent_ptr => try sema.zirFieldParentPtr(block, extended),
.builtin_value => try sema.zirBuiltinValue(block, extended),
.inplace_arith_result_ty => try sema.zirInplaceArithResultTy(extended),
+ .dbg_empty_stmt => {
+ try sema.zirDbgEmptyStmt(block, inst);
+ i += 1;
+ continue;
+ },
};
},
@@ -6671,6 +6676,11 @@ fn zirDbgStmt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!voi
});
}
+fn zirDbgEmptyStmt(_: *Sema, block: *Block, _: Zir.Inst.Index) CompileError!void {
+ if (block.is_comptime or block.ownerModule().strip) return;
+ _ = try block.addNoOp(.dbg_empty_stmt);
+}
+
fn zirDbgVar(
sema: *Sema,
block: *Block,
test/src/Debugger.zig
@@ -808,6 +808,424 @@ pub fn addTestsForTarget(db: *Debugger, target: Target) void {
\\1 breakpoints deleted; 0 breakpoint locations disabled.
},
);
+ db.addLldbTest(
+ "step_single_stmt_loops",
+ target,
+ &.{
+ .{
+ .path = "step_single_stmt_loops.zig",
+ .source =
+ \\pub fn main() void {
+ \\ var x: u32 = 0;
+ \\ for (0..3) |_| {
+ \\ x +%= 1;
+ \\ }
+ \\ {
+ \\ var i: u32 = 0;
+ \\ while (i < 3) : (i +%= 1) {
+ \\ x +%= 1;
+ \\ }
+ \\ }
+ \\ {
+ \\ var i: u32 = 0;
+ \\ while (i < 3) {
+ \\ i +%= 1;
+ \\ }
+ \\ }
+ \\ inline for (0..3) |_| {
+ \\ x +%= 1;
+ \\ }
+ \\ {
+ \\ comptime var i: u32 = 0;
+ \\ inline while (i < 3) : (i +%= 1) {
+ \\ x +%= 1;
+ \\ }
+ \\ }
+ \\ {
+ \\ comptime var i: u32 = 0;
+ \\ inline while (i < 3) {
+ \\ i +%= 1;
+ \\ }
+ \\ }
+ \\ x +%= 1;
+ \\}
+ \\
+ ,
+ },
+ },
+ \\breakpoint set --name step_single_stmt_loops.main
+ \\process launch
+ \\thread step-in
+ \\#00
+ \\frame variable x
+ \\thread step-in
+ \\#01
+ \\frame variable x
+ \\thread step-in
+ \\#02
+ \\frame variable x
+ \\thread step-in
+ \\#03
+ \\frame variable x
+ \\thread step-in
+ \\#04
+ \\frame variable x
+ \\thread step-in
+ \\#05
+ \\frame variable x
+ \\thread step-in
+ \\#06
+ \\frame variable x
+ \\thread step-in
+ \\#07
+ \\frame variable x
+ \\thread step-in
+ \\#08
+ \\frame variable x
+ \\thread step-in
+ \\#09
+ \\frame variable x
+ \\thread step-in
+ \\#10
+ \\frame variable x
+ \\thread step-in
+ \\#11
+ \\frame variable x
+ \\thread step-in
+ \\#12
+ \\frame variable x
+ \\thread step-in
+ \\#13
+ \\frame variable x
+ \\thread step-in
+ \\#14
+ \\frame variable x
+ \\thread step-in
+ \\#15
+ \\frame variable x
+ \\thread step-in
+ \\#16
+ \\frame variable x
+ \\thread step-in
+ \\#17
+ \\frame variable x
+ \\thread step-in
+ \\#18
+ \\frame variable x
+ \\thread step-in
+ \\#19
+ \\frame variable x
+ \\thread step-in
+ \\#20
+ \\frame variable x
+ \\thread step-in
+ \\#21
+ \\frame variable x
+ \\thread step-in
+ \\#22
+ \\frame variable x
+ \\thread step-in
+ \\#23
+ \\frame variable x
+ \\thread step-in
+ \\#24
+ \\frame variable x
+ \\thread step-in
+ \\#25
+ \\frame variable x
+ \\thread step-in
+ \\#26
+ \\frame variable x
+ \\thread step-in
+ \\#27
+ \\frame variable x
+ \\thread step-in
+ \\#28
+ \\frame variable x
+ \\thread step-in
+ \\#29
+ \\frame variable x
+ \\thread step-in
+ \\#30
+ \\frame variable x
+ \\thread step-in
+ \\#31
+ \\frame variable x
+ \\thread step-in
+ \\#32
+ \\frame variable x
+ \\thread step-in
+ \\#33
+ \\frame variable x
+ \\thread step-in
+ \\#34
+ \\frame variable x
+ \\thread step-in
+ \\#35
+ \\frame variable x
+ \\thread step-in
+ \\#36
+ \\frame variable x
+ \\thread step-in
+ \\#37
+ \\frame variable x
+ \\thread step-in
+ \\#38
+ \\frame variable x
+ \\thread step-in
+ \\#39
+ \\frame variable x
+ \\thread step-in
+ \\#40
+ \\frame variable x
+ \\thread step-in
+ \\#41
+ \\frame variable x
+ \\thread step-in
+ \\#42
+ \\frame variable x
+ \\thread step-in
+ \\#43
+ \\frame variable x
+ \\thread step-in
+ \\#44
+ \\frame variable x
+ \\thread step-in
+ \\#45
+ \\frame variable x
+ \\
+ ,
+ &.{
+ \\(lldb) #00
+ \\(lldb) frame variable x
+ \\(u32) x = 0
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #01
+ \\(lldb) frame variable x
+ \\(u32) x = 0
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #02
+ \\(lldb) frame variable x
+ \\(u32) x = 1
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #03
+ \\(lldb) frame variable x
+ \\(u32) x = 1
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #04
+ \\(lldb) frame variable x
+ \\(u32) x = 1
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #05
+ \\(lldb) frame variable x
+ \\(u32) x = 2
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #06
+ \\(lldb) frame variable x
+ \\(u32) x = 2
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #07
+ \\(lldb) frame variable x
+ \\(u32) x = 2
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #08
+ \\(lldb) frame variable x
+ \\(u32) x = 3
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #09
+ \\(lldb) frame variable x
+ \\(u32) x = 3
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #10
+ \\(lldb) frame variable x
+ \\(u32) x = 3
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #11
+ \\(lldb) frame variable x
+ \\(u32) x = 3
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #12
+ \\(lldb) frame variable x
+ \\(u32) x = 3
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #13
+ \\(lldb) frame variable x
+ \\(u32) x = 4
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #14
+ \\(lldb) frame variable x
+ \\(u32) x = 4
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #15
+ \\(lldb) frame variable x
+ \\(u32) x = 4
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #16
+ \\(lldb) frame variable x
+ \\(u32) x = 5
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #17
+ \\(lldb) frame variable x
+ \\(u32) x = 5
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #18
+ \\(lldb) frame variable x
+ \\(u32) x = 5
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #19
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #20
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #21
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #22
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #23
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #24
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #25
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #26
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #27
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #28
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #29
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #30
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #31
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #32
+ \\(lldb) frame variable x
+ \\(u32) x = 6
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #33
+ \\(lldb) frame variable x
+ \\(u32) x = 7
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #34
+ \\(lldb) frame variable x
+ \\(u32) x = 7
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #35
+ \\(lldb) frame variable x
+ \\(u32) x = 8
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #36
+ \\(lldb) frame variable x
+ \\(u32) x = 8
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #37
+ \\(lldb) frame variable x
+ \\(u32) x = 9
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #38
+ \\(lldb) frame variable x
+ \\(u32) x = 9
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #39
+ \\(lldb) frame variable x
+ \\(u32) x = 10
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #40
+ \\(lldb) frame variable x
+ \\(u32) x = 10
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #41
+ \\(lldb) frame variable x
+ \\(u32) x = 11
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #42
+ \\(lldb) frame variable x
+ \\(u32) x = 11
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #43
+ \\(lldb) frame variable x
+ \\(u32) x = 12
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #44
+ \\(lldb) frame variable x
+ \\(u32) x = 12
+ \\(lldb) thread step-in
+ ,
+ \\(lldb) #45
+ \\(lldb) frame variable x
+ \\(u32) x = 12
+ },
+ );
db.addLldbTest(
"inline_call",
target,