Skip to content

Commit 8547612

Browse files
Rollup merge of rust-lang#147608 - Zalathar:debuginfo, r=nnethercote
cg_llvm: Use `LLVMDIBuilderCreateGlobalVariableExpression` - Part of rust-lang#134001 - Follow-up to rust-lang#146763 --- This PR dismantles the somewhat complicated `LLVMRustDIBuilderCreateStaticVariable` function, and replaces it with equivalent calls to `LLVMDIBuilderCreateGlobalVariableExpression` and `LLVMGlobalSetMetadata`. A key difference is that the new code does not replicate the attempted downcast of `InitVal`. As far as I can tell, those downcasts were actually dead, because `llvm::ConstantInt` and `llvm::ConstantFP` are not subclasses of `llvm::GlobalVariable`. I tried replacing those code paths with fatal errors, and was unable to induce failure in any of the relevant test suites I ran. I have also confirmed that if the calls to `create_static_variable` are commented out, debuginfo tests will fail, demonstrating some amount of relevant test coverage. The new `DIBuilder` methods have been added via an extension trait, not as inherent methods, to avoid impeding rust-lang#142897.
2 parents b4700c5 + 1081d98 commit 8547612

File tree

6 files changed

+150
-93
lines changed

6 files changed

+150
-93
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use libc::c_uint;
2+
use rustc_abi::Align;
3+
4+
use crate::llvm::debuginfo::DIBuilder;
5+
use crate::llvm::{self, ToLlvmBool};
6+
7+
/// Extension trait for defining safe wrappers and helper methods on
8+
/// `&DIBuilder<'ll>`, without requiring it to be defined in the same crate.
9+
pub(crate) trait DIBuilderExt<'ll> {
10+
fn as_di_builder(&self) -> &DIBuilder<'ll>;
11+
12+
fn create_expression(&self, addr_ops: &[u64]) -> &'ll llvm::Metadata {
13+
let this = self.as_di_builder();
14+
unsafe { llvm::LLVMDIBuilderCreateExpression(this, addr_ops.as_ptr(), addr_ops.len()) }
15+
}
16+
17+
fn create_static_variable(
18+
&self,
19+
scope: Option<&'ll llvm::Metadata>,
20+
name: &str,
21+
linkage_name: &str,
22+
file: &'ll llvm::Metadata,
23+
line_number: c_uint,
24+
ty: &'ll llvm::Metadata,
25+
is_local_to_unit: bool,
26+
val: &'ll llvm::Value,
27+
decl: Option<&'ll llvm::Metadata>,
28+
align: Option<Align>,
29+
) -> &'ll llvm::Metadata {
30+
let this = self.as_di_builder();
31+
let align_in_bits = align.map_or(0, |align| align.bits() as u32);
32+
33+
// `LLVMDIBuilderCreateGlobalVariableExpression` would assert if we
34+
// gave it a null `Expr` pointer, so give it an empty expression
35+
// instead, which is what the C++ `createGlobalVariableExpression`
36+
// method would do if given a null `DIExpression` pointer.
37+
let expr = self.create_expression(&[]);
38+
39+
let global_var_expr = unsafe {
40+
llvm::LLVMDIBuilderCreateGlobalVariableExpression(
41+
this,
42+
scope,
43+
name.as_ptr(),
44+
name.len(),
45+
linkage_name.as_ptr(),
46+
linkage_name.len(),
47+
file,
48+
line_number,
49+
ty,
50+
is_local_to_unit.to_llvm_bool(),
51+
expr,
52+
decl,
53+
align_in_bits,
54+
)
55+
};
56+
57+
unsafe { llvm::LLVMGlobalSetMetadata(val, llvm::MD_dbg, global_var_expr) };
58+
59+
global_var_expr
60+
}
61+
}
62+
63+
impl<'ll> DIBuilderExt<'ll> for &DIBuilder<'ll> {
64+
fn as_di_builder(&self) -> &DIBuilder<'ll> {
65+
self
66+
}
67+
68+
// All other methods have default bodies that rely on `as_di_builder`.
69+
}

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ use super::namespace::mangled_name_of_instance;
3434
use super::type_names::{compute_debuginfo_type_name, compute_debuginfo_vtable_name};
3535
use super::utils::{DIB, debug_context, get_namespace_for_item, is_node_local_to_unit};
3636
use crate::common::{AsCCharPtr, CodegenCx};
37-
use crate::debuginfo::dwarf_const;
3837
use crate::debuginfo::metadata::type_map::build_type_with_children;
3938
use crate::debuginfo::utils::{WidePtrKind, wide_pointer_kind};
39+
use crate::debuginfo::{DIBuilderExt, dwarf_const};
4040
use crate::llvm::debuginfo::{
4141
DIBasicType, DIBuilder, DICompositeType, DIDescriptor, DIFile, DIFlags, DILexicalBlock,
4242
DIScope, DIType, DebugEmissionKind, DebugNameTableKind,
@@ -1410,23 +1410,18 @@ pub(crate) fn build_global_var_di_node<'ll>(
14101410

14111411
let global_align = cx.align_of(variable_type);
14121412

1413-
unsafe {
1414-
llvm::LLVMRustDIBuilderCreateStaticVariable(
1415-
DIB(cx),
1416-
Some(var_scope),
1417-
var_name.as_c_char_ptr(),
1418-
var_name.len(),
1419-
linkage_name.as_c_char_ptr(),
1420-
linkage_name.len(),
1421-
file_metadata,
1422-
line_number,
1423-
type_di_node,
1424-
is_local_to_unit,
1425-
global,
1426-
None,
1427-
global_align.bits() as u32,
1428-
);
1429-
}
1413+
DIB(cx).create_static_variable(
1414+
Some(var_scope),
1415+
var_name,
1416+
linkage_name,
1417+
file_metadata,
1418+
line_number,
1419+
type_di_node,
1420+
is_local_to_unit,
1421+
global, // (value)
1422+
None, // (decl)
1423+
Some(global_align),
1424+
);
14301425
}
14311426

14321427
/// Generates LLVM debuginfo for a vtable.
@@ -1643,25 +1638,19 @@ pub(crate) fn create_vtable_di_node<'ll, 'tcx>(
16431638
let vtable_name =
16441639
compute_debuginfo_vtable_name(cx.tcx, ty, poly_trait_ref, VTableNameKind::GlobalVariable);
16451640
let vtable_type_di_node = build_vtable_type_di_node(cx, ty, poly_trait_ref);
1646-
let linkage_name = "";
16471641

1648-
unsafe {
1649-
llvm::LLVMRustDIBuilderCreateStaticVariable(
1650-
DIB(cx),
1651-
NO_SCOPE_METADATA,
1652-
vtable_name.as_c_char_ptr(),
1653-
vtable_name.len(),
1654-
linkage_name.as_c_char_ptr(),
1655-
linkage_name.len(),
1656-
unknown_file_metadata(cx),
1657-
UNKNOWN_LINE_NUMBER,
1658-
vtable_type_di_node,
1659-
true,
1660-
vtable,
1661-
None,
1662-
0,
1663-
);
1664-
}
1642+
DIB(cx).create_static_variable(
1643+
NO_SCOPE_METADATA,
1644+
&vtable_name,
1645+
"", // (linkage_name)
1646+
unknown_file_metadata(cx),
1647+
UNKNOWN_LINE_NUMBER,
1648+
vtable_type_di_node,
1649+
true, // (is_local_to_unit)
1650+
vtable, // (value)
1651+
None, // (decl)
1652+
None::<Align>,
1653+
);
16651654
}
16661655

16671656
/// Creates an "extension" of an existing `DIScope` into another file.

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ use rustc_target::spec::DebuginfoKind;
2828
use smallvec::SmallVec;
2929
use tracing::debug;
3030

31+
use self::create_scope_map::compute_mir_scopes;
32+
pub(crate) use self::di_builder::DIBuilderExt;
33+
pub(crate) use self::metadata::build_global_var_di_node;
3134
use self::metadata::{
3235
UNKNOWN_COLUMN_NUMBER, UNKNOWN_LINE_NUMBER, file_metadata, spanned_type_di_node, type_di_node,
3336
};
@@ -42,15 +45,13 @@ use crate::llvm::debuginfo::{
4245
use crate::llvm::{self, Value};
4346

4447
mod create_scope_map;
48+
mod di_builder;
4549
mod dwarf_const;
4650
mod gdb;
4751
pub(crate) mod metadata;
4852
mod namespace;
4953
mod utils;
5054

51-
use self::create_scope_map::compute_mir_scopes;
52-
pub(crate) use self::metadata::build_global_var_di_node;
53-
5455
/// A context object for maintaining all state needed by the debuginfo module.
5556
pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
5657
llmod: &'ll llvm::Module,
@@ -182,9 +183,7 @@ impl<'ll> DebugInfoBuilderMethods for Builder<'_, 'll, '_> {
182183
}
183184

184185
let di_builder = DIB(self.cx());
185-
let addr_expr = unsafe {
186-
llvm::LLVMDIBuilderCreateExpression(di_builder, addr_ops.as_ptr(), addr_ops.len())
187-
};
186+
let addr_expr = di_builder.create_expression(&addr_ops);
188187
unsafe {
189188
llvm::LLVMDIBuilderInsertDeclareRecordAtEnd(
190189
di_builder,

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t};
2222

2323
use super::RustString;
2424
use super::debuginfo::{
25-
DIArray, DIBuilder, DIDerivedType, DIDescriptor, DIEnumerator, DIFile, DIFlags,
26-
DIGlobalVariableExpression, DILocation, DISPFlags, DIScope, DISubprogram,
27-
DITemplateTypeParameter, DIType, DebugEmissionKind, DebugNameTableKind,
25+
DIArray, DIBuilder, DIDerivedType, DIDescriptor, DIEnumerator, DIFile, DIFlags, DILocation,
26+
DISPFlags, DIScope, DISubprogram, DITemplateTypeParameter, DIType, DebugEmissionKind,
27+
DebugNameTableKind,
2828
};
2929
use crate::llvm::MetadataKindId;
3030
use crate::{TryFromU32, llvm};
@@ -781,7 +781,6 @@ pub(crate) mod debuginfo {
781781
pub(crate) type DIDerivedType = DIType;
782782
pub(crate) type DICompositeType = DIDerivedType;
783783
pub(crate) type DIVariable = DIDescriptor;
784-
pub(crate) type DIGlobalVariableExpression = DIDescriptor;
785784
pub(crate) type DIArray = DIDescriptor;
786785
pub(crate) type DIEnumerator = DIDescriptor;
787786
pub(crate) type DITemplateTypeParameter = DIDescriptor;
@@ -1877,6 +1876,22 @@ unsafe extern "C" {
18771876
Length: size_t,
18781877
) -> &'ll Metadata;
18791878

1879+
pub(crate) fn LLVMDIBuilderCreateGlobalVariableExpression<'ll>(
1880+
Builder: &DIBuilder<'ll>,
1881+
Scope: Option<&'ll Metadata>,
1882+
Name: *const c_uchar, // See "PTR_LEN_STR".
1883+
NameLen: size_t,
1884+
Linkage: *const c_uchar, // See "PTR_LEN_STR".
1885+
LinkLen: size_t,
1886+
File: &'ll Metadata,
1887+
LineNo: c_uint,
1888+
Ty: &'ll Metadata,
1889+
LocalToUnit: llvm::Bool,
1890+
Expr: &'ll Metadata,
1891+
Decl: Option<&'ll Metadata>,
1892+
AlignInBits: u32,
1893+
) -> &'ll Metadata;
1894+
18801895
pub(crate) fn LLVMDIBuilderInsertDeclareRecordAtEnd<'ll>(
18811896
Builder: &DIBuilder<'ll>,
18821897
Storage: &'ll Value,
@@ -2213,22 +2228,6 @@ unsafe extern "C" {
22132228
Ty: &'a DIType,
22142229
) -> &'a DIType;
22152230

2216-
pub(crate) fn LLVMRustDIBuilderCreateStaticVariable<'a>(
2217-
Builder: &DIBuilder<'a>,
2218-
Context: Option<&'a DIScope>,
2219-
Name: *const c_char,
2220-
NameLen: size_t,
2221-
LinkageName: *const c_char,
2222-
LinkageNameLen: size_t,
2223-
File: &'a DIFile,
2224-
LineNo: c_uint,
2225-
Ty: &'a DIType,
2226-
isLocalToUnit: bool,
2227-
Val: &'a Value,
2228-
Decl: Option<&'a DIDescriptor>,
2229-
AlignInBits: u32,
2230-
) -> &'a DIGlobalVariableExpression;
2231-
22322231
pub(crate) fn LLVMRustDIBuilderCreateEnumerator<'a>(
22332232
Builder: &DIBuilder<'a>,
22342233
Name: *const c_char,

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,37 +1038,6 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateVariantMemberType(
10381038
fromRust(Flags), unwrapDI<DIType>(Ty)));
10391039
}
10401040

1041-
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticVariable(
1042-
LLVMDIBuilderRef Builder, LLVMMetadataRef Context, const char *Name,
1043-
size_t NameLen, const char *LinkageName, size_t LinkageNameLen,
1044-
LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,
1045-
bool IsLocalToUnit, LLVMValueRef V, LLVMMetadataRef Decl = nullptr,
1046-
uint32_t AlignInBits = 0) {
1047-
llvm::GlobalVariable *InitVal = cast<llvm::GlobalVariable>(unwrap(V));
1048-
1049-
llvm::DIExpression *InitExpr = nullptr;
1050-
if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
1051-
InitExpr = unwrap(Builder)->createConstantValueExpression(
1052-
IntVal->getValue().getSExtValue());
1053-
} else if (llvm::ConstantFP *FPVal =
1054-
llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
1055-
InitExpr = unwrap(Builder)->createConstantValueExpression(
1056-
FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
1057-
}
1058-
1059-
llvm::DIGlobalVariableExpression *VarExpr =
1060-
unwrap(Builder)->createGlobalVariableExpression(
1061-
unwrapDI<DIDescriptor>(Context), StringRef(Name, NameLen),
1062-
StringRef(LinkageName, LinkageNameLen), unwrapDI<DIFile>(File),
1063-
LineNo, unwrapDI<DIType>(Ty), IsLocalToUnit,
1064-
/* isDefined */ true, InitExpr, unwrapDIPtr<MDNode>(Decl),
1065-
/* templateParams */ nullptr, AlignInBits);
1066-
1067-
InitVal->setMetadata("dbg", VarExpr);
1068-
1069-
return wrap(VarExpr);
1070-
}
1071-
10721041
extern "C" LLVMMetadataRef
10731042
LLVMRustDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder, const char *Name,
10741043
size_t NameLen, const uint64_t Value[2],

tests/debuginfo/basic-types-globals.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,38 @@
66
//@ [lto] compile-flags:-C lto
77
//@ [lto] no-prefer-dynamic
88

9+
// lldb-command:run
10+
// lldb-command:v B
11+
// lldb-check: ::B::[...] = false
12+
// lldb-command:v I
13+
// lldb-check: ::I::[...] = -1
14+
// lldb-command:v --format=d C
15+
// lldb-check: ::C::[...] = 97
16+
// lldb-command:v --format=d I8
17+
// lldb-check: ::I8::[...] = 68
18+
// lldb-command:v I16
19+
// lldb-check: ::I16::[...] = -16
20+
// lldb-command:v I32
21+
// lldb-check: ::I32::[...] = -32
22+
// lldb-command:v I64
23+
// lldb-check: ::I64::[...] = -64
24+
// lldb-command:v U
25+
// lldb-check: ::U::[...] = 1
26+
// lldb-command:v --format=d U8
27+
// lldb-check: ::U8::[...] = 100
28+
// lldb-command:v U16
29+
// lldb-check: ::U16::[...] = 16
30+
// lldb-command:v U32
31+
// lldb-check: ::U32::[...] = 32
32+
// lldb-command:v U64
33+
// lldb-check: ::U64::[...] = 64
34+
// lldb-command:v F16
35+
// lldb-check: ::F16::[...] = 1.5
36+
// lldb-command:v F32
37+
// lldb-check: ::F32::[...] = 2.5
38+
// lldb-command:v F64
39+
// lldb-check: ::F64::[...] = 3.5
40+
941
// gdb-command:run
1042
// gdb-command:print B
1143
// gdb-check:$1 = false

0 commit comments

Comments
 (0)