aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig9
-rw-r--r--src/codegen/llvm.zig45
2 files changed, 53 insertions, 1 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 05ceb30379..c726f659a1 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -1687,6 +1687,7 @@ 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),
@@ -2660,6 +2661,14 @@ fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue {
return CValue.none;
}
+fn airDbgFunc(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;
+ try writer.print("/* dbg func:{s} */\n", .{function.owner_decl.name});
+ return CValue.none;
+}
+
fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue {
const pl_op = f.air.instructions.items(.data)[inst].pl_op;
const name = f.air.nullTerminatedString(pl_op.payload);
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;