diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index abec1f354a..a9b518357b 100644 --- a/lib/std/zig/AstGen.zig +++ b/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; diff --git a/lib/std/zig/Zir.zig b/lib/std/zig/Zir.zig index 00a48e21f7..f2c103f835 100644 --- a/lib/std/zig/Zir.zig +++ b/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. diff --git a/src/Air.zig b/src/Air.zig index 3aa5f317c0..4589bb1557 100644 --- a/src/Air.zig +++ b/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, diff --git a/src/Air/types_resolved.zig b/src/Air/types_resolved.zig index 098cb29b22..cc866184e4 100644 --- a/src/Air/types_resolved.zig +++ b/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, diff --git a/src/Liveness.zig b/src/Liveness.zig index b5bffc6a48..709844c0ac 100644 --- a/src/Liveness.zig +++ b/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, diff --git a/src/Liveness/Verify.zig b/src/Liveness/Verify.zig index aa2239793a..01e0842ded 100644 --- a/src/Liveness/Verify.zig +++ b/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, diff --git a/src/Sema.zig b/src/Sema.zig index 25fb54dab8..5acd2012d5 100644 --- a/src/Sema.zig +++ b/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, diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 6371cf92f3..8fd27d4bb7 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/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, diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 9966648759..065f4a047d 100644 --- a/src/arch/arm/CodeGen.zig +++ b/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, diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 24497defa2..29a0a8b8b5 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/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), diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index a1bef1f4cd..7bbed29d8f 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/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, diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 50a8869282..ccdf38a474 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/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), diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 06ae399f25..298b2e11e0 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/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); diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig index 0395b7a43b..f744eb3fc4 100644 --- a/src/arch/x86_64/Emit.zig +++ b/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 => {}, diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig index 6ac79378c1..015b3ba12e 100644 --- a/src/arch/x86_64/Lower.zig +++ b/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, diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig index 0e9d010758..a7f308b7b4 100644 --- a/src/arch/x86_64/Mir.zig +++ b/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 diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 0410023588..56466b4395 100644 --- a/src/codegen/c.zig +++ b/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; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index fb20d4d622..d0b12350c0 100644 --- a/src/codegen/llvm.zig +++ b/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); diff --git a/src/dev.zig b/src/dev.zig index 0d365c3e19..d623a708e7 100644 --- a/src/dev.zig +++ b/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, diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 6653a8309a..afdc5d1d48 100644 --- a/src/link/Dwarf.zig +++ b/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); diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 1e29ab8bf6..effe12539c 100644 --- a/src/link/Elf/ZigObject.zig +++ b/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"), diff --git a/src/main.zig b/src/main.zig index 291820cb75..13e24d8c25 100644 --- a/src/main.zig +++ b/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, .{ diff --git a/src/print_air.zig b/src/print_air.zig index 6a3f31a27c..280d05edfa 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -202,6 +202,7 @@ const Writer = struct { .trap, .breakpoint, + .dbg_empty_stmt, .unreach, .ret_addr, .frame_addr, diff --git a/src/print_zir.zig b/src/print_zir.zig index b8f4432e72..808ead0e79 100644 --- a/src/print_zir.zig +++ b/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("))"), } } diff --git a/test/src/Debugger.zig b/test/src/Debugger.zig index b4b453700d..1e2289eb11 100644 --- a/test/src/Debugger.zig +++ b/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,