| author | |
| committer | |
| log | 49c0bb1f33044658909cae4351d931af497ee4e5 |
| tree | abf9ecce7f08db5b5f92ed30e3fc3f40b926acc3 |
| parent | d4a7a9ac4cf64ef6bf0b1aed16282c3d8b47b431 |
| parent | d83a26f068f42c6f9cafd25b7038b70553a496d8 |
| signature |
Add debug info for inlined calls16 files changed, 277 insertions(+), 12 deletions(-)
src/Air.zig+8-1| ... | @@ -7,7 +7,6 @@ const std = @import("std"); | ... | @@ -7,7 +7,6 @@ const std = @import("std"); |
| 7 | const builtin = @import("builtin"); | 7 | const builtin = @import("builtin"); |
| 8 | const Value = @import("value.zig").Value; | 8 | const Value = @import("value.zig").Value; |
| 9 | const Type = @import("type.zig").Type; | 9 | const Type = @import("type.zig").Type; |
| 10 | const Module = @import("Module.zig"); | ||
| 11 | const assert = std.debug.assert; | 10 | const assert = std.debug.assert; |
| 12 | const Air = @This(); | 11 | const Air = @This(); |
| 13 | 12 | ||
| ... | @@ -327,6 +326,12 @@ pub const Inst = struct { | ... | @@ -327,6 +326,12 @@ pub const Inst = struct { |
| 327 | /// Result type is always void. | 326 | /// Result type is always void. |
| 328 | /// Uses the `dbg_stmt` field. | 327 | /// Uses the `dbg_stmt` field. |
| 329 | dbg_stmt, | 328 | dbg_stmt, |
| 329 | /// Marks the start of an inline call. | ||
| 330 | /// Uses `ty_pl` with the payload being the index of a Value.Function in air.values. | ||
| 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, | ||
| 330 | /// Marks the beginning of a local variable. The operand is a pointer pointing | 335 | /// Marks the beginning of a local variable. The operand is a pointer pointing |
| 331 | /// to the storage for the variable. The local may be a const or a var. | 336 | /// to the storage for the variable. The local may be a const or a var. |
| 332 | /// Result type is always void. | 337 | /// Result type is always void. |
| ... | @@ -971,6 +976,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { | ... | @@ -971,6 +976,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { |
| 971 | 976 | ||
| 972 | .breakpoint, | 977 | .breakpoint, |
| 973 | .dbg_stmt, | 978 | .dbg_stmt, |
| 979 | .dbg_inline_begin, | ||
| 980 | .dbg_inline_end, | ||
| 974 | .dbg_var_ptr, | 981 | .dbg_var_ptr, |
| 975 | .dbg_var_val, | 982 | .dbg_var_val, |
| 976 | .store, | 983 | .store, |
src/AstGen.zig+17| ... | @@ -5148,6 +5148,7 @@ fn ifExpr( | ... | @@ -5148,6 +5148,7 @@ fn ifExpr( |
| 5148 | else | 5148 | else |
| 5149 | false; | 5149 | false; |
| 5150 | 5150 | ||
| 5151 | try emitDbgNode(parent_gz, if_full.ast.cond_expr); | ||
| 5151 | const cond: struct { | 5152 | const cond: struct { |
| 5152 | inst: Zir.Inst.Ref, | 5153 | inst: Zir.Inst.Ref, |
| 5153 | bool_bit: Zir.Inst.Ref, | 5154 | bool_bit: Zir.Inst.Ref, |
| ... | @@ -5458,6 +5459,7 @@ fn whileExpr( | ... | @@ -5458,6 +5459,7 @@ fn whileExpr( |
| 5458 | else | 5459 | else |
| 5459 | false; | 5460 | false; |
| 5460 | 5461 | ||
| 5462 | try emitDbgNode(parent_gz, while_full.ast.cond_expr); | ||
| 5461 | const cond: struct { | 5463 | const cond: struct { |
| 5462 | inst: Zir.Inst.Ref, | 5464 | inst: Zir.Inst.Ref, |
| 5463 | bool_bit: Zir.Inst.Ref, | 5465 | bool_bit: Zir.Inst.Ref, |
| ... | @@ -5678,6 +5680,8 @@ fn forExpr( | ... | @@ -5678,6 +5680,8 @@ fn forExpr( |
| 5678 | else | 5680 | else |
| 5679 | false; | 5681 | false; |
| 5680 | 5682 | ||
| 5683 | try emitDbgNode(parent_gz, for_full.ast.cond_expr); | ||
| 5684 | |||
| 5681 | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; | 5685 | const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none; |
| 5682 | const array_ptr = try expr(parent_gz, scope, cond_rl, for_full.ast.cond_expr); | 5686 | const array_ptr = try expr(parent_gz, scope, cond_rl, for_full.ast.cond_expr); |
| 5683 | const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr); | 5687 | const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr); |
| ... | @@ -7810,6 +7814,19 @@ fn callExpr( | ... | @@ -7810,6 +7814,19 @@ fn callExpr( |
| 7810 | break :blk .auto; | 7814 | break :blk .auto; |
| 7811 | }; | 7815 | }; |
| 7812 | 7816 | ||
| 7817 | { | ||
| 7818 | astgen.advanceSourceCursor(astgen.tree.tokens.items(.start)[call.ast.lparen]); | ||
| 7819 | const line = astgen.source_line - gz.decl_line; | ||
| 7820 | const column = astgen.source_column; | ||
| 7821 | |||
| 7822 | _ = try gz.add(.{ .tag = .dbg_stmt, .data = .{ | ||
| 7823 | .dbg_stmt = .{ | ||
| 7824 | .line = line, | ||
| 7825 | .column = column, | ||
| 7826 | }, | ||
| 7827 | } }); | ||
| 7828 | } | ||
| 7829 | |||
| 7813 | assert(callee != .none); | 7830 | assert(callee != .none); |
| 7814 | assert(node != 0); | 7831 | assert(node != 0); |
| 7815 | 7832 |
src/Liveness.zig+2| ... | @@ -314,6 +314,8 @@ fn analyzeInst( | ... | @@ -314,6 +314,8 @@ fn analyzeInst( |
| 314 | .const_ty, | 314 | .const_ty, |
| 315 | .breakpoint, | 315 | .breakpoint, |
| 316 | .dbg_stmt, | 316 | .dbg_stmt, |
| 317 | .dbg_inline_begin, | ||
| 318 | .dbg_inline_end, | ||
| 317 | .unreach, | 319 | .unreach, |
| 318 | .fence, | 320 | .fence, |
| 319 | .ret_addr, | 321 | .ret_addr, |
src/Sema.zig+37| ... | @@ -4639,6 +4639,10 @@ fn analyzeCall( | ... | @@ -4639,6 +4639,10 @@ fn analyzeCall( |
| 4639 | // comptime state. | 4639 | // comptime state. |
| 4640 | var should_memoize = true; | 4640 | var should_memoize = true; |
| 4641 | 4641 | ||
| 4642 | var new_fn_info = module_fn.owner_decl.ty.fnInfo(); | ||
| 4643 | new_fn_info.param_types = try sema.arena.alloc(Type, new_fn_info.param_types.len); | ||
| 4644 | new_fn_info.comptime_params = (try sema.arena.alloc(bool, new_fn_info.param_types.len)).ptr; | ||
| 4645 | |||
| 4642 | // This will have return instructions analyzed as break instructions to | 4646 | // This will have return instructions analyzed as break instructions to |
| 4643 | // the block_inst above. Here we are performing "comptime/inline semantic analysis" | 4647 | // the block_inst above. Here we are performing "comptime/inline semantic analysis" |
| 4644 | // for a function body, which means we must map the parameter ZIR instructions to | 4648 | // for a function body, which means we must map the parameter ZIR instructions to |
| ... | @@ -4658,6 +4662,7 @@ fn analyzeCall( | ... | @@ -4658,6 +4662,7 @@ fn analyzeCall( |
| 4658 | const param_body = sema.code.extra[extra.end..][0..extra.data.body_len]; | 4662 | const param_body = sema.code.extra[extra.end..][0..extra.data.body_len]; |
| 4659 | const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst); | 4663 | const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst); |
| 4660 | const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst); | 4664 | const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst); |
| 4665 | new_fn_info.param_types[arg_i] = param_ty; | ||
| 4661 | const arg_src = call_src; // TODO: better source location | 4666 | const arg_src = call_src; // TODO: better source location |
| 4662 | const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src); | 4667 | const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src); |
| 4663 | try sema.inst_map.putNoClobber(gpa, inst, casted_arg); | 4668 | try sema.inst_map.putNoClobber(gpa, inst, casted_arg); |
| ... | @@ -4685,6 +4690,7 @@ fn analyzeCall( | ... | @@ -4685,6 +4690,7 @@ fn analyzeCall( |
| 4685 | .param_anytype, .param_anytype_comptime => { | 4690 | .param_anytype, .param_anytype_comptime => { |
| 4686 | // No coercion needed. | 4691 | // No coercion needed. |
| 4687 | const uncasted_arg = uncasted_args[arg_i]; | 4692 | const uncasted_arg = uncasted_args[arg_i]; |
| 4693 | new_fn_info.param_types[arg_i] = sema.typeOf(uncasted_arg); | ||
| 4688 | try sema.inst_map.putNoClobber(gpa, inst, uncasted_arg); | 4694 | try sema.inst_map.putNoClobber(gpa, inst, uncasted_arg); |
| 4689 | 4695 | ||
| 4690 | if (is_comptime_call) { | 4696 | if (is_comptime_call) { |
| ... | @@ -4735,6 +4741,7 @@ fn analyzeCall( | ... | @@ -4735,6 +4741,7 @@ fn analyzeCall( |
| 4735 | } | 4741 | } |
| 4736 | break :blk bare_return_type; | 4742 | break :blk bare_return_type; |
| 4737 | }; | 4743 | }; |
| 4744 | new_fn_info.return_type = fn_ret_ty; | ||
| 4738 | const parent_fn_ret_ty = sema.fn_ret_ty; | 4745 | const parent_fn_ret_ty = sema.fn_ret_ty; |
| 4739 | sema.fn_ret_ty = fn_ret_ty; | 4746 | sema.fn_ret_ty = fn_ret_ty; |
| 4740 | defer sema.fn_ret_ty = parent_fn_ret_ty; | 4747 | defer sema.fn_ret_ty = parent_fn_ret_ty; |
| ... | @@ -4757,6 +4764,11 @@ fn analyzeCall( | ... | @@ -4757,6 +4764,11 @@ fn analyzeCall( |
| 4757 | } | 4764 | } |
| 4758 | } | 4765 | } |
| 4759 | 4766 | ||
| 4767 | const new_func_resolved_ty = try Type.Tag.function.create(sema.arena, new_fn_info); | ||
| 4768 | if (!is_comptime_call) { | ||
| 4769 | try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin); | ||
| 4770 | } | ||
| 4771 | |||
| 4760 | const result = result: { | 4772 | const result = result: { |
| 4761 | sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) { | 4773 | sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) { |
| 4762 | error.ComptimeReturn => break :result inlining.comptime_result, | 4774 | error.ComptimeReturn => break :result inlining.comptime_result, |
| ... | @@ -4771,6 +4783,10 @@ fn analyzeCall( | ... | @@ -4771,6 +4783,10 @@ fn analyzeCall( |
| 4771 | break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges); | 4783 | break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges); |
| 4772 | }; | 4784 | }; |
| 4773 | 4785 | ||
| 4786 | if (!is_comptime_call) { | ||
| 4787 | try sema.emitDbgInline(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty, .dbg_inline_end); | ||
| 4788 | } | ||
| 4789 | |||
| 4774 | if (should_memoize and is_comptime_call) { | 4790 | if (should_memoize and is_comptime_call) { |
| 4775 | const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result); | 4791 | const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result); |
| 4776 | 4792 | ||
| ... | @@ -5175,6 +5191,27 @@ fn instantiateGenericCall( | ... | @@ -5175,6 +5191,27 @@ fn instantiateGenericCall( |
| 5175 | return func_inst; | 5191 | return func_inst; |
| 5176 | } | 5192 | } |
| 5177 | 5193 | ||
| 5194 | fn emitDbgInline( | ||
| 5195 | sema: *Sema, | ||
| 5196 | block: *Block, | ||
| 5197 | old_func: *Module.Fn, | ||
| 5198 | new_func: *Module.Fn, | ||
| 5199 | new_func_ty: Type, | ||
| 5200 | tag: Air.Inst.Tag, | ||
| 5201 | ) CompileError!void { | ||
| 5202 | // No change of file; no dbg_inline needed. | ||
| 5203 | if (old_func == new_func) return; | ||
| 5204 | |||
| 5205 | try sema.air_values.append(sema.gpa, try Value.Tag.function.create(sema.arena, new_func)); | ||
| 5206 | _ = try block.addInst(.{ | ||
| 5207 | .tag = tag, | ||
| 5208 | .data = .{ .ty_pl = .{ | ||
| 5209 | .ty = try sema.addType(new_func_ty), | ||
| 5210 | .payload = @intCast(u32, sema.air_values.items.len - 1), | ||
| 5211 | } }, | ||
| 5212 | }); | ||
| 5213 | } | ||
| 5214 | |||
| 5178 | fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5215 | fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 5179 | _ = block; | 5216 | _ = block; |
| 5180 | const tracy = trace(@src()); | 5217 | const tracy = trace(@src()); |
src/arch/aarch64/CodeGen.zig+12| ... | @@ -649,6 +649,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -649,6 +649,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 649 | .dbg_var_val, | 649 | .dbg_var_val, |
| 650 | => try self.airDbgVar(inst), | 650 | => try self.airDbgVar(inst), |
| 651 | 651 | ||
| 652 | .dbg_inline_begin, | ||
| 653 | .dbg_inline_end, | ||
| 654 | => try self.airDbgInline(inst), | ||
| 655 | |||
| 652 | .call => try self.airCall(inst, .auto), | 656 | .call => try self.airCall(inst, .auto), |
| 653 | .call_always_tail => try self.airCall(inst, .always_tail), | 657 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 654 | .call_never_tail => try self.airCall(inst, .never_tail), | 658 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -2715,6 +2719,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2715,6 +2719,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 2715 | return self.finishAirBookkeeping(); | 2719 | return self.finishAirBookkeeping(); |
| 2716 | } | 2720 | } |
| 2717 | 2721 | ||
| 2722 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | ||
| 2723 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | ||
| 2724 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; | ||
| 2725 | // TODO emit debug info for function change | ||
| 2726 | _ = function; | ||
| 2727 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | ||
| 2728 | } | ||
| 2729 | |||
| 2718 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 2730 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 2719 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 2731 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 2720 | const name = self.air.nullTerminatedString(pl_op.payload); | 2732 | const name = self.air.nullTerminatedString(pl_op.payload); |
src/arch/arm/CodeGen.zig+12| ... | @@ -646,6 +646,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -646,6 +646,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 646 | .dbg_var_val, | 646 | .dbg_var_val, |
| 647 | => try self.airDbgVar(inst), | 647 | => try self.airDbgVar(inst), |
| 648 | 648 | ||
| 649 | .dbg_inline_begin, | ||
| 650 | .dbg_inline_end, | ||
| 651 | => try self.airDbgInline(inst), | ||
| 652 | |||
| 649 | .call => try self.airCall(inst, .auto), | 653 | .call => try self.airCall(inst, .auto), |
| 650 | .call_always_tail => try self.airCall(inst, .always_tail), | 654 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 651 | .call_never_tail => try self.airCall(inst, .never_tail), | 655 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -2835,6 +2839,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2835,6 +2839,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 2835 | return self.finishAirBookkeeping(); | 2839 | return self.finishAirBookkeeping(); |
| 2836 | } | 2840 | } |
| 2837 | 2841 | ||
| 2842 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | ||
| 2843 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | ||
| 2844 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; | ||
| 2845 | // TODO emit debug info for function change | ||
| 2846 | _ = function; | ||
| 2847 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | ||
| 2848 | } | ||
| 2849 | |||
| 2838 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 2850 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 2839 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 2851 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 2840 | const name = self.air.nullTerminatedString(pl_op.payload); | 2852 | const name = self.air.nullTerminatedString(pl_op.payload); |
src/arch/riscv64/CodeGen.zig+12| ... | @@ -613,6 +613,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -613,6 +613,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 613 | .dbg_var_val, | 613 | .dbg_var_val, |
| 614 | => try self.airDbgVar(inst), | 614 | => try self.airDbgVar(inst), |
| 615 | 615 | ||
| 616 | .dbg_inline_begin, | ||
| 617 | .dbg_inline_end, | ||
| 618 | => try self.airDbgInline(inst), | ||
| 619 | |||
| 616 | .call => try self.airCall(inst, .auto), | 620 | .call => try self.airCall(inst, .auto), |
| 617 | .call_always_tail => try self.airCall(inst, .always_tail), | 621 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 618 | .call_never_tail => try self.airCall(inst, .never_tail), | 622 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -1640,6 +1644,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -1640,6 +1644,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 1640 | return self.finishAirBookkeeping(); | 1644 | return self.finishAirBookkeeping(); |
| 1641 | } | 1645 | } |
| 1642 | 1646 | ||
| 1647 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | ||
| 1648 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | ||
| 1649 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; | ||
| 1650 | // TODO emit debug info for function change | ||
| 1651 | _ = function; | ||
| 1652 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | ||
| 1653 | } | ||
| 1654 | |||
| 1643 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 1655 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 1644 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 1656 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 1645 | const name = self.air.nullTerminatedString(pl_op.payload); | 1657 | const name = self.air.nullTerminatedString(pl_op.payload); |
src/arch/wasm/CodeGen.zig+2| ... | @@ -1227,6 +1227,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { | ... | @@ -1227,6 +1227,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1227 | 1227 | ||
| 1228 | // TODO | 1228 | // TODO |
| 1229 | .dbg_stmt, | 1229 | .dbg_stmt, |
| 1230 | .dbg_inline_begin, | ||
| 1231 | .dbg_inline_end, | ||
| 1230 | .dbg_var_ptr, | 1232 | .dbg_var_ptr, |
| 1231 | .dbg_var_val, | 1233 | .dbg_var_val, |
| 1232 | => WValue.none, | 1234 | => WValue.none, |
src/arch/x86_64/CodeGen.zig+12| ... | @@ -730,6 +730,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -730,6 +730,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 730 | .dbg_var_val, | 730 | .dbg_var_val, |
| 731 | => try self.airDbgVar(inst), | 731 | => try self.airDbgVar(inst), |
| 732 | 732 | ||
| 733 | .dbg_inline_begin, | ||
| 734 | .dbg_inline_end, | ||
| 735 | => try self.airDbgInline(inst), | ||
| 736 | |||
| 733 | .call => try self.airCall(inst, .auto), | 737 | .call => try self.airCall(inst, .auto), |
| 734 | .call_always_tail => try self.airCall(inst, .always_tail), | 738 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 735 | .call_never_tail => try self.airCall(inst, .never_tail), | 739 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -3670,6 +3674,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -3670,6 +3674,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { |
| 3670 | return self.finishAirBookkeeping(); | 3674 | return self.finishAirBookkeeping(); |
| 3671 | } | 3675 | } |
| 3672 | 3676 | ||
| 3677 | fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { | ||
| 3678 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | ||
| 3679 | const function = self.air.values[ty_pl.payload].castTag(.function).?.data; | ||
| 3680 | // TODO emit debug info for function change | ||
| 3681 | _ = function; | ||
| 3682 | return self.finishAir(inst, .dead, .{ .none, .none, .none }); | ||
| 3683 | } | ||
| 3684 | |||
| 3673 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { | 3685 | fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void { |
| 3674 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 3686 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 3675 | const name = self.air.nullTerminatedString(pl_op.payload); | 3687 | const name = self.air.nullTerminatedString(pl_op.payload); |
src/codegen/c.zig+12| ... | @@ -1726,6 +1726,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1726,6 +1726,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1726 | .dbg_var_val, | 1726 | .dbg_var_val, |
| 1727 | => try airDbgVar(f, inst), | 1727 | => try airDbgVar(f, inst), |
| 1728 | 1728 | ||
| 1729 | .dbg_inline_begin, | ||
| 1730 | .dbg_inline_end, | ||
| 1731 | => try airDbgInline(f, inst), | ||
| 1732 | |||
| 1729 | .call => try airCall(f, inst, .auto), | 1733 | .call => try airCall(f, inst, .auto), |
| 1730 | .call_always_tail => try airCall(f, inst, .always_tail), | 1734 | .call_always_tail => try airCall(f, inst, .always_tail), |
| 1731 | .call_never_tail => try airCall(f, inst, .never_tail), | 1735 | .call_never_tail => try airCall(f, inst, .never_tail), |
| ... | @@ -2660,6 +2664,14 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2660,6 +2664,14 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2660 | return CValue.none; | 2664 | return CValue.none; |
| 2661 | } | 2665 | } |
| 2662 | 2666 | ||
| 2667 | fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue { | ||
| 2668 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | ||
| 2669 | const writer = f.object.writer(); | ||
| 2670 | const function = f.air.values[ty_pl.payload].castTag(.function).?.data; | ||
| 2671 | try writer.print("/* dbg func:{s} */\n", .{function.owner_decl.name}); | ||
| 2672 | return CValue.none; | ||
| 2673 | } | ||
| 2674 | |||
| 2663 | fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { | 2675 | fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2664 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; | 2676 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; |
| 2665 | const name = f.air.nullTerminatedString(pl_op.payload); | 2677 | const name = f.air.nullTerminatedString(pl_op.payload); |
src/codegen/llvm.zig+88-7| ... | @@ -620,7 +620,8 @@ pub const Object = struct { | ... | @@ -620,7 +620,8 @@ pub const Object = struct { |
| 620 | 620 | ||
| 621 | llvm_func.fnSetSubprogram(subprogram); | 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 | var fg: FuncGen = .{ | 627 | var fg: FuncGen = .{ |
| ... | @@ -639,6 +640,7 @@ pub const Object = struct { | ... | @@ -639,6 +640,7 @@ pub const Object = struct { |
| 639 | .single_threaded = module.comp.bin_file.options.single_threaded, | 640 | .single_threaded = module.comp.bin_file.options.single_threaded, |
| 640 | .di_scope = di_scope, | 641 | .di_scope = di_scope, |
| 641 | .di_file = di_file, | 642 | .di_file = di_file, |
| 643 | .base_line = dg.decl.src_line, | ||
| 642 | .prev_dbg_line = 0, | 644 | .prev_dbg_line = 0, |
| 643 | .prev_dbg_column = 0, | 645 | .prev_dbg_column = 0, |
| 644 | }; | 646 | }; |
| ... | @@ -1754,11 +1756,14 @@ pub const DeclGen = struct { | ... | @@ -1754,11 +1756,14 @@ pub const DeclGen = struct { |
| 1754 | /// Note that this can be called before the function's semantic analysis has | 1756 | /// Note that this can be called before the function's semantic analysis has |
| 1755 | /// completed, so if any attributes rely on that, they must be done in updateFunc, not here. | 1757 | /// completed, so if any attributes rely on that, they must be done in updateFunc, not here. |
| 1756 | fn resolveLlvmFunction(dg: *DeclGen, decl: *Module.Decl) !*const llvm.Value { | 1758 | fn resolveLlvmFunction(dg: *DeclGen, decl: *Module.Decl) !*const llvm.Value { |
| 1759 | return dg.resolveLlvmFunctionExtra(decl, decl.ty); | ||
| 1760 | } | ||
| 1761 | |||
| 1762 | fn resolveLlvmFunctionExtra(dg: *DeclGen, decl: *Module.Decl, zig_fn_type: Type) !*const llvm.Value { | ||
| 1757 | const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl); | 1763 | const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl); |
| 1758 | if (gop.found_existing) return gop.value_ptr.*; | 1764 | if (gop.found_existing) return gop.value_ptr.*; |
| 1759 | 1765 | ||
| 1760 | assert(decl.has_tv); | 1766 | assert(decl.has_tv); |
| 1761 | const zig_fn_type = decl.ty; | ||
| 1762 | const fn_info = zig_fn_type.fnInfo(); | 1767 | const fn_info = zig_fn_type.fnInfo(); |
| 1763 | const target = dg.module.getTarget(); | 1768 | const target = dg.module.getTarget(); |
| 1764 | const sret = firstParamSRet(fn_info, target); | 1769 | const sret = firstParamSRet(fn_info, target); |
| ... | @@ -3207,9 +3212,13 @@ pub const FuncGen = struct { | ... | @@ -3207,9 +3212,13 @@ pub const FuncGen = struct { |
| 3207 | builder: *const llvm.Builder, | 3212 | builder: *const llvm.Builder, |
| 3208 | di_scope: ?*llvm.DIScope, | 3213 | di_scope: ?*llvm.DIScope, |
| 3209 | di_file: ?*llvm.DIFile, | 3214 | di_file: ?*llvm.DIFile, |
| 3215 | base_line: u32, | ||
| 3210 | prev_dbg_line: c_uint, | 3216 | prev_dbg_line: c_uint, |
| 3211 | prev_dbg_column: c_uint, | 3217 | prev_dbg_column: c_uint, |
| 3212 | 3218 | ||
| 3219 | /// Stack of locations where a call was inlined. | ||
| 3220 | dbg_inlined: std.ArrayListUnmanaged(DbgState) = .{}, | ||
| 3221 | |||
| 3213 | /// This stores the LLVM values used in a function, such that they can be referred to | 3222 | /// This stores the LLVM values used in a function, such that they can be referred to |
| 3214 | /// in other instructions. This table is cleared before every function is generated. | 3223 | /// in other instructions. This table is cleared before every function is generated. |
| 3215 | func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value), | 3224 | func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value), |
| ... | @@ -3237,11 +3246,13 @@ pub const FuncGen = struct { | ... | @@ -3237,11 +3246,13 @@ pub const FuncGen = struct { |
| 3237 | 3246 | ||
| 3238 | single_threaded: bool, | 3247 | single_threaded: bool, |
| 3239 | 3248 | ||
| 3249 | const DbgState = struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 }; | ||
| 3240 | const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock); | 3250 | const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock); |
| 3241 | const BreakValues = std.ArrayListUnmanaged(*const llvm.Value); | 3251 | const BreakValues = std.ArrayListUnmanaged(*const llvm.Value); |
| 3242 | 3252 | ||
| 3243 | fn deinit(self: *FuncGen) void { | 3253 | fn deinit(self: *FuncGen) void { |
| 3244 | self.builder.dispose(); | 3254 | self.builder.dispose(); |
| 3255 | self.dbg_inlined.deinit(self.gpa); | ||
| 3245 | self.func_inst_table.deinit(self.gpa); | 3256 | self.func_inst_table.deinit(self.gpa); |
| 3246 | self.blocks.deinit(self.gpa); | 3257 | self.blocks.deinit(self.gpa); |
| 3247 | } | 3258 | } |
| ... | @@ -3460,6 +3471,8 @@ pub const FuncGen = struct { | ... | @@ -3460,6 +3471,8 @@ pub const FuncGen = struct { |
| 3460 | .const_ty => unreachable, | 3471 | .const_ty => unreachable, |
| 3461 | .unreach => self.airUnreach(inst), | 3472 | .unreach => self.airUnreach(inst), |
| 3462 | .dbg_stmt => self.airDbgStmt(inst), | 3473 | .dbg_stmt => self.airDbgStmt(inst), |
| 3474 | .dbg_inline_begin => try self.airDbgInline(inst, true), | ||
| 3475 | .dbg_inline_end => try self.airDbgInline(inst, false), | ||
| 3463 | .dbg_var_ptr => try self.airDbgVarPtr(inst), | 3476 | .dbg_var_ptr => try self.airDbgVarPtr(inst), |
| 3464 | .dbg_var_val => try self.airDbgVarVal(inst), | 3477 | .dbg_var_val => try self.airDbgVarVal(inst), |
| 3465 | // zig fmt: on | 3478 | // zig fmt: on |
| ... | @@ -4175,9 +4188,69 @@ pub const FuncGen = struct { | ... | @@ -4175,9 +4188,69 @@ pub const FuncGen = struct { |
| 4175 | fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value { | 4188 | fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value { |
| 4176 | const di_scope = self.di_scope orelse return null; | 4189 | const di_scope = self.di_scope orelse return null; |
| 4177 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; | 4190 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; |
| 4178 | 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); |
| 4179 | self.prev_dbg_column = @intCast(c_uint, dbg_stmt.column + 1); | 4192 | self.prev_dbg_column = @intCast(c_uint, dbg_stmt.column + 1); |
| 4180 | 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); | ||
| 4198 | return null; | ||
| 4199 | } | ||
| 4200 | |||
| 4201 | fn airDbgInline(self: *FuncGen, inst: Air.Inst.Index, start: bool) !?*const llvm.Value { | ||
| 4202 | const dib = self.dg.object.di_builder orelse return null; | ||
| 4203 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | ||
| 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 | |||
| 4224 | const fn_ty = try self.air.getRefType(ty_pl.ty).copy(self.dg.object.type_map_arena.allocator()); | ||
| 4225 | const fqn = try decl.getFullyQualifiedName(self.gpa); | ||
| 4226 | defer self.gpa.free(fqn); | ||
| 4227 | const fn_info = fn_ty.fnInfo(); | ||
| 4228 | |||
| 4229 | const is_internal_linkage = !self.dg.module.decl_exports.contains(decl); | ||
| 4230 | const noret_bit: c_uint = if (fn_info.return_type.isNoReturn()) | ||
| 4231 | llvm.DIFlags.NoReturn | ||
| 4232 | else | ||
| 4233 | 0; | ||
| 4234 | const subprogram = dib.createFunction( | ||
| 4235 | di_file.toScope(), | ||
| 4236 | decl.name, | ||
| 4237 | fqn, | ||
| 4238 | di_file, | ||
| 4239 | line_number, | ||
| 4240 | try self.dg.object.lowerDebugType(fn_ty, .full), | ||
| 4241 | is_internal_linkage, | ||
| 4242 | true, // is definition | ||
| 4243 | line_number + func.lbrace_line, // scope line | ||
| 4244 | llvm.DIFlags.StaticMember | noret_bit, | ||
| 4245 | self.dg.module.comp.bin_file.options.optimize_mode != .Debug, | ||
| 4246 | null, // decl_subprogram | ||
| 4247 | ); | ||
| 4248 | |||
| 4249 | try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode()); | ||
| 4250 | |||
| 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; | ||
| 4181 | return null; | 4254 | return null; |
| 4182 | } | 4255 | } |
| 4183 | 4256 | ||
| ... | @@ -4197,7 +4270,11 @@ pub const FuncGen = struct { | ... | @@ -4197,7 +4270,11 @@ pub const FuncGen = struct { |
| 4197 | true, // always preserve | 4270 | true, // always preserve |
| 4198 | 0, // flags | 4271 | 0, // flags |
| 4199 | ); | 4272 | ); |
| 4200 | 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); | ||
| 4201 | const insert_block = self.builder.getInsertBlock(); | 4278 | const insert_block = self.builder.getInsertBlock(); |
| 4202 | _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block); | 4279 | _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block); |
| 4203 | return null; | 4280 | return null; |
| ... | @@ -4219,7 +4296,11 @@ pub const FuncGen = struct { | ... | @@ -4219,7 +4296,11 @@ pub const FuncGen = struct { |
| 4219 | true, // always preserve | 4296 | true, // always preserve |
| 4220 | 0, // flags | 4297 | 0, // flags |
| 4221 | ); | 4298 | ); |
| 4222 | 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); | ||
| 4223 | const insert_block = self.builder.getInsertBlock(); | 4304 | const insert_block = self.builder.getInsertBlock(); |
| 4224 | if (isByRef(operand_ty)) { | 4305 | if (isByRef(operand_ty)) { |
| 4225 | _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block); | 4306 | _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block); |
| ... | @@ -5481,7 +5562,7 @@ pub const FuncGen = struct { | ... | @@ -5481,7 +5562,7 @@ pub const FuncGen = struct { |
| 5481 | self.arg_index, // includes +1 because 0 is return type | 5562 | self.arg_index, // includes +1 because 0 is return type |
| 5482 | ); | 5563 | ); |
| 5483 | 5564 | ||
| 5484 | 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); |
| 5485 | const insert_block = self.builder.getInsertBlock(); | 5566 | const insert_block = self.builder.getInsertBlock(); |
| 5486 | if (isByRef(inst_ty)) { | 5567 | if (isByRef(inst_ty)) { |
| 5487 | _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block); | 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,8 +839,8 @@ pub const Builder = opaque { |
| 839 | pub const buildExactSDiv = LLVMBuildExactSDiv; | 839 | pub const buildExactSDiv = LLVMBuildExactSDiv; |
| 840 | extern fn LLVMBuildExactSDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value; | 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; | 842 | pub const setCurrentDebugLocation = ZigLLVMSetCurrentDebugLocation2; |
| 843 | extern fn ZigLLVMSetCurrentDebugLocation(builder: *const Builder, line: c_uint, column: c_uint, scope: *DIScope) void; | 843 | extern fn ZigLLVMSetCurrentDebugLocation2(builder: *const Builder, line: c_uint, column: c_uint, scope: *DIScope, inlined_at: ?*DILocation) void; |
| 844 | 844 | ||
| 845 | pub const clearCurrentDebugLocation = ZigLLVMClearCurrentDebugLocation; | 845 | pub const clearCurrentDebugLocation = ZigLLVMClearCurrentDebugLocation; |
| 846 | extern fn ZigLLVMClearCurrentDebugLocation(builder: *const Builder) void; | 846 | extern fn ZigLLVMClearCurrentDebugLocation(builder: *const Builder) void; |
| ... | @@ -1479,8 +1479,8 @@ pub const DISubprogram = opaque { | ... | @@ -1479,8 +1479,8 @@ pub const DISubprogram = opaque { |
| 1479 | extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void; | 1479 | extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void; |
| 1480 | }; | 1480 | }; |
| 1481 | 1481 | ||
| 1482 | pub const getDebugLoc = ZigLLVMGetDebugLoc; | 1482 | pub const getDebugLoc = ZigLLVMGetDebugLoc2; |
| 1483 | extern fn ZigLLVMGetDebugLoc(line: c_uint, col: c_uint, scope: *DIScope) *DILocation; | 1483 | extern fn ZigLLVMGetDebugLoc2(line: c_uint, col: c_uint, scope: *DIScope, inlined_at: ?*DILocation) *DILocation; |
| 1484 | 1484 | ||
| 1485 | pub const DIBuilder = opaque { | 1485 | pub const DIBuilder = opaque { |
| 1486 | pub const dispose = ZigLLVMDisposeDIBuilder; | 1486 | pub const dispose = ZigLLVMDisposeDIBuilder; |
src/print_air.zig+8| ... | @@ -242,6 +242,8 @@ const Writer = struct { | ... | @@ -242,6 +242,8 @@ const Writer = struct { |
| 242 | .constant => try w.writeConstant(s, inst), | 242 | .constant => try w.writeConstant(s, inst), |
| 243 | .assembly => try w.writeAssembly(s, inst), | 243 | .assembly => try w.writeAssembly(s, inst), |
| 244 | .dbg_stmt => try w.writeDbgStmt(s, inst), | 244 | .dbg_stmt => try w.writeDbgStmt(s, inst), |
| 245 | |||
| 246 | .dbg_inline_begin, .dbg_inline_end => try w.writeDbgInline(s, inst), | ||
| 245 | .aggregate_init => try w.writeAggregateInit(s, inst), | 247 | .aggregate_init => try w.writeAggregateInit(s, inst), |
| 246 | .union_init => try w.writeUnionInit(s, inst), | 248 | .union_init => try w.writeUnionInit(s, inst), |
| 247 | .br => try w.writeBr(s, inst), | 249 | .br => try w.writeBr(s, inst), |
| ... | @@ -552,6 +554,12 @@ const Writer = struct { | ... | @@ -552,6 +554,12 @@ const Writer = struct { |
| 552 | try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); | 554 | try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); |
| 553 | } | 555 | } |
| 554 | 556 | ||
| 557 | fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | ||
| 558 | const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; | ||
| 559 | const function = w.air.values[ty_pl.payload].castTag(.function).?.data; | ||
| 560 | try s.print("{s}", .{function.owner_decl.name}); | ||
| 561 | } | ||
| 562 | |||
| 555 | fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { | 563 | fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 556 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; | 564 | const pl_op = w.air.instructions.items(.data)[inst].pl_op; |
| 557 | try w.writeOperand(s, inst, 0, pl_op.operand); | 565 | try w.writeOperand(s, inst, 0, pl_op.operand); |
src/type.zig+30| ... | @@ -486,6 +486,36 @@ pub const Type = extern union { | ... | @@ -486,6 +486,36 @@ pub const Type = extern union { |
| 486 | 486 | ||
| 487 | .pointer => return self.castTag(.pointer).?.*, | 487 | .pointer => return self.castTag(.pointer).?.*, |
| 488 | 488 | ||
| 489 | .optional_single_mut_pointer => return .{ .data = .{ | ||
| 490 | .pointee_type = self.castPointer().?.data, | ||
| 491 | .sentinel = null, | ||
| 492 | .@"align" = 0, | ||
| 493 | .@"addrspace" = .generic, | ||
| 494 | .bit_offset = 0, | ||
| 495 | .host_size = 0, | ||
| 496 | .@"allowzero" = false, | ||
| 497 | .mutable = true, | ||
| 498 | .@"volatile" = false, | ||
| 499 | .size = .One, | ||
| 500 | } }, | ||
| 501 | .optional_single_const_pointer => return .{ .data = .{ | ||
| 502 | .pointee_type = self.castPointer().?.data, | ||
| 503 | .sentinel = null, | ||
| 504 | .@"align" = 0, | ||
| 505 | .@"addrspace" = .generic, | ||
| 506 | .bit_offset = 0, | ||
| 507 | .host_size = 0, | ||
| 508 | .@"allowzero" = false, | ||
| 509 | .mutable = false, | ||
| 510 | .@"volatile" = false, | ||
| 511 | .size = .One, | ||
| 512 | } }, | ||
| 513 | .optional => { | ||
| 514 | var buf: Payload.ElemType = undefined; | ||
| 515 | const child_type = self.optionalChild(&buf); | ||
| 516 | return child_type.ptrInfo(); | ||
| 517 | }, | ||
| 518 | |||
| 489 | else => unreachable, | 519 | else => unreachable, |
| 490 | } | 520 | } |
| 491 | } | 521 | } |
src/zig_llvm.cpp+17| ... | @@ -799,6 +799,15 @@ void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, | ... | @@ -799,6 +799,15 @@ void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, |
| 799 | unwrap(builder)->SetCurrentDebugLocation(debug_loc); | 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 | void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) { | 811 | void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) { |
| 803 | unwrap(builder)->SetCurrentDebugLocation(DebugLoc()); | 812 | unwrap(builder)->SetCurrentDebugLocation(DebugLoc()); |
| 804 | } | 813 | } |
| ... | @@ -1025,6 +1034,14 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop | ... | @@ -1025,6 +1034,14 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop |
| 1025 | return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get()); | 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 | void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) { | 1045 | void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) { |
| 1029 | if (on_state) { | 1046 | if (on_state) { |
| 1030 | FastMathFlags fmf; | 1047 | FastMathFlags fmf; |
src/zig_llvm.h+4| ... | @@ -232,6 +232,8 @@ ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel | ... | @@ -232,6 +232,8 @@ ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel |
| 232 | 232 | ||
| 233 | ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, | 233 | ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, |
| 234 | unsigned int line, unsigned int column, struct ZigLLVMDIScope *scope); | 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 | ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder); | 237 | ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder); |
| 236 | 238 | ||
| 237 | ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block); | 239 | ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block); |
| ... | @@ -290,6 +292,8 @@ ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder); | ... | @@ -290,6 +292,8 @@ ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder); |
| 290 | 292 | ||
| 291 | ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, | 293 | ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, |
| 292 | struct ZigLLVMDIScope *scope); | 294 | struct ZigLLVMDIScope *scope); |
| 295 | ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col, | ||
| 296 | ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at); | ||
| 293 | 297 | ||
| 294 | ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dib, | 298 | ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dib, |
| 295 | LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info, | 299 | LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info, |