|
| 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)]
|
@@ -1672,6 +1722,50 @@ unsafe extern "C" {
|
1672 | 1722 | ) -> &'a Value;
|
1673 | 1723 | }
|
1674 | 1724 |
|
| 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 | + |
1675 | 1769 | #[link(name = "llvm-wrapper", kind = "static")]
|
1676 | 1770 | unsafe extern "C" {
|
1677 | 1771 | pub fn LLVMRustInstallErrorHandlers();
|
@@ -1939,12 +2033,6 @@ unsafe extern "C" {
|
1939 | 2033 | ValueLen: size_t,
|
1940 | 2034 | );
|
1941 | 2035 |
|
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 |
| - |
1948 | 2036 | pub fn LLVMRustDIBuilderCreateCompileUnit<'a>(
|
1949 | 2037 | Builder: &DIBuilder<'a>,
|
1950 | 2038 | Lang: c_uint,
|
@@ -2107,20 +2195,6 @@ unsafe extern "C" {
|
2107 | 2195 | Type: &'a DIType,
|
2108 | 2196 | ) -> &'a DIDerivedType;
|
2109 | 2197 |
|
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 |
| - |
2124 | 2198 | pub fn LLVMRustDIBuilderCreateStaticVariable<'a>(
|
2125 | 2199 | Builder: &DIBuilder<'a>,
|
2126 | 2200 | Context: Option<&'a DIScope>,
|
@@ -2245,27 +2319,13 @@ unsafe extern "C" {
|
2245 | 2319 | Ty: &'a DIType,
|
2246 | 2320 | ) -> &'a DITemplateTypeParameter;
|
2247 | 2321 |
|
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 |
| - |
2256 | 2322 | pub fn LLVMRustDICompositeTypeReplaceArrays<'a>(
|
2257 | 2323 | Builder: &DIBuilder<'a>,
|
2258 | 2324 | CompositeType: &'a DIType,
|
2259 | 2325 | Elements: Option<&'a DIArray>,
|
2260 | 2326 | Params: Option<&'a DIArray>,
|
2261 | 2327 | );
|
2262 | 2328 |
|
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; |
2269 | 2329 | pub fn LLVMRustDILocationCloneWithBaseDiscriminator<'a>(
|
2270 | 2330 | Location: &'a DILocation,
|
2271 | 2331 | BD: c_uint,
|
|
0 commit comments