Skip to content

Commit

Permalink
Unrolled build for rust-lang#136375
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rust-timer authored Feb 5, 2025
2 parents 8df89d1 + c3f2930 commit 0efe609
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ fn make_mir_scope<'ll, 'tcx>(
})
}
None => unsafe {
llvm::LLVMRustDIBuilderCreateLexicalBlock(
llvm::LLVMDIBuilderCreateLexicalBlock(
DIB(cx),
parent_scope.dbg_scope,
file_metadata,
Expand Down
13 changes: 10 additions & 3 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(

unsafe {
let compile_unit_file = llvm::LLVMRustDIBuilderCreateFile(
debug_context.builder,
debug_context.builder.as_ref(),
name_in_debuginfo.as_c_char_ptr(),
name_in_debuginfo.len(),
work_dir.as_c_char_ptr(),
Expand All @@ -944,7 +944,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
);

let unit_metadata = llvm::LLVMRustDIBuilderCreateCompileUnit(
debug_context.builder,
debug_context.builder.as_ref(),
dwarf_const::DW_LANG_Rust,
compile_unit_file,
producer.as_c_char_ptr(),
Expand Down Expand Up @@ -1641,7 +1641,14 @@ pub(crate) fn extend_scope_to_file<'ll>(
file: &SourceFile,
) -> &'ll DILexicalBlock {
let file_metadata = file_metadata(cx, file);
unsafe { llvm::LLVMRustDIBuilderCreateLexicalBlockFile(DIB(cx), scope_metadata, file_metadata) }
unsafe {
llvm::LLVMDIBuilderCreateLexicalBlockFile(
DIB(cx),
scope_metadata,
file_metadata,
/* Discriminator (default) */ 0u32,
)
}
}

fn tuple_field_name(field_index: usize) -> Cow<'static, str> {
Expand Down
18 changes: 5 additions & 13 deletions compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::builder::Builder;
use crate::common::{AsCCharPtr, CodegenCx};
use crate::llvm;
use crate::llvm::debuginfo::{
DIArray, DIBuilder, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType,
DIArray, DIBuilderBox, DIFile, DIFlags, DILexicalBlock, DILocation, DISPFlags, DIScope, DIType,
DIVariable,
};
use crate::value::Value;
Expand All @@ -61,26 +61,18 @@ const DW_TAG_arg_variable: c_uint = 0x101;
/// A context object for maintaining all state needed by the debuginfo module.
pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
llmod: &'ll llvm::Module,
builder: &'ll mut DIBuilder<'ll>,
builder: DIBuilderBox<'ll>,
created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>,

type_map: metadata::TypeMap<'ll, 'tcx>,
namespace_map: RefCell<DefIdMap<&'ll DIScope>>,
recursion_marker_type: OnceCell<&'ll DIType>,
}

impl Drop for CodegenUnitDebugContext<'_, '_> {
fn drop(&mut self) {
unsafe {
llvm::LLVMRustDIBuilderDispose(&mut *(self.builder as *mut _));
}
}
}

impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
pub(crate) fn new(llmod: &'ll llvm::Module) -> Self {
debug!("CodegenUnitDebugContext::new");
let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
let builder = DIBuilderBox::new(llmod);
// DIBuilder inherits context from the module, so we'd better use the same one
CodegenUnitDebugContext {
llmod,
Expand All @@ -93,7 +85,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
}

pub(crate) fn finalize(&self, sess: &Session) {
unsafe { llvm::LLVMRustDIBuilderFinalize(self.builder) };
unsafe { llvm::LLVMDIBuilderFinalize(self.builder.as_ref()) };

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

unsafe { llvm::LLVMRustDIBuilderCreateDebugLocation(line, col, scope, inlined_at) }
unsafe { llvm::LLVMDIBuilderCreateDebugLocation(self.llcx, line, col, scope, inlined_at) }
}

fn create_vtable_debuginfo(
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId;
use rustc_middle::ty::{self, Instance};

use super::utils::{DIB, debug_context};
use crate::common::{AsCCharPtr, CodegenCx};
use crate::common::CodegenCx;
use crate::llvm;
use crate::llvm::debuginfo::DIScope;

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

let scope = unsafe {
llvm::LLVMRustDIBuilderCreateNameSpace(
llvm::LLVMDIBuilderCreateNameSpace(
DIB(cx),
parent_scope,
namespace_name_string.as_c_char_ptr(),
namespace_name_string.as_ptr(),
namespace_name_string.len(),
false, // ExportSymbols (only relevant for C++ anonymous namespaces)
llvm::False, // ExportSymbols (only relevant for C++ anonymous namespaces)
)
};

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub(crate) fn debug_context<'a, 'll, 'tcx>(
#[inline]
#[allow(non_snake_case)]
pub(crate) fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> {
cx.dbg_cx.as_ref().unwrap().builder
cx.dbg_cx.as_ref().unwrap().builder.as_ref()
}

pub(crate) fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
Expand Down
140 changes: 100 additions & 40 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
//! Bindings to the LLVM-C API (`LLVM*`), and to our own `extern "C"` wrapper
//! functions around the unstable LLVM C++ API (`LLVMRust*`).
//!
//! ## Passing pointer/length strings as `*const c_uchar`
//!
//! Normally it's a good idea for Rust-side bindings to match the corresponding
//! C-side function declarations as closely as possible. But when passing `&str`
//! or `&[u8]` data as a pointer/length pair, it's more convenient to declare
//! the Rust-side pointer as `*const c_uchar` instead of `*const c_char`.
//! Both pointer types have the same ABI, and using `*const c_uchar` avoids
//! the need for an extra cast from `*const u8` on the Rust side.
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]

use std::fmt::Debug;
use std::marker::PhantomData;
use std::ptr;

use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, size_t};
use bitflags::bitflags;
use libc::{c_char, c_int, c_uchar, c_uint, c_ulonglong, c_void, size_t};
use rustc_macros::TryFromU32;
use rustc_target::spec::SymbolVisibility;

use super::RustString;
use super::debuginfo::{
DIArray, DIBasicType, DIBuilder, DICompositeType, DIDerivedType, DIDescriptor, DIEnumerator,
DIFile, DIFlags, DIGlobalVariableExpression, DILexicalBlock, DILocation, DINameSpace,
DISPFlags, DIScope, DISubprogram, DISubrange, DITemplateTypeParameter, DIType, DIVariable,
DebugEmissionKind, DebugNameTableKind,
DIFile, DIFlags, DIGlobalVariableExpression, DILocation, DISPFlags, DIScope, DISubprogram,
DISubrange, DITemplateTypeParameter, DIType, DIVariable, DebugEmissionKind, DebugNameTableKind,
};
use crate::llvm;

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

pub mod debuginfo {
use std::ptr;

use bitflags::bitflags;

use super::{InvariantOpaque, Metadata};
use crate::llvm::{self, Module};

/// Opaque target type for references to an LLVM debuginfo builder.
///
/// `&'_ DIBuilder<'ll>` corresponds to `LLVMDIBuilderRef`, which is the
/// LLVM-C wrapper for `DIBuilder *`.
///
/// Debuginfo builders are created and destroyed during codegen, so the
/// builder reference typically has a shorter lifetime than the LLVM
/// session (`'ll`) that it participates in.
#[repr(C)]
pub struct DIBuilder<'a>(InvariantOpaque<'a>);
pub struct DIBuilder<'ll>(InvariantOpaque<'ll>);

/// Owning pointer to a `DIBuilder<'ll>` that will dispose of the builder
/// when dropped. Use `.as_ref()` to get the underlying `&DIBuilder`
/// needed for debuginfo FFI calls.
pub(crate) struct DIBuilderBox<'ll> {
raw: ptr::NonNull<DIBuilder<'ll>>,
}

impl<'ll> DIBuilderBox<'ll> {
pub(crate) fn new(llmod: &'ll Module) -> Self {
let raw = unsafe { llvm::LLVMCreateDIBuilder(llmod) };
let raw = ptr::NonNull::new(raw).unwrap();
Self { raw }
}

pub(crate) fn as_ref(&self) -> &DIBuilder<'ll> {
// SAFETY: This is an owning pointer, so `&DIBuilder` is valid
// for as long as `&self` is.
unsafe { self.raw.as_ref() }
}
}

impl<'ll> Drop for DIBuilderBox<'ll> {
fn drop(&mut self) {
unsafe { llvm::LLVMDisposeDIBuilder(self.raw) };
}
}

pub type DIDescriptor = Metadata;
pub type DILocation = Metadata;
Expand Down Expand Up @@ -914,7 +965,6 @@ pub mod debuginfo {
}
}

use bitflags::bitflags;
// These values **must** match with LLVMRustAllocKindFlags
bitflags! {
#[repr(transparent)]
Expand Down Expand Up @@ -1675,6 +1725,50 @@ unsafe extern "C" {
) -> &'a Value;
}

// FFI bindings for `DIBuilder` functions in the LLVM-C API.
// Try to keep these in the same order as in `llvm/include/llvm-c/DebugInfo.h`.
//
// FIXME(#134001): Audit all `Option` parameters, especially in lists, to check
// that they really are nullable on the C/C++ side. LLVM doesn't appear to
// actually document which ones are nullable.
unsafe extern "C" {
pub(crate) fn LLVMCreateDIBuilder<'ll>(M: &'ll Module) -> *mut DIBuilder<'ll>;
pub(crate) fn LLVMDisposeDIBuilder<'ll>(Builder: ptr::NonNull<DIBuilder<'ll>>);

pub(crate) fn LLVMDIBuilderFinalize<'ll>(Builder: &DIBuilder<'ll>);

pub(crate) fn LLVMDIBuilderCreateNameSpace<'ll>(
Builder: &DIBuilder<'ll>,
ParentScope: Option<&'ll Metadata>,
Name: *const c_uchar,
NameLen: size_t,
ExportSymbols: llvm::Bool,
) -> &'ll Metadata;

pub(crate) fn LLVMDIBuilderCreateLexicalBlock<'ll>(
Builder: &DIBuilder<'ll>,
Scope: &'ll Metadata,
File: &'ll Metadata,
Line: c_uint,
Column: c_uint,
) -> &'ll Metadata;

pub(crate) fn LLVMDIBuilderCreateLexicalBlockFile<'ll>(
Builder: &DIBuilder<'ll>,
Scope: &'ll Metadata,
File: &'ll Metadata,
Discriminator: c_uint, // (optional "DWARF path discriminator"; default is 0)
) -> &'ll Metadata;

pub(crate) fn LLVMDIBuilderCreateDebugLocation<'ll>(
Ctx: &'ll Context,
Line: c_uint,
Column: c_uint,
Scope: &'ll Metadata,
InlinedAt: Option<&'ll Metadata>,
) -> &'ll Metadata;
}

#[link(name = "llvm-wrapper", kind = "static")]
unsafe extern "C" {
pub fn LLVMRustInstallErrorHandlers();
Expand Down Expand Up @@ -1942,12 +2036,6 @@ unsafe extern "C" {
ValueLen: size_t,
);

pub fn LLVMRustDIBuilderCreate(M: &Module) -> &mut DIBuilder<'_>;

pub fn LLVMRustDIBuilderDispose<'a>(Builder: &'a mut DIBuilder<'a>);

pub fn LLVMRustDIBuilderFinalize(Builder: &DIBuilder<'_>);

pub fn LLVMRustDIBuilderCreateCompileUnit<'a>(
Builder: &DIBuilder<'a>,
Lang: c_uint,
Expand Down Expand Up @@ -2110,20 +2198,6 @@ unsafe extern "C" {
Type: &'a DIType,
) -> &'a DIDerivedType;

pub fn LLVMRustDIBuilderCreateLexicalBlock<'a>(
Builder: &DIBuilder<'a>,
Scope: &'a DIScope,
File: &'a DIFile,
Line: c_uint,
Col: c_uint,
) -> &'a DILexicalBlock;

pub fn LLVMRustDIBuilderCreateLexicalBlockFile<'a>(
Builder: &DIBuilder<'a>,
Scope: &'a DIScope,
File: &'a DIFile,
) -> &'a DILexicalBlock;

pub fn LLVMRustDIBuilderCreateStaticVariable<'a>(
Builder: &DIBuilder<'a>,
Context: Option<&'a DIScope>,
Expand Down Expand Up @@ -2248,27 +2322,13 @@ unsafe extern "C" {
Ty: &'a DIType,
) -> &'a DITemplateTypeParameter;

pub fn LLVMRustDIBuilderCreateNameSpace<'a>(
Builder: &DIBuilder<'a>,
Scope: Option<&'a DIScope>,
Name: *const c_char,
NameLen: size_t,
ExportSymbols: bool,
) -> &'a DINameSpace;

pub fn LLVMRustDICompositeTypeReplaceArrays<'a>(
Builder: &DIBuilder<'a>,
CompositeType: &'a DIType,
Elements: Option<&'a DIArray>,
Params: Option<&'a DIArray>,
);

pub fn LLVMRustDIBuilderCreateDebugLocation<'a>(
Line: c_uint,
Column: c_uint,
Scope: &'a DIScope,
InlinedAt: Option<&'a DILocation>,
) -> &'a DILocation;
pub fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>(
Location: &'a DILocation,
BD: c_uint,
Expand Down
Loading

0 comments on commit 0efe609

Please sign in to comment.