Skip to content
/ rust Public
forked from rust-lang/rust

Commit 5bb1bbb

Browse files
authored
Rollup merge of rust-lang#136375 - Zalathar:llvm-di-builder, r=workingjubilee
cg_llvm: Replace some DIBuilder wrappers with LLVM-C API bindings (part 1) Part of rust-lang#134001, follow-up to rust-lang#136326, extracted from rust-lang#134009. This PR performs an arbitrary subset of the LLVM-C binding migrations from rust-lang#134009, which should make it less tedious to review. The remaining migrations can occur in one or more subsequent PRs.
2 parents c487764 + c3f2930 commit 5bb1bbb

File tree

7 files changed

+121
-98
lines changed

7 files changed

+121
-98
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ fn make_mir_scope<'ll, 'tcx>(
127127
})
128128
}
129129
None => unsafe {
130-
llvm::LLVMRustDIBuilderCreateLexicalBlock(
130+
llvm::LLVMDIBuilderCreateLexicalBlock(
131131
DIB(cx),
132132
parent_scope.dbg_scope,
133133
file_metadata,

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

+10-3
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
931931

932932
unsafe {
933933
let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
934-
debug_context.builder,
934+
debug_context.builder.as_ref(),
935935
name_in_debuginfo.as_c_char_ptr(),
936936
name_in_debuginfo.len(),
937937
work_dir.as_c_char_ptr(),
@@ -944,7 +944,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
944944
);
945945

946946
let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
947-
debug_context.builder,
947+
debug_context.builder.as_ref(),
948948
dwarf_const::DW_LANG_Rust,
949949
compile_unit_file,
950950
producer.as_c_char_ptr(),
@@ -1641,7 +1641,14 @@ pub(crate) fn extend_scope_to_file<'ll>(
16411641
file: &SourceFile,
16421642
) -> &'ll DILexicalBlock {
16431643
let file_metadata = file_metadata(cx, file);
1644-
unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
1644+
unsafe {
1645+
llvm::LLVMDIBuilderCreateLexicalBlockFile(
1646+
DIB(cx),
1647+
scope_metadata,
1648+
file_metadata,
1649+
/* Discriminator (default) */ 0u32,
1650+
)
1651+
}
16451652
}
16461653

16471654
fn tuple_field_name(field_index: usize) -> Cow<'static, str> {

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+5-13
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use crate::builder::Builder;
3434
use crate::common::{AsCCharPtr, CodegenCx};
3535
use crate::llvm;
3636
use crate::llvm::debuginfo::{
37-
DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType,
37+
DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType,
3838
DIVariable,
3939
};
4040
use crate::value::Value;
@@ -61,26 +61,18 @@ const DW_TAG_arg_variable: c_uint = 0x101;
6161
/// A context object for maintaining all state needed by the debuginfo module.
6262
pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
6363
llmod: &'ll llvm::Module,
64-
builder: &'ll mut DIBuilder<'ll>,
64+
builder: DIBuilderBox<'ll>,
6565
created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>,
6666

6767
type_map: metadata::TypeMap<'ll, 'tcx>,
6868
namespace_map: RefCell<DefIdMap<&'ll DIScope>>,
6969
recursion_marker_type: OnceCell<&'ll DIType>,
7070
}
7171

72-
impl Drop for CodegenUnitDebugContext<'_, '_> {
73-
fn drop(&mut self) {
74-
unsafe {
75-
llvm::LLVMRustDIBuilderDispose(&mut *(self.builder as *mut _));
76-
}
77-
}
78-
}
79-
8072
impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
8173
pub(crate) fn new(llmod: &'ll llvm::Module) -> Self {
8274
debug!("CodegenUnitDebugContext::new");
83-
let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
75+
let builder = DIBuilderBox::new(llmod);
8476
// DIBuilder inherits context from the module, so we'd better use the same one
8577
CodegenUnitDebugContext {
8678
llmod,
@@ -93,7 +85,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
9385
}
9486

9587
pub(crate) fn finalize(&self, sess: &Session) {
96-
unsafe { llvm::LLVMRustDIBuilderFinalize(self.builder) };
88+
unsafe { llvm::LLVMDIBuilderFinalize(self.builder.as_ref()) };
9789

9890
match sess.target.debuginfo_kind {
9991
DebuginfoKind::Dwarf | DebuginfoKind::DwarfDsym => {
@@ -582,7 +574,7 @@ impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
582574
(line, col)
583575
};
584576

585-
unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation(line, col, scope, inlined_at) }
577+
unsafe { llvm::LLVMDIBuilderCreateDebugLocation(self.llcx, line, col, scope, inlined_at) }
586578
}
587579

588580
fn create_vtable_debuginfo(

compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId;
55
use rustc_middle::ty::{self, Instance};
66

77
use super::utils::{DIB, debug_context};
8-
use crate::common::{AsCCharPtr, CodegenCx};
8+
use crate::common::CodegenCx;
99
use crate::llvm;
1010
use crate::llvm::debuginfo::DIScope;
1111

@@ -33,12 +33,12 @@ pub(crate) fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'l
3333
};
3434

3535
let scope = unsafe {
36-
llvm::LLVMRustDIBuilderCreateNameSpace(
36+
llvm::LLVMDIBuilderCreateNameSpace(
3737
DIB(cx),
3838
parent_scope,
39-
namespace_name_string.as_c_char_ptr(),
39+
namespace_name_string.as_ptr(),
4040
namespace_name_string.len(),
41-
false, // ExportSymbols (only relevant for C++ anonymous namespaces)
41+
llvm::False, // ExportSymbols (only relevant for C++ anonymous namespaces)
4242
)
4343
};
4444

compiler/rustc_codegen_llvm/src/debuginfo/utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub(crate) fn debug_context<'a, 'll, 'tcx>(
4141
#[inline]
4242
#[allow(non_snake_case)]
4343
pub(crate) fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> {
44-
cx.dbg_cx.as_ref().unwrap().builder
44+
cx.dbg_cx.as_ref().unwrap().builder.as_ref()
4545
}
4646

4747
pub(crate) fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+100-40
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,34 @@
1+
//! Bindings to the LLVM-C API (`LLVM*`), and to our own `extern "C"` wrapper
2+
//! functions around the unstable LLVM C++ API (`LLVMRust*`).
3+
//!
4+
//! ## Passing pointer/length strings as `*const c_uchar`
5+
//!
6+
//! Normally it's a good idea for Rust-side bindings to match the corresponding
7+
//! C-side function declarations as closely as possible. But when passing `&str`
8+
//! or `&[u8]` data as a pointer/length pair, it's more convenient to declare
9+
//! the Rust-side pointer as `*const c_uchar` instead of `*const c_char`.
10+
//! Both pointer types have the same ABI, and using `*const c_uchar` avoids
11+
//! the need for an extra cast from `*const u8` on the Rust side.
12+
113
#![allow(non_camel_case_types)]
214
#![allow(non_upper_case_globals)]
315

416
use std::fmt::Debug;
517
use std::marker::PhantomData;
618
use std::ptr;
719

8-
use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t};
20+
use bitflags::bitflags;
21+
use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t};
922
use rustc_macros::TryFromU32;
1023
use rustc_target::spec::SymbolVisibility;
1124

1225
use super::RustString;
1326
use super::debuginfo::{
1427
DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator,
15-
DIFile, DIFlags, DIGlobalVariableExpression, DILexicalBlock, DILocation, DINameSpace,
16-
DISPFlags, DIScope, DISubprogram, DISubrange, DITemplateTypeParameter, DIType, DIVariable,
17-
DebugEmissionKind, DebugNameTableKind,
28+
DIFile, DIFlags, DIGlobalVariableExpression, DILocation, DISPFlags, DIScope, DISubprogram,
29+
DISubrange, DITemplateTypeParameter, DIType, DIVariable, DebugEmissionKind, DebugNameTableKind,
1830
};
31+
use crate::llvm;
1932

2033
/// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
2134
/// which has a different ABI from Rust or C++ `bool`.
@@ -789,12 +802,50 @@ pub type DiagnosticHandlerTy = unsafe extern "C" fn(&DiagnosticInfo, *mut c_void
789802
pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint);
790803

791804
pub mod debuginfo {
805+
use std::ptr;
806+
792807
use bitflags::bitflags;
793808

794809
use super::{InvariantOpaque, Metadata};
810+
use crate::llvm::{self, Module};
795811

812+
/// Opaque target type for references to an LLVM debuginfo builder.
813+
///
814+
/// `&'_ DIBuilder<'ll>` corresponds to `LLVMDIBuilderRef`, which is the
815+
/// LLVM-C wrapper for `DIBuilder *`.
816+
///
817+
/// Debuginfo builders are created and destroyed during codegen, so the
818+
/// builder reference typically has a shorter lifetime than the LLVM
819+
/// session (`'ll`) that it participates in.
796820
#[repr(C)]
797-
pub struct DIBuilder<'a>(InvariantOpaque<'a>);
821+
pub struct DIBuilder<'ll>(InvariantOpaque<'ll>);
822+
823+
/// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder
824+
/// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder`
825+
/// needed for debuginfo FFI calls.
826+
pub(crate) struct DIBuilderBox<'ll> {
827+
raw: ptr::NonNull<DIBuilder<'ll>>,
828+
}
829+
830+
impl<'ll> DIBuilderBox<'ll> {
831+
pub(crate) fn new(llmod: &'ll Module) -> Self {
832+
let raw = unsafe { llvm::LLVMCreateDIBuilder(llmod) };
833+
let raw = ptr::NonNull::new(raw).unwrap();
834+
Self { raw }
835+
}
836+
837+
pub(crate) fn as_ref(&self) -> &DIBuilder<'ll> {
838+
// SAFETY: This is an owning pointer, so `&DIBuilder` is valid
839+
// for as long as `&self` is.
840+
unsafe { self.raw.as_ref() }
841+
}
842+
}
843+
844+
impl<'ll> Drop for DIBuilderBox<'ll> {
845+
fn drop(&mut self) {
846+
unsafe { llvm::LLVMDisposeDIBuilder(self.raw) };
847+
}
848+
}
798849

799850
pub type DIDescriptor = Metadata;
800851
pub type DILocation = Metadata;
@@ -914,7 +965,6 @@ pub mod debuginfo {
914965
}
915966
}
916967

917-
use bitflags::bitflags;
918968
// These values **must** match with LLVMRustAllocKindFlags
919969
bitflags! {
920970
#[repr(transparent)]
@@ -1672,6 +1722,50 @@ unsafe extern "C" {
16721722
) -> &'a Value;
16731723
}
16741724

1725+
// FFI bindings for `DIBuilder` functions in the LLVM-C API.
1726+
// Try to keep these in the same order as in `llvm/include/llvm-c/DebugInfo.h`.
1727+
//
1728+
// FIXME(#134001): Audit all `Option` parameters, especially in lists, to check
1729+
// that they really are nullable on the C/C++ side. LLVM doesn't appear to
1730+
// actually document which ones are nullable.
1731+
unsafe extern "C" {
1732+
pub(crate) fn LLVMCreateDIBuilder<'ll>(M: &'ll Module) -> *mut DIBuilder<'ll>;
1733+
pub(crate) fn LLVMDisposeDIBuilder<'ll>(Builder: ptr::NonNull<DIBuilder<'ll>>);
1734+
1735+
pub(crate) fn LLVMDIBuilderFinalize<'ll>(Builder: &DIBuilder<'ll>);
1736+
1737+
pub(crate) fn LLVMDIBuilderCreateNameSpace<'ll>(
1738+
Builder: &DIBuilder<'ll>,
1739+
ParentScope: Option<&'ll Metadata>,
1740+
Name: *const c_uchar,
1741+
NameLen: size_t,
1742+
ExportSymbols: llvm::Bool,
1743+
) -> &'ll Metadata;
1744+
1745+
pub(crate) fn LLVMDIBuilderCreateLexicalBlock<'ll>(
1746+
Builder: &DIBuilder<'ll>,
1747+
Scope: &'ll Metadata,
1748+
File: &'ll Metadata,
1749+
Line: c_uint,
1750+
Column: c_uint,
1751+
) -> &'ll Metadata;
1752+
1753+
pub(crate) fn LLVMDIBuilderCreateLexicalBlockFile<'ll>(
1754+
Builder: &DIBuilder<'ll>,
1755+
Scope: &'ll Metadata,
1756+
File: &'ll Metadata,
1757+
Discriminator: c_uint, // (optional "DWARF path discriminator"; default is 0)
1758+
) -> &'ll Metadata;
1759+
1760+
pub(crate) fn LLVMDIBuilderCreateDebugLocation<'ll>(
1761+
Ctx: &'ll Context,
1762+
Line: c_uint,
1763+
Column: c_uint,
1764+
Scope: &'ll Metadata,
1765+
InlinedAt: Option<&'ll Metadata>,
1766+
) -> &'ll Metadata;
1767+
}
1768+
16751769
#[link(name = "llvm-wrapper", kind = "static")]
16761770
unsafe extern "C" {
16771771
pub fn LLVMRustInstallErrorHandlers();
@@ -1939,12 +2033,6 @@ unsafe extern "C" {
19392033
ValueLen: size_t,
19402034
);
19412035

1942-
pub fn LLVMRustDIBuilderCreate(M: &Module) -> &mut DIBuilder<'_>;
1943-
1944-
pub fn LLVMRustDIBuilderDispose<'a>(Builder: &'a mut DIBuilder<'a>);
1945-
1946-
pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder<'_>);
1947-
19482036
pub fn LLVMRustDIBuilderCreateCompileUnit<'a>(
19492037
Builder: &DIBuilder<'a>,
19502038
Lang: c_uint,
@@ -2107,20 +2195,6 @@ unsafe extern "C" {
21072195
Type: &'a DIType,
21082196
) -> &'a DIDerivedType;
21092197

2110-
pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
2111-
Builder: &DIBuilder<'a>,
2112-
Scope: &'a DIScope,
2113-
File: &'a DIFile,
2114-
Line: c_uint,
2115-
Col: c_uint,
2116-
) -> &'a DILexicalBlock;
2117-
2118-
pub fn LLVMRustDIBuilderCreateLexicalBlockFile<'a>(
2119-
Builder: &DIBuilder<'a>,
2120-
Scope: &'a DIScope,
2121-
File: &'a DIFile,
2122-
) -> &'a DILexicalBlock;
2123-
21242198
pub fn LLVMRustDIBuilderCreateStaticVariable<'a>(
21252199
Builder: &DIBuilder<'a>,
21262200
Context: Option<&'a DIScope>,
@@ -2245,27 +2319,13 @@ unsafe extern "C" {
22452319
Ty: &'a DIType,
22462320
) -> &'a DITemplateTypeParameter;
22472321

2248-
pub fn LLVMRustDIBuilderCreateNameSpace<'a>(
2249-
Builder: &DIBuilder<'a>,
2250-
Scope: Option<&'a DIScope>,
2251-
Name: *const c_char,
2252-
NameLen: size_t,
2253-
ExportSymbols: bool,
2254-
) -> &'a DINameSpace;
2255-
22562322
pub fn LLVMRustDICompositeTypeReplaceArrays<'a>(
22572323
Builder: &DIBuilder<'a>,
22582324
CompositeType: &'a DIType,
22592325
Elements: Option<&'a DIArray>,
22602326
Params: Option<&'a DIArray>,
22612327
);
22622328

2263-
pub fn LLVMRustDIBuilderCreateDebugLocation<'a>(
2264-
Line: c_uint,
2265-
Column: c_uint,
2266-
Scope: &'a DIScope,
2267-
InlinedAt: Option<&'a DILocation>,
2268-
) -> &'a DILocation;
22692329
pub fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>(
22702330
Location: &'a DILocation,
22712331
BD: c_uint,

0 commit comments

Comments
 (0)