authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-16 20:40:16+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-16 20:40:16+02:00
log49c0bb1f33044658909cae4351d931af497ee4e5
treeabf9ecce7f08db5b5f92ed30e3fc3f40b926acc3
parentd4a7a9ac4cf64ef6bf0b1aed16282c3d8b47b431
parentd83a26f068f42c6f9cafd25b7038b70553a496d8
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11177 from Vexu/dbg_func

Add debug info for inlined calls

16 files changed, 277 insertions(+), 12 deletions(-)

src/Air.zig+8-1
......@@ -7,7 +7,6 @@ const std = @import("std");
77const builtin = @import("builtin");
88const Value = @import("value.zig").Value;
99const Type = @import("type.zig").Type;
10const Module = @import("Module.zig");
1110const assert = std.debug.assert;
1211const Air = @This();
1312
......@@ -327,6 +326,12 @@ pub const Inst = struct {
327326 /// Result type is always void.
328327 /// Uses the `dbg_stmt` field.
329328 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,
330335 /// Marks the beginning of a local variable. The operand is a pointer pointing
331336 /// to the storage for the variable. The local may be a const or a var.
332337 /// Result type is always void.
......@@ -971,6 +976,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
971976
972977 .breakpoint,
973978 .dbg_stmt,
979 .dbg_inline_begin,
980 .dbg_inline_end,
974981 .dbg_var_ptr,
975982 .dbg_var_val,
976983 .store,
src/AstGen.zig+17
......@@ -5148,6 +5148,7 @@ fn ifExpr(
51485148 else
51495149 false;
51505150
5151 try emitDbgNode(parent_gz, if_full.ast.cond_expr);
51515152 const cond: struct {
51525153 inst: Zir.Inst.Ref,
51535154 bool_bit: Zir.Inst.Ref,
......@@ -5458,6 +5459,7 @@ fn whileExpr(
54585459 else
54595460 false;
54605461
5462 try emitDbgNode(parent_gz, while_full.ast.cond_expr);
54615463 const cond: struct {
54625464 inst: Zir.Inst.Ref,
54635465 bool_bit: Zir.Inst.Ref,
......@@ -5678,6 +5680,8 @@ fn forExpr(
56785680 else
56795681 false;
56805682
5683 try emitDbgNode(parent_gz, for_full.ast.cond_expr);
5684
56815685 const cond_rl: ResultLoc = if (payload_is_ref) .ref else .none;
56825686 const array_ptr = try expr(parent_gz, scope, cond_rl, for_full.ast.cond_expr);
56835687 const len = try parent_gz.addUnNode(.indexable_ptr_len, array_ptr, for_full.ast.cond_expr);
......@@ -7810,6 +7814,19 @@ fn callExpr(
78107814 break :blk .auto;
78117815 };
78127816
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
78137830 assert(callee != .none);
78147831 assert(node != 0);
78157832
src/Liveness.zig+2
......@@ -314,6 +314,8 @@ fn analyzeInst(
314314 .const_ty,
315315 .breakpoint,
316316 .dbg_stmt,
317 .dbg_inline_begin,
318 .dbg_inline_end,
317319 .unreach,
318320 .fence,
319321 .ret_addr,
src/Sema.zig+37
......@@ -4639,6 +4639,10 @@ fn analyzeCall(
46394639 // comptime state.
46404640 var should_memoize = true;
46414641
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
46424646 // This will have return instructions analyzed as break instructions to
46434647 // the block_inst above. Here we are performing "comptime/inline semantic analysis"
46444648 // for a function body, which means we must map the parameter ZIR instructions to
......@@ -4658,6 +4662,7 @@ fn analyzeCall(
46584662 const param_body = sema.code.extra[extra.end..][0..extra.data.body_len];
46594663 const param_ty_inst = try sema.resolveBody(&child_block, param_body, inst);
46604664 const param_ty = try sema.analyzeAsType(&child_block, param_src, param_ty_inst);
4665 new_fn_info.param_types[arg_i] = param_ty;
46614666 const arg_src = call_src; // TODO: better source location
46624667 const casted_arg = try sema.coerce(&child_block, param_ty, uncasted_args[arg_i], arg_src);
46634668 try sema.inst_map.putNoClobber(gpa, inst, casted_arg);
......@@ -4685,6 +4690,7 @@ fn analyzeCall(
46854690 .param_anytype, .param_anytype_comptime => {
46864691 // No coercion needed.
46874692 const uncasted_arg = uncasted_args[arg_i];
4693 new_fn_info.param_types[arg_i] = sema.typeOf(uncasted_arg);
46884694 try sema.inst_map.putNoClobber(gpa, inst, uncasted_arg);
46894695
46904696 if (is_comptime_call) {
......@@ -4735,6 +4741,7 @@ fn analyzeCall(
47354741 }
47364742 break :blk bare_return_type;
47374743 };
4744 new_fn_info.return_type = fn_ret_ty;
47384745 const parent_fn_ret_ty = sema.fn_ret_ty;
47394746 sema.fn_ret_ty = fn_ret_ty;
47404747 defer sema.fn_ret_ty = parent_fn_ret_ty;
......@@ -4757,6 +4764,11 @@ fn analyzeCall(
47574764 }
47584765 }
47594766
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
47604772 const result = result: {
47614773 sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
47624774 error.ComptimeReturn => break :result inlining.comptime_result,
......@@ -4771,6 +4783,10 @@ fn analyzeCall(
47714783 break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges);
47724784 };
47734785
4786 if (!is_comptime_call) {
4787 try sema.emitDbgInline(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty, .dbg_inline_end);
4788 }
4789
47744790 if (should_memoize and is_comptime_call) {
47754791 const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result);
47764792
......@@ -5175,6 +5191,27 @@ fn instantiateGenericCall(
51755191 return func_inst;
51765192}
51775193
5194fn 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
51785215fn zirIntType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
51795216 _ = block;
51805217 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 {
649649 .dbg_var_val,
650650 => try self.airDbgVar(inst),
651651
652 .dbg_inline_begin,
653 .dbg_inline_end,
654 => try self.airDbgInline(inst),
655
652656 .call => try self.airCall(inst, .auto),
653657 .call_always_tail => try self.airCall(inst, .always_tail),
654658 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -2715,6 +2719,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
27152719 return self.finishAirBookkeeping();
27162720}
27172721
2722fn 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
27182730fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
27192731 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
27202732 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 {
646646 .dbg_var_val,
647647 => try self.airDbgVar(inst),
648648
649 .dbg_inline_begin,
650 .dbg_inline_end,
651 => try self.airDbgInline(inst),
652
649653 .call => try self.airCall(inst, .auto),
650654 .call_always_tail => try self.airCall(inst, .always_tail),
651655 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -2835,6 +2839,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
28352839 return self.finishAirBookkeeping();
28362840}
28372841
2842fn 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
28382850fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
28392851 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
28402852 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 {
613613 .dbg_var_val,
614614 => try self.airDbgVar(inst),
615615
616 .dbg_inline_begin,
617 .dbg_inline_end,
618 => try self.airDbgInline(inst),
619
616620 .call => try self.airCall(inst, .auto),
617621 .call_always_tail => try self.airCall(inst, .always_tail),
618622 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -1640,6 +1644,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
16401644 return self.finishAirBookkeeping();
16411645}
16421646
1647fn 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
16431655fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
16441656 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
16451657 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 {
12271227
12281228 // TODO
12291229 .dbg_stmt,
1230 .dbg_inline_begin,
1231 .dbg_inline_end,
12301232 .dbg_var_ptr,
12311233 .dbg_var_val,
12321234 => WValue.none,
src/arch/x86_64/CodeGen.zig+12
......@@ -730,6 +730,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
730730 .dbg_var_val,
731731 => try self.airDbgVar(inst),
732732
733 .dbg_inline_begin,
734 .dbg_inline_end,
735 => try self.airDbgInline(inst),
736
733737 .call => try self.airCall(inst, .auto),
734738 .call_always_tail => try self.airCall(inst, .always_tail),
735739 .call_never_tail => try self.airCall(inst, .never_tail),
......@@ -3670,6 +3674,14 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
36703674 return self.finishAirBookkeeping();
36713675}
36723676
3677fn 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
36733685fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
36743686 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
36753687 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
17261726 .dbg_var_val,
17271727 => try airDbgVar(f, inst),
17281728
1729 .dbg_inline_begin,
1730 .dbg_inline_end,
1731 => try airDbgInline(f, inst),
1732
17291733 .call => try airCall(f, inst, .auto),
17301734 .call_always_tail => try airCall(f, inst, .always_tail),
17311735 .call_never_tail => try airCall(f, inst, .never_tail),
......@@ -2660,6 +2664,14 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
26602664 return CValue.none;
26612665}
26622666
2667fn 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
26632675fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
26642676 const pl_op = f.air.instructions.items(.data)[inst].pl_op;
26652677 const name = f.air.nullTerminatedString(pl_op.payload);
src/codegen/llvm.zig+88-7
......@@ -620,7 +620,8 @@ pub const Object = struct {
620620
621621 llvm_func.fnSetSubprogram(subprogram);
622622
623 di_scope = subprogram.toScope();
623 const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file.?, line_number, 1);
624 di_scope = lexical_block.toScope();
624625 }
625626
626627 var fg: FuncGen = .{
......@@ -639,6 +640,7 @@ pub const Object = struct {
639640 .single_threaded = module.comp.bin_file.options.single_threaded,
640641 .di_scope = di_scope,
641642 .di_file = di_file,
643 .base_line = dg.decl.src_line,
642644 .prev_dbg_line = 0,
643645 .prev_dbg_column = 0,
644646 };
......@@ -1754,11 +1756,14 @@ pub const DeclGen = struct {
17541756 /// Note that this can be called before the function's semantic analysis has
17551757 /// completed, so if any attributes rely on that, they must be done in updateFunc, not here.
17561758 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 {
17571763 const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl);
17581764 if (gop.found_existing) return gop.value_ptr.*;
17591765
17601766 assert(decl.has_tv);
1761 const zig_fn_type = decl.ty;
17621767 const fn_info = zig_fn_type.fnInfo();
17631768 const target = dg.module.getTarget();
17641769 const sret = firstParamSRet(fn_info, target);
......@@ -3207,9 +3212,13 @@ pub const FuncGen = struct {
32073212 builder: *const llvm.Builder,
32083213 di_scope: ?*llvm.DIScope,
32093214 di_file: ?*llvm.DIFile,
3215 base_line: u32,
32103216 prev_dbg_line: c_uint,
32113217 prev_dbg_column: c_uint,
32123218
3219 /// Stack of locations where a call was inlined.
3220 dbg_inlined: std.ArrayListUnmanaged(DbgState) = .{},
3221
32133222 /// This stores the LLVM values used in a function, such that they can be referred to
32143223 /// in other instructions. This table is cleared before every function is generated.
32153224 func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value),
......@@ -3237,11 +3246,13 @@ pub const FuncGen = struct {
32373246
32383247 single_threaded: bool,
32393248
3249 const DbgState = struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 };
32403250 const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock);
32413251 const BreakValues = std.ArrayListUnmanaged(*const llvm.Value);
32423252
32433253 fn deinit(self: *FuncGen) void {
32443254 self.builder.dispose();
3255 self.dbg_inlined.deinit(self.gpa);
32453256 self.func_inst_table.deinit(self.gpa);
32463257 self.blocks.deinit(self.gpa);
32473258 }
......@@ -3460,6 +3471,8 @@ pub const FuncGen = struct {
34603471 .const_ty => unreachable,
34613472 .unreach => self.airUnreach(inst),
34623473 .dbg_stmt => self.airDbgStmt(inst),
3474 .dbg_inline_begin => try self.airDbgInline(inst, true),
3475 .dbg_inline_end => try self.airDbgInline(inst, false),
34633476 .dbg_var_ptr => try self.airDbgVarPtr(inst),
34643477 .dbg_var_val => try self.airDbgVarVal(inst),
34653478 // zig fmt: on
......@@ -4175,9 +4188,69 @@ pub const FuncGen = struct {
41754188 fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value {
41764189 const di_scope = self.di_scope orelse return null;
41774190 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);
41794192 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;
41814254 return null;
41824255 }
41834256
......@@ -4197,7 +4270,11 @@ pub const FuncGen = struct {
41974270 true, // always preserve
41984271 0, // flags
41994272 );
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);
42014278 const insert_block = self.builder.getInsertBlock();
42024279 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
42034280 return null;
......@@ -4219,7 +4296,11 @@ pub const FuncGen = struct {
42194296 true, // always preserve
42204297 0, // flags
42214298 );
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);
42234304 const insert_block = self.builder.getInsertBlock();
42244305 if (isByRef(operand_ty)) {
42254306 _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block);
......@@ -5481,7 +5562,7 @@ pub const FuncGen = struct {
54815562 self.arg_index, // includes +1 because 0 is return type
54825563 );
54835564
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);
54855566 const insert_block = self.builder.getInsertBlock();
54865567 if (isByRef(inst_ty)) {
54875568 _ = 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 {
839839 pub const buildExactSDiv = LLVMBuildExactSDiv;
840840 extern fn LLVMBuildExactSDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value;
841841
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;
844844
845845 pub const clearCurrentDebugLocation = ZigLLVMClearCurrentDebugLocation;
846846 extern fn ZigLLVMClearCurrentDebugLocation(builder: *const Builder) void;
......@@ -1479,8 +1479,8 @@ pub const DISubprogram = opaque {
14791479 extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void;
14801480};
14811481
1482pub const getDebugLoc = ZigLLVMGetDebugLoc;
1483extern fn ZigLLVMGetDebugLoc(line: c_uint, col: c_uint, scope: *DIScope) *DILocation;
1482pub const getDebugLoc = ZigLLVMGetDebugLoc2;
1483extern fn ZigLLVMGetDebugLoc2(line: c_uint, col: c_uint, scope: *DIScope, inlined_at: ?*DILocation) *DILocation;
14841484
14851485pub const DIBuilder = opaque {
14861486 pub const dispose = ZigLLVMDisposeDIBuilder;
src/print_air.zig+8
......@@ -242,6 +242,8 @@ const Writer = struct {
242242 .constant => try w.writeConstant(s, inst),
243243 .assembly => try w.writeAssembly(s, inst),
244244 .dbg_stmt => try w.writeDbgStmt(s, inst),
245
246 .dbg_inline_begin, .dbg_inline_end => try w.writeDbgInline(s, inst),
245247 .aggregate_init => try w.writeAggregateInit(s, inst),
246248 .union_init => try w.writeUnionInit(s, inst),
247249 .br => try w.writeBr(s, inst),
......@@ -552,6 +554,12 @@ const Writer = struct {
552554 try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 });
553555 }
554556
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
555563 fn writeDbgVar(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
556564 const pl_op = w.air.instructions.items(.data)[inst].pl_op;
557565 try w.writeOperand(s, inst, 0, pl_op.operand);
src/type.zig+30
......@@ -486,6 +486,36 @@ pub const Type = extern union {
486486
487487 .pointer => return self.castTag(.pointer).?.*,
488488
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
489519 else => unreachable,
490520 }
491521 }
src/zig_llvm.cpp+17
......@@ -799,6 +799,15 @@ void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder,
799799 unwrap(builder)->SetCurrentDebugLocation(debug_loc);
800800}
801801
802void 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
802811void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) {
803812 unwrap(builder)->SetCurrentDebugLocation(DebugLoc());
804813}
......@@ -1025,6 +1034,14 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop
10251034 return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get());
10261035}
10271036
1037ZigLLVMDILocation *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
10281045void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {
10291046 if (on_state) {
10301047 FastMathFlags fmf;
src/zig_llvm.h+4
......@@ -232,6 +232,8 @@ ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel
232232
233233ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder,
234234 unsigned int line, unsigned int column, struct ZigLLVMDIScope *scope);
235ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line,
236 unsigned int column, ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at);
235237ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder);
236238
237239ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block);
......@@ -290,6 +292,8 @@ ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder);
290292
291293ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col,
292294 struct ZigLLVMDIScope *scope);
295ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col,
296 ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at);
293297
294298ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dib,
295299 LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info,