From 03438118369605df178f4bfdb5b1a8ad6a349be7 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 15 Mar 2022 16:42:26 +0200 Subject: Sema: emit dbg_func around inline calls --- src/codegen/llvm.zig | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'src/codegen/llvm.zig') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index c4b381f6d6..e8c527c112 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1754,11 +1754,14 @@ pub const DeclGen = struct { /// Note that this can be called before the function's semantic analysis has /// completed, so if any attributes rely on that, they must be done in updateFunc, not here. fn resolveLlvmFunction(dg: *DeclGen, decl: *Module.Decl) !*const llvm.Value { + return dg.resolveLlvmFunctionExtra(decl, decl.ty); + } + + fn resolveLlvmFunctionExtra(dg: *DeclGen, decl: *Module.Decl, zig_fn_type: Type) !*const llvm.Value { const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl); if (gop.found_existing) return gop.value_ptr.*; assert(decl.has_tv); - const zig_fn_type = decl.ty; const fn_info = zig_fn_type.fnInfo(); const target = dg.module.getTarget(); const sret = firstParamSRet(fn_info, target); @@ -3460,6 +3463,7 @@ pub const FuncGen = struct { .const_ty => unreachable, .unreach => self.airUnreach(inst), .dbg_stmt => self.airDbgStmt(inst), + .dbg_func => try self.airDbgFunc(inst), .dbg_var_ptr => try self.airDbgVarPtr(inst), .dbg_var_val => try self.airDbgVarVal(inst), // zig fmt: on @@ -4181,6 +4185,45 @@ pub const FuncGen = struct { return null; } + fn airDbgFunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { + const dib = self.dg.object.di_builder orelse return null; + const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; + + const function = self.air.values[ty_pl.payload].castTag(.function).?.data; + const decl = function.owner_decl; + const fn_ty = try self.air.getRefType(ty_pl.ty).copy(self.dg.object.type_map_arena.allocator()); + const llvm_func = try self.dg.resolveLlvmFunctionExtra(decl, fn_ty); + const fn_info = fn_ty.fnInfo(); + const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope); + + const line_number = decl.src_line + 1; + const is_internal_linkage = !self.dg.module.decl_exports.contains(decl); + const noret_bit: c_uint = if (fn_info.return_type.isNoReturn()) + llvm.DIFlags.NoReturn + else + 0; + const subprogram = dib.createFunction( + di_file.toScope(), + decl.name, + llvm_func.getValueName(), + di_file, + line_number, + try self.dg.lowerDebugType(fn_ty), + is_internal_linkage, + true, // is definition + line_number + function.lbrace_line, // scope line + llvm.DIFlags.StaticMember | noret_bit, + self.dg.module.comp.bin_file.options.optimize_mode != .Debug, + null, // decl_subprogram + ); + try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode()); + + llvm_func.fnSetSubprogram(subprogram); + + self.di_scope = subprogram.toScope(); + return null; + } + fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { const dib = self.dg.object.di_builder orelse return null; const pl_op = self.air.instructions.items(.data)[inst].pl_op; -- cgit v1.2.3 From d83a26f068f42c6f9cafd25b7038b70553a496d8 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Tue, 15 Mar 2022 18:27:09 +0200 Subject: stage2 llvm: keep track of inlined functions --- src/Air.zig | 10 ++++-- src/Liveness.zig | 3 +- src/Sema.zig | 15 ++++++--- src/arch/aarch64/CodeGen.zig | 7 ++-- src/arch/arm/CodeGen.zig | 7 ++-- src/arch/riscv64/CodeGen.zig | 7 ++-- src/arch/wasm/CodeGen.zig | 3 +- src/arch/x86_64/CodeGen.zig | 7 ++-- src/codegen/c.zig | 7 ++-- src/codegen/llvm.zig | 78 ++++++++++++++++++++++++++++++++----------- src/codegen/llvm/bindings.zig | 8 ++--- src/print_air.zig | 5 +-- src/zig_llvm.cpp | 17 ++++++++++ src/zig_llvm.h | 4 +++ 14 files changed, 132 insertions(+), 46 deletions(-) (limited to 'src/codegen/llvm.zig') diff --git a/src/Air.zig b/src/Air.zig index 2097be073a..45cae07f6a 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -326,9 +326,12 @@ pub const Inst = struct { /// Result type is always void. /// Uses the `dbg_stmt` field. dbg_stmt, - /// Marks change of source function. Emitted around an inline call. + /// Marks the start of an inline call. /// Uses `ty_pl` with the payload being the index of a Value.Function in air.values. - dbg_func, + dbg_inline_begin, + /// Marks the end of an inline call. + /// Uses `ty_pl` with the payload being the index of a Value.Function in air.values. + dbg_inline_end, /// Marks the beginning of a local variable. The operand is a pointer pointing /// to the storage for the variable. The local may be a const or a var. /// Result type is always void. @@ -973,7 +976,8 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type { .breakpoint, .dbg_stmt, - .dbg_func, + .dbg_inline_begin, + .dbg_inline_end, .dbg_var_ptr, .dbg_var_val, .store, diff --git a/src/Liveness.zig b/src/Liveness.zig index 54acc62962..45558c6811 100644 --- a/src/Liveness.zig +++ b/src/Liveness.zig @@ -314,7 +314,8 @@ fn analyzeInst( .const_ty, .breakpoint, .dbg_stmt, - .dbg_func, + .dbg_inline_begin, + .dbg_inline_end, .unreach, .fence, .ret_addr, diff --git a/src/Sema.zig b/src/Sema.zig index 81bdc821d8..ca341bfeac 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -4765,7 +4765,9 @@ fn analyzeCall( } const new_func_resolved_ty = try Type.Tag.function.create(sema.arena, new_fn_info); - if (!is_comptime_call) try sema.emitDbgFunc(block, parent_func.?, module_fn, new_func_resolved_ty); + if (!is_comptime_call) { + try sema.emitDbgInline(block, parent_func.?, module_fn, new_func_resolved_ty, .dbg_inline_begin); + } const result = result: { sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) { @@ -4781,7 +4783,9 @@ fn analyzeCall( break :result try sema.analyzeBlockBody(block, call_src, &child_block, merges); }; - if (!is_comptime_call) try sema.emitDbgFunc(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty); + if (!is_comptime_call) { + try sema.emitDbgInline(block, module_fn, parent_func.?, parent_func.?.owner_decl.ty, .dbg_inline_end); + } if (should_memoize and is_comptime_call) { const result_val = try sema.resolveConstMaybeUndefVal(block, call_src, result); @@ -5187,19 +5191,20 @@ fn instantiateGenericCall( return func_inst; } -fn emitDbgFunc( +fn emitDbgInline( sema: *Sema, block: *Block, old_func: *Module.Fn, new_func: *Module.Fn, new_func_ty: Type, + tag: Air.Inst.Tag, ) CompileError!void { - // No change of file; no dbg_func needed. + // No change of file; no dbg_inline needed. if (old_func == new_func) return; try sema.air_values.append(sema.gpa, try Value.Tag.function.create(sema.arena, new_func)); _ = try block.addInst(.{ - .tag = .dbg_func, + .tag = tag, .data = .{ .ty_pl = .{ .ty = try sema.addType(new_func_ty), .payload = @intCast(u32, sema.air_values.items.len - 1), diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 2dca8e2dfe..dddd4a27a1 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -598,7 +598,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .fence => try self.airFence(), .cond_br => try self.airCondBr(inst), .dbg_stmt => try self.airDbgStmt(inst), - .dbg_func => try self.airDbgFunc(inst), .fptrunc => try self.airFptrunc(inst), .fpext => try self.airFpext(inst), .intcast => try self.airIntCast(inst), @@ -650,6 +649,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .dbg_var_val, => try self.airDbgVar(inst), + .dbg_inline_begin, + .dbg_inline_end, + => try self.airDbgInline(inst), + .call => try self.airCall(inst, .auto), .call_always_tail => try self.airCall(inst, .always_tail), .call_never_tail => try self.airCall(inst, .never_tail), @@ -2716,7 +2719,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { return self.finishAirBookkeeping(); } -fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void { +fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const function = self.air.values[ty_pl.payload].castTag(.function).?.data; // TODO emit debug info for function change diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 10a6348d4f..0ccec1be88 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -595,7 +595,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .fence => try self.airFence(), .cond_br => try self.airCondBr(inst), .dbg_stmt => try self.airDbgStmt(inst), - .dbg_func => try self.airDbgFunc(inst), .fptrunc => try self.airFptrunc(inst), .fpext => try self.airFpext(inst), .intcast => try self.airIntCast(inst), @@ -647,6 +646,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .dbg_var_val, => try self.airDbgVar(inst), + .dbg_inline_begin, + .dbg_inline_end, + => try self.airDbgInline(inst), + .call => try self.airCall(inst, .auto), .call_always_tail => try self.airCall(inst, .always_tail), .call_never_tail => try self.airCall(inst, .never_tail), @@ -2836,7 +2839,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { return self.finishAirBookkeeping(); } -fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void { +fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const function = self.air.values[ty_pl.payload].castTag(.function).?.data; // TODO emit debug info for function change diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 1604f04526..0b8cbc2d62 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -562,7 +562,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .fence => try self.airFence(), .cond_br => try self.airCondBr(inst), .dbg_stmt => try self.airDbgStmt(inst), - .dbg_func => try self.airDbgFunc(inst), .fptrunc => try self.airFptrunc(inst), .fpext => try self.airFpext(inst), .intcast => try self.airIntCast(inst), @@ -614,6 +613,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .dbg_var_val, => try self.airDbgVar(inst), + .dbg_inline_begin, + .dbg_inline_end, + => try self.airDbgInline(inst), + .call => try self.airCall(inst, .auto), .call_always_tail => try self.airCall(inst, .always_tail), .call_never_tail => try self.airCall(inst, .never_tail), @@ -1641,7 +1644,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { return self.finishAirBookkeeping(); } -fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void { +fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const function = self.air.values[ty_pl.payload].castTag(.function).?.data; // TODO emit debug info for function change diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 849fc597c8..33fb35163a 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1227,7 +1227,8 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { // TODO .dbg_stmt, - .dbg_func, + .dbg_inline_begin, + .dbg_inline_end, .dbg_var_ptr, .dbg_var_val, => WValue.none, diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index cecff3b53b..63c85a5a9e 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -679,7 +679,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .fence => try self.airFence(), .cond_br => try self.airCondBr(inst), .dbg_stmt => try self.airDbgStmt(inst), - .dbg_func => try self.airDbgFunc(inst), .fptrunc => try self.airFptrunc(inst), .fpext => try self.airFpext(inst), .intcast => try self.airIntCast(inst), @@ -731,6 +730,10 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { .dbg_var_val, => try self.airDbgVar(inst), + .dbg_inline_begin, + .dbg_inline_end, + => try self.airDbgInline(inst), + .call => try self.airCall(inst, .auto), .call_always_tail => try self.airCall(inst, .always_tail), .call_never_tail => try self.airCall(inst, .never_tail), @@ -3671,7 +3674,7 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void { return self.finishAirBookkeeping(); } -fn airDbgFunc(self: *Self, inst: Air.Inst.Index) !void { +fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const function = self.air.values[ty_pl.payload].castTag(.function).?.data; // TODO emit debug info for function change diff --git a/src/codegen/c.zig b/src/codegen/c.zig index c726f659a1..358e7354dd 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -1687,7 +1687,6 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .block => try airBlock(f, inst), .bitcast => try airBitcast(f, inst), .dbg_stmt => try airDbgStmt(f, inst), - .dbg_func => try airDbgFunc(f, inst), .intcast => try airIntCast(f, inst), .trunc => try airTrunc(f, inst), .bool_to_int => try airBoolToInt(f, inst), @@ -1727,6 +1726,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO .dbg_var_val, => try airDbgVar(f, inst), + .dbg_inline_begin, + .dbg_inline_end, + => try airDbgInline(f, inst), + .call => try airCall(f, inst, .auto), .call_always_tail => try airCall(f, inst, .always_tail), .call_never_tail => try airCall(f, inst, .never_tail), @@ -2661,7 +2664,7 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { return CValue.none; } -fn airDbgFunc(f: *Function, inst: Air.Inst.Index) !CValue { +fn airDbgInline(f: *Function, inst: Air.Inst.Index) !CValue { const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; const writer = f.object.writer(); const function = f.air.values[ty_pl.payload].castTag(.function).?.data; diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index e8c527c112..9321b26e15 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -620,7 +620,8 @@ pub const Object = struct { llvm_func.fnSetSubprogram(subprogram); - di_scope = subprogram.toScope(); + const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file.?, line_number, 1); + di_scope = lexical_block.toScope(); } var fg: FuncGen = .{ @@ -639,6 +640,7 @@ pub const Object = struct { .single_threaded = module.comp.bin_file.options.single_threaded, .di_scope = di_scope, .di_file = di_file, + .base_line = dg.decl.src_line, .prev_dbg_line = 0, .prev_dbg_column = 0, }; @@ -3210,9 +3212,13 @@ pub const FuncGen = struct { builder: *const llvm.Builder, di_scope: ?*llvm.DIScope, di_file: ?*llvm.DIFile, + base_line: u32, prev_dbg_line: c_uint, prev_dbg_column: c_uint, + /// Stack of locations where a call was inlined. + dbg_inlined: std.ArrayListUnmanaged(DbgState) = .{}, + /// This stores the LLVM values used in a function, such that they can be referred to /// in other instructions. This table is cleared before every function is generated. func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value), @@ -3240,11 +3246,13 @@ pub const FuncGen = struct { single_threaded: bool, + const DbgState = struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 }; const BreakBasicBlocks = std.ArrayListUnmanaged(*const llvm.BasicBlock); const BreakValues = std.ArrayListUnmanaged(*const llvm.Value); fn deinit(self: *FuncGen) void { self.builder.dispose(); + self.dbg_inlined.deinit(self.gpa); self.func_inst_table.deinit(self.gpa); self.blocks.deinit(self.gpa); } @@ -3463,7 +3471,8 @@ pub const FuncGen = struct { .const_ty => unreachable, .unreach => self.airUnreach(inst), .dbg_stmt => self.airDbgStmt(inst), - .dbg_func => try self.airDbgFunc(inst), + .dbg_inline_begin => try self.airDbgInline(inst, true), + .dbg_inline_end => try self.airDbgInline(inst, false), .dbg_var_ptr => try self.airDbgVarPtr(inst), .dbg_var_val => try self.airDbgVarVal(inst), // zig fmt: on @@ -4179,24 +4188,44 @@ pub const FuncGen = struct { fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value { const di_scope = self.di_scope orelse return null; const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; - self.prev_dbg_line = @intCast(c_uint, self.dg.decl.src_line + dbg_stmt.line + 1); + self.prev_dbg_line = @intCast(c_uint, self.base_line + dbg_stmt.line + 1); self.prev_dbg_column = @intCast(c_uint, dbg_stmt.column + 1); - self.builder.setCurrentDebugLocation(self.prev_dbg_line, self.prev_dbg_column, di_scope); + const inlined_at = if (self.dbg_inlined.items.len > 0) + self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc + else + null; + self.builder.setCurrentDebugLocation(self.prev_dbg_line, self.prev_dbg_column, di_scope, inlined_at); return null; } - fn airDbgFunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { + fn airDbgInline(self: *FuncGen, inst: Air.Inst.Index, start: bool) !?*const llvm.Value { const dib = self.dg.object.di_builder orelse return null; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; - - const function = self.air.values[ty_pl.payload].castTag(.function).?.data; - const decl = function.owner_decl; + + const func = self.air.values[ty_pl.payload].castTag(.function).?.data; + const decl = func.owner_decl; + const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope); + self.di_file = di_file; + const line_number = decl.src_line + 1; + const cur_debug_location = self.builder.getCurrentDebugLocation2(); + if (start) { + try self.dbg_inlined.append(self.gpa, .{ + .loc = @ptrCast(*llvm.DILocation, cur_debug_location), + .scope = self.di_scope.?, + .base_line = self.base_line, + }); + } else { + const old = self.dbg_inlined.pop(); + self.di_scope = old.scope; + self.base_line = old.base_line; + return null; + } + const fn_ty = try self.air.getRefType(ty_pl.ty).copy(self.dg.object.type_map_arena.allocator()); - const llvm_func = try self.dg.resolveLlvmFunctionExtra(decl, fn_ty); + const fqn = try decl.getFullyQualifiedName(self.gpa); + defer self.gpa.free(fqn); const fn_info = fn_ty.fnInfo(); - const di_file = try self.dg.object.getDIFile(self.gpa, decl.src_namespace.file_scope); - const line_number = decl.src_line + 1; const is_internal_linkage = !self.dg.module.decl_exports.contains(decl); const noret_bit: c_uint = if (fn_info.return_type.isNoReturn()) llvm.DIFlags.NoReturn @@ -4205,22 +4234,23 @@ pub const FuncGen = struct { const subprogram = dib.createFunction( di_file.toScope(), decl.name, - llvm_func.getValueName(), + fqn, di_file, line_number, - try self.dg.lowerDebugType(fn_ty), + try self.dg.object.lowerDebugType(fn_ty, .full), is_internal_linkage, true, // is definition - line_number + function.lbrace_line, // scope line + line_number + func.lbrace_line, // scope line llvm.DIFlags.StaticMember | noret_bit, self.dg.module.comp.bin_file.options.optimize_mode != .Debug, null, // decl_subprogram ); - try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode()); - llvm_func.fnSetSubprogram(subprogram); + try self.dg.object.di_map.put(self.gpa, decl, subprogram.toNode()); - self.di_scope = subprogram.toScope(); + const lexical_block = dib.createLexicalBlock(subprogram.toScope(), di_file, line_number, 1); + self.di_scope = lexical_block.toScope(); + self.base_line = decl.src_line; return null; } @@ -4240,7 +4270,11 @@ pub const FuncGen = struct { true, // always preserve 0, // flags ); - const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?); + const inlined_at = if (self.dbg_inlined.items.len > 0) + self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc + else + null; + const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at); const insert_block = self.builder.getInsertBlock(); _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block); return null; @@ -4262,7 +4296,11 @@ pub const FuncGen = struct { true, // always preserve 0, // flags ); - const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?); + const inlined_at = if (self.dbg_inlined.items.len > 0) + self.dbg_inlined.items[self.dbg_inlined.items.len - 1].loc + else + null; + const debug_loc = llvm.getDebugLoc(self.prev_dbg_line, self.prev_dbg_column, self.di_scope.?, inlined_at); const insert_block = self.builder.getInsertBlock(); if (isByRef(operand_ty)) { _ = dib.insertDeclareAtEnd(operand, di_local_var, debug_loc, insert_block); @@ -5524,7 +5562,7 @@ pub const FuncGen = struct { self.arg_index, // includes +1 because 0 is return type ); - const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?); + const debug_loc = llvm.getDebugLoc(lbrace_line, lbrace_col, self.di_scope.?, null); const insert_block = self.builder.getInsertBlock(); if (isByRef(inst_ty)) { _ = dib.insertDeclareAtEnd(arg_val, di_local_var, debug_loc, insert_block); diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index c54d226f66..a6c53fddce 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -839,8 +839,8 @@ pub const Builder = opaque { pub const buildExactSDiv = LLVMBuildExactSDiv; extern fn LLVMBuildExactSDiv(*const Builder, LHS: *const Value, RHS: *const Value, Name: [*:0]const u8) *const Value; - pub const setCurrentDebugLocation = ZigLLVMSetCurrentDebugLocation; - extern fn ZigLLVMSetCurrentDebugLocation(builder: *const Builder, line: c_uint, column: c_uint, scope: *DIScope) void; + pub const setCurrentDebugLocation = ZigLLVMSetCurrentDebugLocation2; + extern fn ZigLLVMSetCurrentDebugLocation2(builder: *const Builder, line: c_uint, column: c_uint, scope: *DIScope, inlined_at: ?*DILocation) void; pub const clearCurrentDebugLocation = ZigLLVMClearCurrentDebugLocation; extern fn ZigLLVMClearCurrentDebugLocation(builder: *const Builder) void; @@ -1479,8 +1479,8 @@ pub const DISubprogram = opaque { extern fn ZigLLVMSubprogramReplaceLinkageName(subprogram: *DISubprogram, linkage_name: *MDString) void; }; -pub const getDebugLoc = ZigLLVMGetDebugLoc; -extern fn ZigLLVMGetDebugLoc(line: c_uint, col: c_uint, scope: *DIScope) *DILocation; +pub const getDebugLoc = ZigLLVMGetDebugLoc2; +extern fn ZigLLVMGetDebugLoc2(line: c_uint, col: c_uint, scope: *DIScope, inlined_at: ?*DILocation) *DILocation; pub const DIBuilder = opaque { pub const dispose = ZigLLVMDisposeDIBuilder; diff --git a/src/print_air.zig b/src/print_air.zig index 3d1d17107c..7442d276c3 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -242,7 +242,8 @@ const Writer = struct { .constant => try w.writeConstant(s, inst), .assembly => try w.writeAssembly(s, inst), .dbg_stmt => try w.writeDbgStmt(s, inst), - .dbg_func => try w.writeDbgFunc(s, inst), + + .dbg_inline_begin, .dbg_inline_end => try w.writeDbgInline(s, inst), .aggregate_init => try w.writeAggregateInit(s, inst), .union_init => try w.writeUnionInit(s, inst), .br => try w.writeBr(s, inst), @@ -553,7 +554,7 @@ const Writer = struct { try s.print("{d}:{d}", .{ dbg_stmt.line + 1, dbg_stmt.column + 1 }); } - fn writeDbgFunc(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + fn writeDbgInline(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; const function = w.air.values[ty_pl.payload].castTag(.function).?.data; try s.print("{s}", .{function.owner_decl.name}); diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 6e3cccafeb..0b0b33b8d9 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -799,6 +799,15 @@ void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, unwrap(builder)->SetCurrentDebugLocation(debug_loc); } +void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line, + unsigned int column, ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at) +{ + DIScope* di_scope = reinterpret_cast(scope); + DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, column, di_scope, + reinterpret_cast(inlined_at), false); + unwrap(builder)->SetCurrentDebugLocation(debug_loc); +} + void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) { unwrap(builder)->SetCurrentDebugLocation(DebugLoc()); } @@ -1025,6 +1034,14 @@ ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScop return reinterpret_cast(debug_loc.get()); } +ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col, ZigLLVMDIScope *scope, + ZigLLVMDILocation *inlined_at) { + DIScope* di_scope = reinterpret_cast(scope); + DebugLoc debug_loc = DILocation::get(di_scope->getContext(), line, col, di_scope, + reinterpret_cast(inlined_at), false); + return reinterpret_cast(debug_loc.get()); +} + void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) { if (on_state) { FastMathFlags fmf; diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 5fe0142e76..761fca86be 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -232,6 +232,8 @@ ZIG_EXTERN_C void ZigLLVMSetModuleCodeModel(LLVMModuleRef module, LLVMCodeModel ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, unsigned int line, unsigned int column, struct ZigLLVMDIScope *scope); +ZIG_EXTERN_C void ZigLLVMSetCurrentDebugLocation2(LLVMBuilderRef builder, unsigned int line, + unsigned int column, ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at); ZIG_EXTERN_C void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder); ZIG_EXTERN_C struct ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(struct ZigLLVMDILexicalBlock *lexical_block); @@ -290,6 +292,8 @@ ZIG_EXTERN_C void ZigLLVMDIBuilderFinalize(struct ZigLLVMDIBuilder *dibuilder); ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, struct ZigLLVMDIScope *scope); +ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc2(unsigned line, unsigned col, + ZigLLVMDIScope *scope, ZigLLVMDILocation *inlined_at); ZIG_EXTERN_C LLVMValueRef ZigLLVMInsertDeclareAtEnd(struct ZigLLVMDIBuilder *dib, LLVMValueRef storage, struct ZigLLVMDILocalVariable *var_info, -- cgit v1.2.3