Skip to content

Commit 0efe609

Browse files
authored
Unrolled build for rust-lang#136375
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 8df89d1 + c3f2930 commit 0efe609

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)]
@@ -1675,6 +1725,50 @@ unsafe extern "C" {
16751725
) -> &'a Value;
16761726
}
16771727

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

1945-
pub fn LLVMRustDIBuilderCreate(M: &Module) -> &mut DIBuilder<'_>;
1946-
1947-
pub fn LLVMRustDIBuilderDispose<'a>(Builder: &'a mut DIBuilder<'a>);
1948-
1949-
pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder<'_>);
1950-
19512039
pub fn LLVMRustDIBuilderCreateCompileUnit<'a>(
19522040
Builder: &DIBuilder<'a>,
19532041
Lang: c_uint,
@@ -2110,20 +2198,6 @@ unsafe extern "C" {
21102198
Type: &'a DIType,
21112199
) -> &'a DIDerivedType;
21122200

2113-
pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
2114-
Builder: &DIBuilder<'a>,
2115-
Scope: &'a DIScope,
2116-
File: &'a DIFile,
2117-
Line: c_uint,
2118-
Col: c_uint,
2119-
) -> &'a DILexicalBlock;
2120-
2121-
pub fn LLVMRustDIBuilderCreateLexicalBlockFile<'a>(
2122-
Builder: &DIBuilder<'a>,
2123-
Scope: &'a DIScope,
2124-
File: &'a DIFile,
2125-
) -> &'a DILexicalBlock;
2126-
21272201
pub fn LLVMRustDIBuilderCreateStaticVariable<'a>(
21282202
Builder: &DIBuilder<'a>,
21292203
Context: Option<&'a DIScope>,
@@ -2248,27 +2322,13 @@ unsafe extern "C" {
22482322
Ty: &'a DIType,
22492323
) -> &'a DITemplateTypeParameter;
22502324

2251-
pub fn LLVMRustDIBuilderCreateNameSpace<'a>(
2252-
Builder: &DIBuilder<'a>,
2253-
Scope: Option<&'a DIScope>,
2254-
Name: *const c_char,
2255-
NameLen: size_t,
2256-
ExportSymbols: bool,
2257-
) -> &'a DINameSpace;
2258-
22592325
pub fn LLVMRustDICompositeTypeReplaceArrays<'a>(
22602326
Builder: &DIBuilder<'a>,
22612327
CompositeType: &'a DIType,
22622328
Elements: Option<&'a DIArray>,
22632329
Params: Option<&'a DIArray>,
22642330
);
22652331

2266-
pub fn LLVMRustDIBuilderCreateDebugLocation<'a>(
2267-
Line: c_uint,
2268-
Column: c_uint,
2269-
Scope: &'a DIScope,
2270-
InlinedAt: Option<&'a DILocation>,
2271-
) -> &'a DILocation;
22722332
pub fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>(
22732333
Location: &'a DILocation,
22742334
BD: c_uint,

0 commit comments

Comments
 (0)