debuginfo: emit DW_TAG_call_site entries

This commit is contained in:
Scott Young
2026-03-20 17:20:06 -04:00
committed by Scott Young
parent 562dee4820
commit 9677d7a587
4 changed files with 28 additions and 3 deletions
@@ -471,7 +471,7 @@ fn dbg_scope_fn(
// FIXME(eddyb) does this need to be separate from `loc.line` for some reason?
let scope_line = loc.line;
let mut flags = DIFlags::FlagPrototyped;
let mut flags = DIFlags::FlagPrototyped | DIFlags::FlagAllCallsDescribed;
if fn_abi.ret.layout.is_uninhabited() {
flags |= DIFlags::FlagNoReturn;
@@ -494,6 +494,9 @@ fn dbg_scope_fn(
// LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition.
// When we use this `decl` below, the subprogram definition gets created at the CU level
// with a DW_AT_specification pointing back to the type's declaration.
// FlagAllCallsDescribed cannot appear on the method declaration DIE
// because it has no body, which LLVM's verifier rejects.
let decl_flags = flags & !DIFlags::FlagAllCallsDescribed;
let decl = is_method.then(|| unsafe {
llvm::LLVMRustDIBuilderCreateMethod(
DIB(self),
@@ -505,7 +508,7 @@ fn dbg_scope_fn(
file_metadata,
loc.line,
function_type_metadata,
flags,
decl_flags,
spflags & !DISPFlags::SPFlagDefinition,
template_parameters,
)
@@ -779,6 +779,7 @@ pub(crate) struct DIFlags: u32 {
const FlagNonTrivial = (1 << 26);
const FlagBigEndian = (1 << 27);
const FlagLittleEndian = (1 << 28);
const FlagAllCallsDescribed = (1 << 29);
}
}
@@ -779,6 +779,7 @@ ASSERT_DIFLAG_VALUE(FlagThunk, 1 << 25);
ASSERT_DIFLAG_VALUE(FlagNonTrivial, 1 << 26);
ASSERT_DIFLAG_VALUE(FlagBigEndian, 1 << 27);
ASSERT_DIFLAG_VALUE(FlagLittleEndian, 1 << 28);
static_assert(DINode::DIFlags::FlagAllCallsDescribed == (1 << 29));
ASSERT_DIFLAG_VALUE(FlagIndirectVirtualBase, (1 << 2) | (1 << 5));
#undef ASSERT_DIFLAG_VALUE
@@ -791,7 +792,7 @@ ASSERT_DIFLAG_VALUE(FlagIndirectVirtualBase, (1 << 2) | (1 << 5));
// to copying each bit/subvalue.
static DINode::DIFlags fromRust(LLVMDIFlags Flags) {
// Check that all set bits are covered by the static assertions above.
const unsigned UNKNOWN_BITS = (1 << 31) | (1 << 30) | (1 << 29) | (1 << 21);
const unsigned UNKNOWN_BITS = (1 << 31) | (1 << 30) | (1 << 21);
if (Flags & UNKNOWN_BITS) {
report_fatal_error("bad LLVMDIFlags");
}
@@ -0,0 +1,20 @@
// Check that DIFlagAllCallsDescribed is set on subprogram definitions.
//@ ignore-msvc (CodeView does not use DIFlagAllCallsDescribed)
//@ compile-flags: -C debuginfo=2 -C opt-level=1 -C no-prepopulate-passes
// CHECK: {{.*}}DISubprogram{{.*}}name: "foo"{{.*}}DIFlagAllCallsDescribed{{.*}}
#[no_mangle]
#[inline(never)]
pub fn foo(x: i32) -> i32 {
bar(x + 1)
}
#[no_mangle]
#[inline(never)]
pub fn bar(x: i32) -> i32 {
x * 2
}
fn main() {}