I have some code that JIT compiles C++ code and I’m now trying to debug the JITted code. The minimum example code is
llvm::SmallVector<const char *, 8> args;
args.push_back("test.cpp");
args.push_back("-debug-info-kind=standalone");
auto diagnostic_options = llvm::makeIntrusiveRefCnt<clang::DiagnosticOptions> ();
auto diagnostic_printer = std::make_unique<clang::TextDiagnosticPrinter> (llvm::errs(),
diagnostic_options.get());
auto diagnostic_ids = llvm::makeIntrusiveRefCnt<clang::DiagnosticIDs> ();
clang::DiagnosticsEngine diagnostic_engine(diagnostic_ids,
diagnostic_options,
diagnostic_printer.release());
auto invocation = std::make_shared<clang::CompilerInvocation> ();
clang::CompilerInvocation::CreateFromArgs(*(invocation.get()), args,
diagnostic_engine);
llvm::StringRef source_code_data("float add(float a, float b) {return a+b;}");
auto buffer = llvm::MemoryBuffer::getMemBuffer(source_code_data);
invocation->getPreprocessorOpts().addRemappedFile("test.cpp",
buffer.release());
clang::CompilerInstance clang;
clang.setInvocation(invocation);
clang.createDiagnostics();
const auto target_options = std::make_shared<clang::TargetOptions> ();
target_options->Triple = llvm::sys::getProcessTriple();
auto *target_info = clang::TargetInfo::CreateTargetInfo(diagnostic_engine,
target_options);
clang.setTarget(target_info);
clang::EmitLLVMAction action;
clang.ExecuteAction(action);
This generates a test.ll
which is missing debug info.
; ModuleID = 'test.cpp'
source_filename = "test.cpp"
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-macosx14.0.0"
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
define float @_Z3addff(float noundef %0, float noundef %1) #0 {
%3 = alloca float, align 4
%4 = alloca float, align 4
store float %0, ptr %3, align 4
store float %1, ptr %4, align 4
%5 = load float, ptr %3, align 4
%6 = load float, ptr %4, align 4
%7 = fadd float %5, %6
ret float %7
}
attributes #0 = { noinline nounwind optnone ssp uwtable(sync) "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "probe-stack"="__chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+zcm,+zcz" }
!llvm.module.flags = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 14, i32 5]}
!1 = !{i32 1, !"wchar_size", i32 4}
!2 = !{i32 8, !"PIC Level", i32 2}
!3 = !{i32 7, !"uwtable", i32 1}
!4 = !{i32 7, !"frame-pointer", i32 1}
!5 = !{!"Apple clang version 15.0.0 (clang-1500.3.9.4)"}
If I compile this using clang++ -g -S -emit-llvm test.cpp
.
; ModuleID = 'test.cpp'
source_filename = "test.cpp"
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
target triple = "arm64-apple-macosx14.0.0"
; Function Attrs: noinline nounwind optnone ssp uwtable(sync)
define float @_Z3addff(float noundef %0, float noundef %1) #0 !dbg !10 {
%3 = alloca float, align 4
%4 = alloca float, align 4
store float %0, ptr %3, align 4
call void @llvm.dbg.declare(metadata ptr %3, metadata !15, metadata !DIExpression()), !dbg !16
store float %1, ptr %4, align 4
call void @llvm.dbg.declare(metadata ptr %4, metadata !17, metadata !DIExpression()), !dbg !18
%5 = load float, ptr %3, align 4, !dbg !19
%6 = load float, ptr %4, align 4, !dbg !20
%7 = fadd float %5, %6, !dbg !21
ret float %7, !dbg !22
}
; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn
declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
attributes #0 = { noinline nounwind optnone ssp uwtable(sync) "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "probe-stack"="__chkstk_darwin" "stack-protector-buffer-size"="8" "target-cpu"="apple-m1" "target-features"="+aes,+crc,+crypto,+dotprod,+fp-armv8,+fp16fml,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+sha2,+sha3,+sm4,+v8.1a,+v8.2a,+v8.3a,+v8.4a,+v8.5a,+v8a,+zcm,+zcz" }
attributes #1 = { nocallback nofree nosync nounwind readnone speculatable willreturn }
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6}
!llvm.dbg.cu = !{!7}
!llvm.ident = !{!9}
!0 = !{i32 2, !"SDK Version", [2 x i32] [i32 14, i32 5]}
!1 = !{i32 7, !"Dwarf Version", i32 4}
!2 = !{i32 2, !"Debug Info Version", i32 3}
!3 = !{i32 1, !"wchar_size", i32 4}
!4 = !{i32 8, !"PIC Level", i32 2}
!5 = !{i32 7, !"uwtable", i32 1}
!6 = !{i32 7, !"frame-pointer", i32 1}
!7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !8, producer: "Apple clang version 15.0.0 (clang-1500.3.9.4)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None, sysroot: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk", sdk: "MacOSX.sdk")
!8 = !DIFile(filename: "test.cpp", directory: "/Users/m4c/Desktop/debug")
!9 = !{!"Apple clang version 15.0.0 (clang-1500.3.9.4)"}
!10 = distinct !DISubprogram(name: "add", linkageName: "_Z3addff", scope: !8, file: !8, line: 1, type: !11, scopeLine: 1, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !14)
!11 = !DISubroutineType(types: !12)
!12 = !{!13, !13, !13}
!13 = !DIBasicType(name: "float", size: 32, encoding: DW_ATE_float)
!14 = !{}
!15 = !DILocalVariable(name: "a", arg: 1, scope: !10, file: !8, line: 1, type: !13)
!16 = !DILocation(line: 1, column: 17, scope: !10)
!17 = !DILocalVariable(name: "b", arg: 2, scope: !10, file: !8, line: 1, type: !13)
!18 = !DILocation(line: 1, column: 26, scope: !10)
!19 = !DILocation(line: 1, column: 37, scope: !10)
!20 = !DILocation(line: 1, column: 39, scope: !10)
!21 = !DILocation(line: 1, column: 38, scope: !10)
!22 = !DILocation(line: 1, column: 30, scope: !10)
How do I get the clang api to generate debug information?