rustc_codegen_llvm/back/
owned_target_machine.rs
1use std::ffi::{CStr, c_char};
2use std::marker::PhantomData;
3use std::ops::Deref;
4use std::ptr::NonNull;
5
6use rustc_data_structures::small_c_str::SmallCStr;
7
8use crate::errors::LlvmError;
9use crate::llvm;
10
11#[repr(transparent)]
14pub struct OwnedTargetMachine {
15 tm_unique: NonNull<llvm::TargetMachine>,
16 phantom: PhantomData<llvm::TargetMachine>,
17}
18
19impl OwnedTargetMachine {
20 pub(crate) fn new(
21 triple: &CStr,
22 cpu: &CStr,
23 features: &CStr,
24 abi: &CStr,
25 model: llvm::CodeModel,
26 reloc: llvm::RelocModel,
27 level: llvm::CodeGenOptLevel,
28 float_abi: llvm::FloatAbi,
29 function_sections: bool,
30 data_sections: bool,
31 unique_section_names: bool,
32 trap_unreachable: bool,
33 singlethread: bool,
34 verbose_asm: bool,
35 emit_stack_size_section: bool,
36 relax_elf_relocations: bool,
37 use_init_array: bool,
38 split_dwarf_file: &CStr,
39 output_obj_file: &CStr,
40 debug_info_compression: &CStr,
41 use_emulated_tls: bool,
42 args_cstr_buff: &[u8],
43 ) -> Result<Self, LlvmError<'static>> {
44 assert!(args_cstr_buff.len() > 0);
45 assert!(
46 *args_cstr_buff.last().unwrap() == 0,
47 "The last character must be a null terminator."
48 );
49
50 let tm_ptr = unsafe {
52 llvm::LLVMRustCreateTargetMachine(
53 triple.as_ptr(),
54 cpu.as_ptr(),
55 features.as_ptr(),
56 abi.as_ptr(),
57 model,
58 reloc,
59 level,
60 float_abi,
61 function_sections,
62 data_sections,
63 unique_section_names,
64 trap_unreachable,
65 singlethread,
66 verbose_asm,
67 emit_stack_size_section,
68 relax_elf_relocations,
69 use_init_array,
70 split_dwarf_file.as_ptr(),
71 output_obj_file.as_ptr(),
72 debug_info_compression.as_ptr(),
73 use_emulated_tls,
74 args_cstr_buff.as_ptr() as *const c_char,
75 args_cstr_buff.len(),
76 )
77 };
78
79 NonNull::new(tm_ptr)
80 .map(|tm_unique| Self { tm_unique, phantom: PhantomData })
81 .ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
82 }
83}
84
85impl Deref for OwnedTargetMachine {
86 type Target = llvm::TargetMachine;
87
88 fn deref(&self) -> &Self::Target {
89 unsafe { self.tm_unique.as_ref() }
92 }
93}
94
95impl Drop for OwnedTargetMachine {
96 fn drop(&mut self) {
97 unsafe {
101 llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut());
102 }
103 }
104}