|
| 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 | +
|
1 | 13 | #![allow(non_camel_case_types)]
|
2 | 14 | #![allow(non_upper_case_globals)]
|
3 | 15 |
|
4 | 16 | use std::fmt::Debug;
|
5 | 17 | use std::marker::PhantomData;
|
6 | 18 | use std::ptr;
|
7 | 19 |
|
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}; |
9 | 22 | use rustc_macros::TryFromU32;
|
10 | 23 | use rustc_target::spec::SymbolVisibility;
|
11 | 24 |
|
12 | 25 | use super::RustString;
|
13 | 26 | use super::debuginfo::{
|
14 | 27 | 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, |
18 | 30 | };
|
| 31 | +use crate::llvm; |
19 | 32 |
|
20 | 33 | /// In the LLVM-C API, boolean values are passed as `typedef int LLVMBool`,
|
21 | 34 | /// 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
|
789 | 802 | pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_void, c_uint);
|
790 | 803 |
|
791 | 804 | pub mod debuginfo {
|
| 805 | + use std::ptr; |
| 806 | + |
792 | 807 | use bitflags::bitflags;
|
793 | 808 |
|
794 | 809 | use super::{InvariantOpaque, Metadata};
|
| 810 | + use crate::llvm::{self, Module}; |
795 | 811 |
|
| 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. |
796 | 820 | #[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 | + } |
798 | 849 |
|
799 | 850 | pub type DIDescriptor = Metadata;
|
800 | 851 | pub type DILocation = Metadata;
|
@@ -914,7 +965,6 @@ pub mod debuginfo {
|
914 | 965 | }
|
915 | 966 | }
|
916 | 967 |
|
917 |
| -use bitflags::bitflags; |
918 | 968 | // These values **must** match with LLVMRustAllocKindFlags
|
919 | 969 | bitflags! {
|
920 | 970 | #[repr(transparent)]
|
@@ -1675,6 +1725,50 @@ unsafe extern "C" {
|
1675 | 1725 | ) -> &'a Value;
|
1676 | 1726 | }
|
1677 | 1727 |
|
| 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 | + |
1678 | 1772 | #[link(name = "llvm-wrapper", kind = "static")]
|
1679 | 1773 | unsafe extern "C" {
|
1680 | 1774 | pub fn LLVMRustInstallErrorHandlers();
|
@@ -1942,12 +2036,6 @@ unsafe extern "C" {
|
1942 | 2036 | ValueLen: size_t,
|
1943 | 2037 | );
|
1944 | 2038 |
|
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 |
| - |
1951 | 2039 | pub fn LLVMRustDIBuilderCreateCompileUnit<'a>(
|
1952 | 2040 | Builder: &DIBuilder<'a>,
|
1953 | 2041 | Lang: c_uint,
|
@@ -2110,20 +2198,6 @@ unsafe extern "C" {
|
2110 | 2198 | Type: &'a DIType,
|
2111 | 2199 | ) -> &'a DIDerivedType;
|
2112 | 2200 |
|
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 |
| - |
2127 | 2201 | pub fn LLVMRustDIBuilderCreateStaticVariable<'a>(
|
2128 | 2202 | Builder: &DIBuilder<'a>,
|
2129 | 2203 | Context: Option<&'a DIScope>,
|
@@ -2248,27 +2322,13 @@ unsafe extern "C" {
|
2248 | 2322 | Ty: &'a DIType,
|
2249 | 2323 | ) -> &'a DITemplateTypeParameter;
|
2250 | 2324 |
|
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 |
| - |
2259 | 2325 | pub fn LLVMRustDICompositeTypeReplaceArrays<'a>(
|
2260 | 2326 | Builder: &DIBuilder<'a>,
|
2261 | 2327 | CompositeType: &'a DIType,
|
2262 | 2328 | Elements: Option<&'a DIArray>,
|
2263 | 2329 | Params: Option<&'a DIArray>,
|
2264 | 2330 | );
|
2265 | 2331 |
|
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; |
2272 | 2332 | pub fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>(
|
2273 | 2333 | Location: &'a DILocation,
|
2274 | 2334 | BD: c_uint,
|
|
0 commit comments