Skip to main content

rustc_llvm/
lib.rs

1// tidy-alphabetical-start
2#![feature(extern_types)]
3// tidy-alphabetical-end
4
5use std::cell::RefCell;
6use std::{ptr, slice};
7
8use libc::size_t;
9
10unsafe extern "C" {
11    /// Opaque type that allows C++ code to write bytes to a Rust-side buffer,
12    /// in conjunction with `RawRustStringOstream`. Use this as `&RustString`
13    /// (Rust) and `RustStringRef` (C++) in FFI signatures.
14    pub type RustString;
15}
16
17impl RustString {
18    pub fn build_byte_buffer(closure: impl FnOnce(&Self)) -> Vec<u8> {
19        let buf = RustStringInner::default();
20        closure(buf.as_opaque());
21        buf.into_inner()
22    }
23}
24
25/// Underlying implementation of [`RustString`].
26///
27/// Having two separate types makes it possible to use the opaque [`RustString`]
28/// in FFI signatures without `improper_ctypes` warnings. This is a workaround
29/// for the fact that there is no way to opt out of `improper_ctypes` when
30/// _declaring_ a type (as opposed to using that type).
31#[derive(#[automatically_derived]
impl ::core::default::Default for RustStringInner {
    #[inline]
    fn default() -> RustStringInner {
        RustStringInner { bytes: ::core::default::Default::default() }
    }
}Default)]
32struct RustStringInner {
33    bytes: RefCell<Vec<u8>>,
34}
35
36impl RustStringInner {
37    fn as_opaque(&self) -> &RustString {
38        let ptr: *const RustStringInner = ptr::from_ref(self);
39        // We can't use `ptr::cast` here because extern types are `!Sized`.
40        let ptr = ptr as *const RustString;
41        unsafe { &*ptr }
42    }
43
44    fn from_opaque(opaque: &RustString) -> &Self {
45        // SAFETY: A valid `&RustString` must have been created via `as_opaque`.
46        let ptr: *const RustString = ptr::from_ref(opaque);
47        let ptr: *const RustStringInner = ptr.cast();
48        unsafe { &*ptr }
49    }
50
51    fn into_inner(self) -> Vec<u8> {
52        self.bytes.into_inner()
53    }
54}
55
56/// Appends the contents of a byte slice to a [`RustString`].
57///
58/// This function is implemented in `rustc_llvm` so that the C++ code in this
59/// crate can link to it directly, without an implied link-time dependency on
60/// `rustc_codegen_llvm`.
61#[unsafe(no_mangle)]
62pub unsafe extern "C" fn LLVMRustStringWriteImpl(
63    buf: &RustString,
64    slice_ptr: *const u8, // Same ABI as `*const c_char`
65    slice_len: size_t,
66) {
67    let slice = unsafe { slice::from_raw_parts(slice_ptr, slice_len) };
68    RustStringInner::from_opaque(buf).bytes.borrow_mut().extend_from_slice(slice);
69}
70
71/// Initialize targets enabled by the build script via `cfg(llvm_component = "...")`.
72/// N.B., this function can't be moved to `rustc_codegen_llvm` because of the `cfg`s.
73pub fn initialize_available_targets() {
74    macro_rules! init_target(
75        ($cfg:meta, $($method:ident),*) => { {
76            #[cfg($cfg)]
77            fn init() {
78                unsafe extern "C" {
79                    $(fn $method();)*
80                }
81                unsafe {
82                    $($method();)*
83                }
84            }
85            #[cfg(not($cfg))]
86            fn init() { }
87            init();
88        } }
89    );
90    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeX86TargetInfo();
            fn LLVMInitializeX86Target();
            fn LLVMInitializeX86TargetMC();
            fn LLVMInitializeX86AsmPrinter();
            fn LLVMInitializeX86AsmParser();
        }
        unsafe {
            LLVMInitializeX86TargetInfo();
            LLVMInitializeX86Target();
            LLVMInitializeX86TargetMC();
            LLVMInitializeX86AsmPrinter();
            LLVMInitializeX86AsmParser();
        }
    }
    init();
};init_target!(
91        llvm_component = "x86",
92        LLVMInitializeX86TargetInfo,
93        LLVMInitializeX86Target,
94        LLVMInitializeX86TargetMC,
95        LLVMInitializeX86AsmPrinter,
96        LLVMInitializeX86AsmParser
97    );
98    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeARMTargetInfo();
            fn LLVMInitializeARMTarget();
            fn LLVMInitializeARMTargetMC();
            fn LLVMInitializeARMAsmPrinter();
            fn LLVMInitializeARMAsmParser();
        }
        unsafe {
            LLVMInitializeARMTargetInfo();
            LLVMInitializeARMTarget();
            LLVMInitializeARMTargetMC();
            LLVMInitializeARMAsmPrinter();
            LLVMInitializeARMAsmParser();
        }
    }
    init();
};init_target!(
99        llvm_component = "arm",
100        LLVMInitializeARMTargetInfo,
101        LLVMInitializeARMTarget,
102        LLVMInitializeARMTargetMC,
103        LLVMInitializeARMAsmPrinter,
104        LLVMInitializeARMAsmParser
105    );
106    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeAArch64TargetInfo();
            fn LLVMInitializeAArch64Target();
            fn LLVMInitializeAArch64TargetMC();
            fn LLVMInitializeAArch64AsmPrinter();
            fn LLVMInitializeAArch64AsmParser();
        }
        unsafe {
            LLVMInitializeAArch64TargetInfo();
            LLVMInitializeAArch64Target();
            LLVMInitializeAArch64TargetMC();
            LLVMInitializeAArch64AsmPrinter();
            LLVMInitializeAArch64AsmParser();
        }
    }
    init();
};init_target!(
107        llvm_component = "aarch64",
108        LLVMInitializeAArch64TargetInfo,
109        LLVMInitializeAArch64Target,
110        LLVMInitializeAArch64TargetMC,
111        LLVMInitializeAArch64AsmPrinter,
112        LLVMInitializeAArch64AsmParser
113    );
114    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeAMDGPUTargetInfo();
            fn LLVMInitializeAMDGPUTarget();
            fn LLVMInitializeAMDGPUTargetMC();
            fn LLVMInitializeAMDGPUAsmPrinter();
            fn LLVMInitializeAMDGPUAsmParser();
        }
        unsafe {
            LLVMInitializeAMDGPUTargetInfo();
            LLVMInitializeAMDGPUTarget();
            LLVMInitializeAMDGPUTargetMC();
            LLVMInitializeAMDGPUAsmPrinter();
            LLVMInitializeAMDGPUAsmParser();
        }
    }
    init();
};init_target!(
115        llvm_component = "amdgpu",
116        LLVMInitializeAMDGPUTargetInfo,
117        LLVMInitializeAMDGPUTarget,
118        LLVMInitializeAMDGPUTargetMC,
119        LLVMInitializeAMDGPUAsmPrinter,
120        LLVMInitializeAMDGPUAsmParser
121    );
122    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeAVRTargetInfo();
            fn LLVMInitializeAVRTarget();
            fn LLVMInitializeAVRTargetMC();
            fn LLVMInitializeAVRAsmPrinter();
            fn LLVMInitializeAVRAsmParser();
        }
        unsafe {
            LLVMInitializeAVRTargetInfo();
            LLVMInitializeAVRTarget();
            LLVMInitializeAVRTargetMC();
            LLVMInitializeAVRAsmPrinter();
            LLVMInitializeAVRAsmParser();
        }
    }
    init();
};init_target!(
123        llvm_component = "avr",
124        LLVMInitializeAVRTargetInfo,
125        LLVMInitializeAVRTarget,
126        LLVMInitializeAVRTargetMC,
127        LLVMInitializeAVRAsmPrinter,
128        LLVMInitializeAVRAsmParser
129    );
130    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeM68kTargetInfo();
            fn LLVMInitializeM68kTarget();
            fn LLVMInitializeM68kTargetMC();
            fn LLVMInitializeM68kAsmPrinter();
            fn LLVMInitializeM68kAsmParser();
        }
        unsafe {
            LLVMInitializeM68kTargetInfo();
            LLVMInitializeM68kTarget();
            LLVMInitializeM68kTargetMC();
            LLVMInitializeM68kAsmPrinter();
            LLVMInitializeM68kAsmParser();
        }
    }
    init();
};init_target!(
131        llvm_component = "m68k",
132        LLVMInitializeM68kTargetInfo,
133        LLVMInitializeM68kTarget,
134        LLVMInitializeM68kTargetMC,
135        LLVMInitializeM68kAsmPrinter,
136        LLVMInitializeM68kAsmParser
137    );
138    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeCSKYTargetInfo();
            fn LLVMInitializeCSKYTarget();
            fn LLVMInitializeCSKYTargetMC();
            fn LLVMInitializeCSKYAsmPrinter();
            fn LLVMInitializeCSKYAsmParser();
        }
        unsafe {
            LLVMInitializeCSKYTargetInfo();
            LLVMInitializeCSKYTarget();
            LLVMInitializeCSKYTargetMC();
            LLVMInitializeCSKYAsmPrinter();
            LLVMInitializeCSKYAsmParser();
        }
    }
    init();
};init_target!(
139        llvm_component = "csky",
140        LLVMInitializeCSKYTargetInfo,
141        LLVMInitializeCSKYTarget,
142        LLVMInitializeCSKYTargetMC,
143        LLVMInitializeCSKYAsmPrinter,
144        LLVMInitializeCSKYAsmParser
145    );
146    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeLoongArchTargetInfo();
            fn LLVMInitializeLoongArchTarget();
            fn LLVMInitializeLoongArchTargetMC();
            fn LLVMInitializeLoongArchAsmPrinter();
            fn LLVMInitializeLoongArchAsmParser();
        }
        unsafe {
            LLVMInitializeLoongArchTargetInfo();
            LLVMInitializeLoongArchTarget();
            LLVMInitializeLoongArchTargetMC();
            LLVMInitializeLoongArchAsmPrinter();
            LLVMInitializeLoongArchAsmParser();
        }
    }
    init();
};init_target!(
147        llvm_component = "loongarch",
148        LLVMInitializeLoongArchTargetInfo,
149        LLVMInitializeLoongArchTarget,
150        LLVMInitializeLoongArchTargetMC,
151        LLVMInitializeLoongArchAsmPrinter,
152        LLVMInitializeLoongArchAsmParser
153    );
154    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeMipsTargetInfo();
            fn LLVMInitializeMipsTarget();
            fn LLVMInitializeMipsTargetMC();
            fn LLVMInitializeMipsAsmPrinter();
            fn LLVMInitializeMipsAsmParser();
        }
        unsafe {
            LLVMInitializeMipsTargetInfo();
            LLVMInitializeMipsTarget();
            LLVMInitializeMipsTargetMC();
            LLVMInitializeMipsAsmPrinter();
            LLVMInitializeMipsAsmParser();
        }
    }
    init();
};init_target!(
155        llvm_component = "mips",
156        LLVMInitializeMipsTargetInfo,
157        LLVMInitializeMipsTarget,
158        LLVMInitializeMipsTargetMC,
159        LLVMInitializeMipsAsmPrinter,
160        LLVMInitializeMipsAsmParser
161    );
162    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializePowerPCTargetInfo();
            fn LLVMInitializePowerPCTarget();
            fn LLVMInitializePowerPCTargetMC();
            fn LLVMInitializePowerPCAsmPrinter();
            fn LLVMInitializePowerPCAsmParser();
        }
        unsafe {
            LLVMInitializePowerPCTargetInfo();
            LLVMInitializePowerPCTarget();
            LLVMInitializePowerPCTargetMC();
            LLVMInitializePowerPCAsmPrinter();
            LLVMInitializePowerPCAsmParser();
        }
    }
    init();
};init_target!(
163        llvm_component = "powerpc",
164        LLVMInitializePowerPCTargetInfo,
165        LLVMInitializePowerPCTarget,
166        LLVMInitializePowerPCTargetMC,
167        LLVMInitializePowerPCAsmPrinter,
168        LLVMInitializePowerPCAsmParser
169    );
170    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeSystemZTargetInfo();
            fn LLVMInitializeSystemZTarget();
            fn LLVMInitializeSystemZTargetMC();
            fn LLVMInitializeSystemZAsmPrinter();
            fn LLVMInitializeSystemZAsmParser();
        }
        unsafe {
            LLVMInitializeSystemZTargetInfo();
            LLVMInitializeSystemZTarget();
            LLVMInitializeSystemZTargetMC();
            LLVMInitializeSystemZAsmPrinter();
            LLVMInitializeSystemZAsmParser();
        }
    }
    init();
};init_target!(
171        llvm_component = "systemz",
172        LLVMInitializeSystemZTargetInfo,
173        LLVMInitializeSystemZTarget,
174        LLVMInitializeSystemZTargetMC,
175        LLVMInitializeSystemZAsmPrinter,
176        LLVMInitializeSystemZAsmParser
177    );
178    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeMSP430TargetInfo();
            fn LLVMInitializeMSP430Target();
            fn LLVMInitializeMSP430TargetMC();
            fn LLVMInitializeMSP430AsmPrinter();
            fn LLVMInitializeMSP430AsmParser();
        }
        unsafe {
            LLVMInitializeMSP430TargetInfo();
            LLVMInitializeMSP430Target();
            LLVMInitializeMSP430TargetMC();
            LLVMInitializeMSP430AsmPrinter();
            LLVMInitializeMSP430AsmParser();
        }
    }
    init();
};init_target!(
179        llvm_component = "msp430",
180        LLVMInitializeMSP430TargetInfo,
181        LLVMInitializeMSP430Target,
182        LLVMInitializeMSP430TargetMC,
183        LLVMInitializeMSP430AsmPrinter,
184        LLVMInitializeMSP430AsmParser
185    );
186    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeRISCVTargetInfo();
            fn LLVMInitializeRISCVTarget();
            fn LLVMInitializeRISCVTargetMC();
            fn LLVMInitializeRISCVAsmPrinter();
            fn LLVMInitializeRISCVAsmParser();
        }
        unsafe {
            LLVMInitializeRISCVTargetInfo();
            LLVMInitializeRISCVTarget();
            LLVMInitializeRISCVTargetMC();
            LLVMInitializeRISCVAsmPrinter();
            LLVMInitializeRISCVAsmParser();
        }
    }
    init();
};init_target!(
187        llvm_component = "riscv",
188        LLVMInitializeRISCVTargetInfo,
189        LLVMInitializeRISCVTarget,
190        LLVMInitializeRISCVTargetMC,
191        LLVMInitializeRISCVAsmPrinter,
192        LLVMInitializeRISCVAsmParser
193    );
194    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeSparcTargetInfo();
            fn LLVMInitializeSparcTarget();
            fn LLVMInitializeSparcTargetMC();
            fn LLVMInitializeSparcAsmPrinter();
            fn LLVMInitializeSparcAsmParser();
        }
        unsafe {
            LLVMInitializeSparcTargetInfo();
            LLVMInitializeSparcTarget();
            LLVMInitializeSparcTargetMC();
            LLVMInitializeSparcAsmPrinter();
            LLVMInitializeSparcAsmParser();
        }
    }
    init();
};init_target!(
195        llvm_component = "sparc",
196        LLVMInitializeSparcTargetInfo,
197        LLVMInitializeSparcTarget,
198        LLVMInitializeSparcTargetMC,
199        LLVMInitializeSparcAsmPrinter,
200        LLVMInitializeSparcAsmParser
201    );
202    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeNVPTXTargetInfo();
            fn LLVMInitializeNVPTXTarget();
            fn LLVMInitializeNVPTXTargetMC();
            fn LLVMInitializeNVPTXAsmPrinter();
        }
        unsafe {
            LLVMInitializeNVPTXTargetInfo();
            LLVMInitializeNVPTXTarget();
            LLVMInitializeNVPTXTargetMC();
            LLVMInitializeNVPTXAsmPrinter();
        }
    }
    init();
};init_target!(
203        llvm_component = "nvptx",
204        LLVMInitializeNVPTXTargetInfo,
205        LLVMInitializeNVPTXTarget,
206        LLVMInitializeNVPTXTargetMC,
207        LLVMInitializeNVPTXAsmPrinter
208    );
209    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeHexagonTargetInfo();
            fn LLVMInitializeHexagonTarget();
            fn LLVMInitializeHexagonTargetMC();
            fn LLVMInitializeHexagonAsmPrinter();
            fn LLVMInitializeHexagonAsmParser();
        }
        unsafe {
            LLVMInitializeHexagonTargetInfo();
            LLVMInitializeHexagonTarget();
            LLVMInitializeHexagonTargetMC();
            LLVMInitializeHexagonAsmPrinter();
            LLVMInitializeHexagonAsmParser();
        }
    }
    init();
};init_target!(
210        llvm_component = "hexagon",
211        LLVMInitializeHexagonTargetInfo,
212        LLVMInitializeHexagonTarget,
213        LLVMInitializeHexagonTargetMC,
214        LLVMInitializeHexagonAsmPrinter,
215        LLVMInitializeHexagonAsmParser
216    );
217    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeXtensaTargetInfo();
            fn LLVMInitializeXtensaTarget();
            fn LLVMInitializeXtensaTargetMC();
            fn LLVMInitializeXtensaAsmPrinter();
            fn LLVMInitializeXtensaAsmParser();
        }
        unsafe {
            LLVMInitializeXtensaTargetInfo();
            LLVMInitializeXtensaTarget();
            LLVMInitializeXtensaTargetMC();
            LLVMInitializeXtensaAsmPrinter();
            LLVMInitializeXtensaAsmParser();
        }
    }
    init();
};init_target!(
218        llvm_component = "xtensa",
219        LLVMInitializeXtensaTargetInfo,
220        LLVMInitializeXtensaTarget,
221        LLVMInitializeXtensaTargetMC,
222        LLVMInitializeXtensaAsmPrinter,
223        LLVMInitializeXtensaAsmParser
224    );
225    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeWebAssemblyTargetInfo();
            fn LLVMInitializeWebAssemblyTarget();
            fn LLVMInitializeWebAssemblyTargetMC();
            fn LLVMInitializeWebAssemblyAsmPrinter();
            fn LLVMInitializeWebAssemblyAsmParser();
        }
        unsafe {
            LLVMInitializeWebAssemblyTargetInfo();
            LLVMInitializeWebAssemblyTarget();
            LLVMInitializeWebAssemblyTargetMC();
            LLVMInitializeWebAssemblyAsmPrinter();
            LLVMInitializeWebAssemblyAsmParser();
        }
    }
    init();
};init_target!(
226        llvm_component = "webassembly",
227        LLVMInitializeWebAssemblyTargetInfo,
228        LLVMInitializeWebAssemblyTarget,
229        LLVMInitializeWebAssemblyTargetMC,
230        LLVMInitializeWebAssemblyAsmPrinter,
231        LLVMInitializeWebAssemblyAsmParser
232    );
233    {
    fn init() {
        unsafe extern "C" {
            fn LLVMInitializeBPFTargetInfo();
            fn LLVMInitializeBPFTarget();
            fn LLVMInitializeBPFTargetMC();
            fn LLVMInitializeBPFAsmPrinter();
            fn LLVMInitializeBPFAsmParser();
        }
        unsafe {
            LLVMInitializeBPFTargetInfo();
            LLVMInitializeBPFTarget();
            LLVMInitializeBPFTargetMC();
            LLVMInitializeBPFAsmPrinter();
            LLVMInitializeBPFAsmParser();
        }
    }
    init();
};init_target!(
234        llvm_component = "bpf",
235        LLVMInitializeBPFTargetInfo,
236        LLVMInitializeBPFTarget,
237        LLVMInitializeBPFTargetMC,
238        LLVMInitializeBPFAsmPrinter,
239        LLVMInitializeBPFAsmParser
240    );
241}