| author | |
| committer | |
| log | d83a26f068f42c6f9cafd25b7038b70553a496d8 |
| tree | 016bc2d9fa343ceac3a1b1f0fd6971dde706a1e4 |
| parent | 03438118369605df178f4bfdb5b1a8ad6a349be7 |
14 files changed, 132 insertions(+), 46 deletions(-)
src/Air.zig+7-3| ... | ... | @@ -326,9 +326,12 @@ pub const Inst = struct { |
| 326 | 326 | /// Result type is always void. |
| 327 | 327 | /// Uses the `dbg_stmt` field. |
| 328 | 328 | dbg_stmt, |
| 329 | /// Marks change of source function. Emitted around an inline call. | |
| 329 | /// Marks the start of an inline call. | |
| 330 | 330 | /// Uses `ty_pl` with the payload being the index of a Value.Function in air.values. |
| 331 | dbg_func, | |
| 331 | dbg_inline_begin, | |
| 332 | /// Marks the end of an inline call. | |
| 333 | /// Uses `ty_pl` with the payload being the index of a Value.Function in air.values. | |
| 334 | dbg_inline_end, | |
| 332 | 335 | /// Marks the beginning of a local variable. The operand is a pointer pointing |
| 333 | 336 | /// to the storage for the variable. The local may be a const or a var. |
| 334 | 337 | /// Result type is always void. |
| ... | ... | @@ -973,7 +976,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 973 | 976 | |
| 974 | 977 | .breakpoint, |
| 975 | 978 | .dbg_stmt, |
| 976 | .dbg_func, | |
| 979 | .dbg_inline_begin, | |
| 980 | .dbg_inline_end, | |
| 977 | 981 | .dbg_var_ptr, |
| 978 | 982 | .dbg_var_val, |
| 979 | 983 | .store, |
src/Liveness.zig+2-1| ... | ... | @@ -314,7 +314,8 @@ fn analyzeInst( |
| 314 | 314 | .const_ty, |
| 315 | 315 | .breakpoint, |
| 316 | 316 | .dbg_stmt, |
| 317 | .dbg_func, | |
| 317 | .dbg_inline_begin, | |
| 318 | .dbg_inline_end, | |
| 318 | 319 | .unreach, |
| 319 | 320 | .fence, |
| 320 | 321 | .ret_addr, |
src/Sema.zig+10-5| ... | ... | @@ -4765,7 +4765,9 @@ fn analyzeCall( |
| 4765 | 4765 | } |
| 4766 | 4766 | |
| 4767 | 4767 | const new_func_resolved_ty = try Type.Tag.function.create(sema.arena, new_fn_info); |
| 4768 | if (!is_comptime_call) try sema.emitDbgFunc(block, parent_func.?, module_fn, new_func_resolved_ty); | |
| 4768 | if (!is_comptime_call) { | |
| 4769 | try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin); | |
| 4770 | } | |
| 4769 | 4771 | |
| 4770 | 4772 | const result = result: { |
| 4771 | 4773 | sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) { |
| ... | ... | @@ -4781,7 +4783,9 @@ fn analyzeCall( |
| 4781 | 4783 | break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges); |
| 4782 | 4784 | }; |
| 4783 | 4785 | |
| 4784 | if (!is_comptime_call) try sema.emitDbgFunc(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty); | |
| 4786 | if (!is_comptime_call) { | |
| 4787 | try sema.emitDbgInline(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty, .dbg_inline_end); | |
| 4788 | } | |
| 4785 | 4789 | |
| 4786 | 4790 | if (should_memoize and is_comptime_call) { |
| 4787 | 4791 | const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result); |
| ... | ... | @@ -5187,19 +5191,20 @@ fn instantiateGenericCall( |
| 5187 | 5191 | return func_inst; |
| 5188 | 5192 | } |
| 5189 | 5193 | |
| 5190 | fn emitDbgFunc( | |
| 5194 | fn emitDbgInline( | |
| 5191 | 5195 | sema: *Sema, |
| 5192 | 5196 | block: *Block, |
| 5193 | 5197 | old_func: *Module.Fn, |
| 5194 | 5198 | new_func: *Module.Fn, |
| 5195 | 5199 | new_func_ty: Type, |
| 5200 | tag: Air.Inst.Tag, | |
| 5196 | 5201 | ) CompileError!void { |
| 5197 | // No change of file; no dbg_func needed. | |
| 5202 | // No change of file; no dbg_inline needed. | |
| 5198 | 5203 | if (old_func == new_func) return; |
| 5199 | 5204 | |
| 5200 | 5205 | try sema.air_values.append(sema.gpa, try Value.Tag.function.create(sema.arena, new_func)); |
| 5201 | 5206 | _ = try block.addInst(.{ |
| 5202 | .tag = .dbg_func, | |
| 5207 | .tag = tag, | |
| 5203 | 5208 | .data = .{ .ty_pl = .{ |
| 5204 | 5209 | .ty = try sema.addType(new_func_ty), |
| 5205 | 5210 | .payload = @intCast(u32, sema.air_values.items.len - 1), |
src/arch/aarch64/CodeGen.zig+5-2| ... | ... | @@ -598,7 +598,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 598 | 598 | .fence => try self.airFence(), |
| 599 | 599 | .cond_br => try self.airCondBr(inst), |
| 600 | 600 | .dbg_stmt => try self.airDbgStmt(inst), |
| 601 | .dbg_func => try self.airDbgFunc(inst), | |
| 602 | 601 | .fptrunc => try self.airFptrunc(inst), |
| 603 | 602 | .fpext => try self.airFpext(inst), |
| 604 | 603 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -650,6 +649,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 650 | 649 | .dbg_var_val, |
| 651 | 650 | => try self.airDbgVar(inst), |
| 652 | 651 | |
| 652 | .dbg_inline_begin, | |
| 653 | .dbg_inline_end, | |
| 654 | => try self.airDbgInline(inst), | |
| 655 | ||
| 653 | 656 | .call => try self.airCall(inst, .auto), |
| 654 | 657 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 655 | 658 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -2716,7 +2719,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 2716 | 2719 | return self.finishAirBookkeeping(); |
| 2717 | 2720 | } |
| 2718 | 2721 | |
| 2719 | fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void { | |
| 2722 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 2720 | 2723 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 2721 | 2724 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; |
| 2722 | 2725 | // TODO emit debug info for function change |
src/arch/arm/CodeGen.zig+5-2| ... | ... | @@ -595,7 +595,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 595 | 595 | .fence => try self.airFence(), |
| 596 | 596 | .cond_br => try self.airCondBr(inst), |
| 597 | 597 | .dbg_stmt => try self.airDbgStmt(inst), |
| 598 | .dbg_func => try self.airDbgFunc(inst), | |
| 599 | 598 | .fptrunc => try self.airFptrunc(inst), |
| 600 | 599 | .fpext => try self.airFpext(inst), |
| 601 | 600 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -647,6 +646,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 647 | 646 | .dbg_var_val, |
| 648 | 647 | => try self.airDbgVar(inst), |
| 649 | 648 | |
| 649 | .dbg_inline_begin, | |
| 650 | .dbg_inline_end, | |
| 651 | => try self.airDbgInline(inst), | |
| 652 | ||
| 650 | 653 | .call => try self.airCall(inst, .auto), |
| 651 | 654 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 652 | 655 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -2836,7 +2839,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 2836 | 2839 | return self.finishAirBookkeeping(); |
| 2837 | 2840 | } |
| 2838 | 2841 | |
| 2839 | fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void { | |
| 2842 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 2840 | 2843 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 2841 | 2844 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; |
| 2842 | 2845 | // TODO emit debug info for function change |
src/arch/riscv64/CodeGen.zig+5-2| ... | ... | @@ -562,7 +562,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 562 | 562 | .fence => try self.airFence(), |
| 563 | 563 | .cond_br => try self.airCondBr(inst), |
| 564 | 564 | .dbg_stmt => try self.airDbgStmt(inst), |
| 565 | .dbg_func => try self.airDbgFunc(inst), | |
| 566 | 565 | .fptrunc => try self.airFptrunc(inst), |
| 567 | 566 | .fpext => try self.airFpext(inst), |
| 568 | 567 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -614,6 +613,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 614 | 613 | .dbg_var_val, |
| 615 | 614 | => try self.airDbgVar(inst), |
| 616 | 615 | |
| 616 | .dbg_inline_begin, | |
| 617 | .dbg_inline_end, | |
| 618 | => try self.airDbgInline(inst), | |
| 619 | ||
| 617 | 620 | .call => try self.airCall(inst, .auto), |
| 618 | 621 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 619 | 622 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -1641,7 +1644,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 1641 | 1644 | return self.finishAirBookkeeping(); |
| 1642 | 1645 | } |
| 1643 | 1646 | |
| 1644 | fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void { | |
| 1647 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 1645 | 1648 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 1646 | 1649 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; |
| 1647 | 1650 | // TODO emit debug info for function change |
src/arch/wasm/CodeGen.zig+2-1| ... | ... | @@ -1227,7 +1227,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1227 | 1227 | |
| 1228 | 1228 | // TODO |
| 1229 | 1229 | .dbg_stmt, |
| 1230 | .dbg_func, | |
| 1230 | .dbg_inline_begin, | |
| 1231 | .dbg_inline_end, | |
| 1231 | 1232 | .dbg_var_ptr, |
| 1232 | 1233 | .dbg_var_val, |
| 1233 | 1234 | => WValue.none, |
src/arch/x86_64/CodeGen.zig+5-2| ... | ... | @@ -679,7 +679,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 679 | 679 | .fence => try self.airFence(), |
| 680 | 680 | .cond_br => try self.airCondBr(inst), |
| 681 | 681 | .dbg_stmt => try self.airDbgStmt(inst), |
| 682 | .dbg_func => try self.airDbgFunc(inst), | |
| 683 | 682 | .fptrunc => try self.airFptrunc(inst), |
| 684 | 683 | .fpext => try self.airFpext(inst), |
| 685 | 684 | .intcast => try self.airIntCast(inst), |
| ... | ... | @@ -731,6 +730,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 731 | 730 | .dbg_var_val, |
| 732 | 731 | => try self.airDbgVar(inst), |
| 733 | 732 | |
| 733 | .dbg_inline_begin, | |
| 734 | .dbg_inline_end, | |
| 735 | => try self.airDbgInline(inst), | |
| 736 | ||
| 734 | 737 | .call => try self.airCall(inst, .auto), |
| 735 | 738 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 736 | 739 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | ... | @@ -3671,7 +3674,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 3671 | 3674 | return self.finishAirBookkeeping(); |
| 3672 | 3675 | } |
| 3673 | 3676 | |
| 3674 | fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void { | |
| 3677 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | |
| 3675 | 3678 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 3676 | 3679 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; |
| 3677 | 3680 | // TODO emit debug info for function change |
src/codegen/c.zig+5-2| ... | ... | @@ -1687,7 +1687,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1687 | 1687 | .block => try airBlock(f, inst), |
| 1688 | 1688 | .bitcast => try airBitcast(f, inst), |
| 1689 | 1689 | .dbg_stmt => try airDbgStmt(f, inst), |
| 1690 | .dbg_func => try airDbgFunc(f, inst), | |
| 1691 | 1690 | .intcast => try airIntCast(f, inst), |
| 1692 | 1691 | .trunc => try airTrunc(f, inst), |
| 1693 | 1692 | .bool_to_int => try airBoolToInt(f, inst), |
| ... | ... | @@ -1727,6 +1726,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1727 | 1726 | .dbg_var_val, |
| 1728 | 1727 | => try airDbgVar(f, inst), |
| 1729 | 1728 | |
| 1729 | .dbg_inline_begin, | |
| 1730 | .dbg_inline_end, | |
| 1731 | => try airDbgInline(f, inst), | |
| 1732 | ||
| 1730 | 1733 | .call => try airCall(f, inst, .auto), |
| 1731 | 1734 | .call_always_tail => try airCall(f, inst, .always_tail), |
| 1732 | 1735 | .call_never_tail => try airCall(f, inst, .never_tail), |
| ... | ... | @@ -2661,7 +2664,7 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2661 | 2664 | return CValue.none; |
| 2662 | 2665 | } |
| 2663 | 2666 | |
| 2664 | fn airDbgFunc(f: *Function, inst: Air.Inst.Index) !CValue { | |
| 2667 | fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue { | |
| 2665 | 2668 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 2666 | 2669 | const writer = f.object.writer(); |
| 2667 | 2670 | const function = f.air.values[ty_pl.payload].castTag(.function).?.data; |
src/codegen/llvm.zig+58-20| ... | ... | @@ -620,7 +620,8 @@ pub const Object = struct { |
| 620 | 620 | |
| 621 | 621 | llvm_func.fnSetSubprogram(subprogram); |
| 622 | 622 | |
| 623 | di_scope = subprogram.toScope(); | |
| 623 | const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file.?, line_number, 1); | |
| 624 | di_scope = lexical_block.toScope(); | |
| 624 | 625 | } |
| 625 | 626 | |
| 626 | 627 | var fg: FuncGen = .{ |
| ... | ... | @@ -639,6 +640,7 @@ pub const Object = struct { |
| 639 | 640 | .single_threaded = module.comp.bin_file.options.single_threaded, |
| 640 | 641 | .di_scope = di_scope, |
| 641 | 642 | .di_file = di_file, |
| 643 | .base_line = dg.decl.src_line, | |
| 642 | 644 | .prev_dbg_line = 0, |
| 643 | 645 | .prev_dbg_column = 0, |
| 644 | 646 | }; |
| ... | ... | @@ -3210,9 +3212,13 @@ pub const FuncGen = struct { |
| 3210 | 3212 | builder: *const llvm.Builder, |
| 3211 | 3213 | di_scope: ?*llvm.DIScope, |
| 3212 | 3214 | di_file: ?*llvm.DIFile, |
| 3215 | base_line: u32, | |
| 3213 | 3216 | prev_dbg_line: c_uint, |
| 3214 | 3217 | prev_dbg_column: c_uint, |
| 3215 | 3218 | |
| 3219 | /// Stack of locations where a call was inlined. | |
| 3220 | dbg_inlined: std.ArrayListUnmanaged(DbgState) = .{}, | |
| 3221 | ||
| 3216 | 3222 | /// This stores the LLVM values used in a function, such that they can be referred to |
| 3217 | 3223 | /// in other instructions. This table is cleared before every function is generated. |
| 3218 | 3224 | func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value), |
| ... | ... | @@ -3240,11 +3246,13 @@ pub const FuncGen = struct { |
| 3240 | 3246 | |
| 3241 | 3247 | single_threaded: bool, |
| 3242 | 3248 | |
| 3249 | const DbgState = struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 }; | |
| 3243 | 3250 | const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock); |
| 3244 | 3251 | const BreakValues = std.ArrayListUnmanaged(*const llvm.Value); |
| 3245 | 3252 | |
| 3246 | 3253 | fn deinit(self: *FuncGen) void { |
| 3247 | 3254 | self.builder.dispose(); |
| 3255 | self.dbg_inlined.deinit(self.gpa); | |
| 3248 | 3256 | self.func_inst_table.deinit(self.gpa); |
| 3249 | 3257 | self.blocks.deinit(self.gpa); |
| 3250 | 3258 | } |
| ... | ... | @@ -3463,7 +3471,8 @@ pub const FuncGen = struct { |
| 3463 | 3471 | .const_ty => unreachable, |
| 3464 | 3472 | .unreach => self.airUnreach(inst), |
| 3465 | 3473 | .dbg_stmt => self.airDbgStmt(inst), |
| 3466 | .dbg_func => try self.airDbgFunc(inst), | |
| 3474 | .dbg_inline_begin => try self.airDbgInline(inst, true), | |
| 3475 | .dbg_inline_end => try self.airDbgInline(inst, false), | |
| 3467 | 3476 | .dbg_var_ptr => try self.airDbgVarPtr(inst), |
| 3468 | 3477 | .dbg_var_val => try self.airDbgVarVal(inst), |
| 3469 | 3478 | // zig fmt: on |
| ... | ... | @@ -4179,24 +4188,44 @@ pub const FuncGen = struct { |
| 4179 | 4188 | fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value { |
| 4180 | 4189 | const di_scope = self.di_scope orelse return null; |
| 4181 | 4190 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; |
| 4182 | self.prev_dbg_line = @intCast(c_uint, self.dg.decl.src_line + dbg_stmt.line + 1); | |
| 4191 | self.prev_dbg_line = @intCast(c_uint, self.base_line + dbg_stmt.line + 1); | |
| 4183 | 4192 | self.prev_dbg_column = @intCast(c_uint, dbg_stmt.column + 1); |
| 4184 | self.builder.setCurrentDebugLocation(self.prev_dbg_line, self.prev_dbg_column, di_scope); | |
| 4193 | const inlined_at = if (self.dbg_inlined.items.len > 0) | |
| 4194 | self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc | |
| 4195 | else | |
| 4196 | null; | |
| 4197 | self.builder.setCurrentDebugLocation(self.prev_dbg_line, self.prev_dbg_column, di_scope, inlined_at); | |
| 4185 | 4198 | return null; |
| 4186 | 4199 | } |
| 4187 | 4200 | |
| 4188 | fn airDbgFunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | |
| 4201 | fn airDbgInline(self: *FuncGen, inst: Air.Inst.Index, start: bool) !?*const llvm.Value { | |
| 4189 | 4202 | const dib = self.dg.object.di_builder orelse return null; |
| 4190 | 4203 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 4191 | ||
| 4192 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; | |
| 4193 | const decl = function.owner_decl; | |
| 4204 | ||
| 4205 | const func = self.air.values[ty_pl.payload].castTag(.function).?.data; | |
| 4206 | const decl = func.owner_decl; | |
| 4207 | const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope); | |
| 4208 | self.di_file = di_file; | |
| 4209 | const line_number = decl.src_line + 1; | |
| 4210 | const cur_debug_location = self.builder.getCurrentDebugLocation2(); | |
| 4211 | if (start) { | |
| 4212 | try self.dbg_inlined.append(self.gpa, .{ | |
| 4213 | .loc = @ptrCast(*llvm.DILocation, cur_debug_location), | |
| 4214 | .scope = self.di_scope.?, | |
| 4215 | .base_line = self.base_line, | |
| 4216 | }); | |
| 4217 | } else { | |
| 4218 | const old = self.dbg_inlined.pop(); | |
| 4219 | self.di_scope = old.scope; | |
| 4220 | self.base_line = old.base_line; | |
| 4221 | return null; | |
| 4222 | } | |
| 4223 | ||
| 4194 | 4224 | const fn_ty = try self.air.getRefType(ty_pl.ty).copy(self.dg.object.type_map_arena.allocator()); |
| 4195 | const llvm_func = try self.dg.resolveLlvmFunctionExtra(decl, fn_ty); | |
| 4225 | const fqn = try decl.getFullyQualifiedName(self.gpa); | |
| 4226 | defer self.gpa.free(fqn); | |
| 4196 | 4227 | const fn_info = fn_ty.fnInfo(); |
| 4197 | const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope); | |
| 4198 | 4228 | |
| 4199 | const line_number = decl.src_line + 1; | |
| 4200 | 4229 | const is_internal_linkage = !self.dg.module.decl_exports.contains(decl); |
| 4201 | 4230 | const noret_bit: c_uint = if (fn_info.return_type.isNoReturn()) |
| 4202 | 4231 | llvm.DIFlags.NoReturn |
| ... | ... | @@ -4205,22 +4234,23 @@ pub const FuncGen = struct { |
| 4205 | 4234 | const subprogram = dib.createFunction( |
| 4206 | 4235 | di_file.toScope(), |
| 4207 | 4236 | decl.name, |
| 4208 | llvm_func.getValueName(), | |
| 4237 | fqn, | |
| 4209 | 4238 | di_file, |
| 4210 | 4239 | line_number, |
| 4211 | try self.dg.lowerDebugType(fn_ty), | |
| 4240 | try self.dg.object.lowerDebugType(fn_ty, .full), | |
| 4212 | 4241 | is_internal_linkage, |
| 4213 | 4242 | true, // is definition |
| 4214 | line_number + function.lbrace_line, // scope line | |
| 4243 | line_number + func.lbrace_line, // scope line | |
| 4215 | 4244 | llvm.DIFlags.StaticMember | noret_bit, |
| 4216 | 4245 | self.dg.module.comp.bin_file.options.optimize_mode != .Debug, |
| 4217 | 4246 | null, // decl_subprogram |
| 4218 | 4247 | ); |
| 4219 | try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode()); | |
| 4220 | 4248 | |
| 4221 | llvm_func.fnSetSubprogram(subprogram); | |
| 4249 | try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode()); | |
| 4222 | 4250 | |
| 4223 | self.di_scope = subprogram.toScope(); | |
| 4251 | const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file, line_number, 1); | |
| 4252 | self.di_scope = lexical_block.toScope(); | |
| 4253 | self.base_line = decl.src_line; | |
| 4224 | 4254 | return null; |
| 4225 | 4255 | } |
| 4226 | 4256 | |
| ... | ... | @@ -4240,7 +4270,11 @@ pub const FuncGen = struct { |
| 4240 | 4270 | true, // always preserve |
| 4241 | 4271 | 0, // flags |
| 4242 | 4272 | ); |
| 4243 | const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?); | |
| 4273 | const inlined_at = if (self.dbg_inlined.items.len > 0) | |
| 4274 | self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc | |
| 4275 | else | |
| 4276 | null; | |
| 4277 | const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at); | |
| 4244 | 4278 | const insert_block = self.builder.getInsertBlock(); |
| 4245 | 4279 | _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block); |
| 4246 | 4280 | return null; |
| ... | ... | @@ -4262,7 +4296,11 @@ pub const FuncGen = struct { |
| 4262 | 4296 | true, // always preserve |
| 4263 | 4297 | 0, // flags |
| 4264 | 4298 | ); |
| 4265 | const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?); | |
| 4299 | const inlined_at = if (self.dbg_inlined.items.len > 0) | |
| 4300 | self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc | |
| 4301 | else | |
| 4302 | null; | |
| 4303 | const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at); | |
| 4266 | 4304 | const insert_block = self.builder.getInsertBlock(); |
| 4267 | 4305 | if (isByRef(operand_ty)) { |
| 4268 | 4306 | _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block); |
| ... | ... | @@ -5524,7 +5562,7 @@ pub const FuncGen = struct { |
| 5524 | 5562 | self.arg_index, // includes +1 because 0 is return type |
| 5525 | 5563 | ); |
| 5526 | 5564 | |
| 5527 | const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?); | |
| 5565 | const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null); | |
| 5528 | 5566 | const insert_block = self.builder.getInsertBlock(); |
| 5529 | 5567 | if (isByRef(inst_ty)) { |
| 5530 | 5568 | _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block); |
src/codegen/llvm/bindings.zig+4-4| ... | ... | @@ -839,8 +839,8 @@ pub const Builder = opaque { |
| 839 | 839 | pub const buildExactSDiv = LLVMBuildExactSDiv; |
| 840 | 840 | extern fn LLVMBuildExactSDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value; |
| 841 | 841 | |
| 842 | pub const setCurrentDebugLocation = ZigLLVMSetCurrentDebugLocation; | |
| 843 | extern fn ZigLLVMSetCurrentDebugLocation(builder: *const Builder, line: c_uint, column: c_uint, scope: *DIScope) void; | |
| 842 | pub const setCurrentDebugLocation = ZigLLVMSetCurrentDebugLocation2; | |
| 843 | extern fn ZigLLVMSetCurrentDebugLocation2(builder: *const Builder, line: c_uint, column: c_uint, scope: *DIScope, inlined_at: ?*DILocation) void; | |
| 844 | 844 | |
| 845 | 845 | pub const clearCurrentDebugLocation = ZigLLVMClearCurrentDebugLocation; |
| 846 | 846 | extern fn ZigLLVMClearCurrentDebugLocation(builder: *const Builder) void; |
| ... | ... | @@ -1479,8 +1479,8 @@ pub const DISubprogram = opaque { |
| 1479 | 1479 | extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void; |
| 1480 | 1480 | }; |
| 1481 | 1481 | |
| 1482 | pub const getDebugLoc = ZigLLVMGetDebugLoc; | |
| 1483 | extern fn ZigLLVMGetDebugLoc(line: c_uint, col: c_uint, scope: *DIScope) *DILocation; | |
| 1482 | pub const getDebugLoc = ZigLLVMGetDebugLoc2; | |
| 1483 | extern fn ZigLLVMGetDebugLoc2(line: c_uint, col: c_uint, scope: *DIScope, inlined_at: ?*DILocation) *DILocation; | |
| 1484 | 1484 | |
| 1485 | 1485 | pub const DIBuilder = opaque { |
| 1486 | 1486 | pub const dispose = ZigLLVMDisposeDIBuilder; |
src/print_air.zig+3-2| ... | ... | @@ -242,7 +242,8 @@ const Writer = struct { |
| 242 | 242 | .constant => try w.writeConstant(s, inst), |
| 243 | 243 | .assembly => try w.writeAssembly(s, inst), |
| 244 | 244 | .dbg_stmt => try w.writeDbgStmt(s, inst), |
| 245 | .dbg_func => try w.writeDbgFunc(s, inst), | |
| 245 | ||
| 246 | .dbg_inline_begin, .dbg_inline_end => try w.writeDbgInline(s, inst), | |
| 246 | 247 | .aggregate_init => try w.writeAggregateInit(s, inst), |
| 247 | 248 | .union_init => try w.writeUnionInit(s, inst), |
| 248 | 249 | .br => try w.writeBr(s, inst), |
| ... | ... | @@ -553,7 +554,7 @@ const Writer = struct { |
| 553 | 554 | try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); |
| 554 | 555 | } |
| 555 | 556 | |
| 556 | fn writeDbgFunc(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | |
| 557 | fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | |
| 557 | 558 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; |
| 558 | 559 | const function = w.air.values[ty_pl.payload].castTag(.function).?.data; |
| 559 | 560 | try s.print("{s}", .{function.owner_decl.name}); |
src/zig_llvm.cpp+17| ... | ... | @@ -799,6 +799,15 @@ void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, |
| 799 | 799 | unwrap(builder)->SetCurrentDebugLocation(debug_loc); |
| 800 | 800 | } |
| 801 | 801 | |
| 802 | void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line, | |
| 803 | unsigned int column, ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at) | |
| 804 | { | |
| 805 | DIScope* di_scope = reinterpret_cast<DIScope*>(scope); | |
| 806 | DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, column, di_scope, | |
| 807 | reinterpret_cast<DILocation *>(inlined_at), false); | |
| 808 | unwrap(builder)->SetCurrentDebugLocation(debug_loc); | |
| 809 | } | |
| 810 | ||
| 802 | 811 | void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) { |
| 803 | 812 | unwrap(builder)->SetCurrentDebugLocation(DebugLoc()); |
| 804 | 813 | } |
| ... | ... | @@ -1025,6 +1034,14 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop |
| 1025 | 1034 | return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get()); |
| 1026 | 1035 | } |
| 1027 | 1036 | |
| 1037 | ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col, ZigLLVMDIScope *scope, | |
| 1038 | ZigLLVMDILocation *inlined_at) { | |
| 1039 | DIScope* di_scope = reinterpret_cast<DIScope*>(scope); | |
| 1040 | DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, col, di_scope, | |
| 1041 | reinterpret_cast<DILocation *>(inlined_at), false); | |
| 1042 | return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get()); | |
| 1043 | } | |
| 1044 | ||
| 1028 | 1045 | void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) { |
| 1029 | 1046 | if (on_state) { |
| 1030 | 1047 | FastMathFlags fmf; |
src/zig_llvm.h+4| ... | ... | @@ -232,6 +232,8 @@ ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel |
| 232 | 232 | |
| 233 | 233 | ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, |
| 234 | 234 | unsigned int line, unsigned int column, struct ZigLLVMDIScope *scope); |
| 235 | ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line, | |
| 236 | unsigned int column, ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at); | |
| 235 | 237 | ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder); |
| 236 | 238 | |
| 237 | 239 | ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block); |
| ... | ... | @@ -290,6 +292,8 @@ ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder); |
| 290 | 292 | |
| 291 | 293 | ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, |
| 292 | 294 | struct ZigLLVMDIScope *scope); |
| 295 | ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col, | |
| 296 | ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at); | |
| 293 | 297 | |
| 294 | 298 | ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dib, |
| 295 | 299 | LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info, |