Skip to main content

rustc_codegen_llvm/back/
owned_mc_subtarget_info.rs

1use std::ffi::CStr;
2use std::ptr::NonNull;
3
4use rustc_data_structures::small_c_str::SmallCStr;
5
6use crate::diagnostics::LlvmError;
7use crate::llvm;
8
9/// Responsible for safely creating and disposing llvm::MCSubtargetInfo via ffi functions.
10/// Not cloneable as there is no clone function for llvm::MCSubtargetInfo.
11pub(crate) struct OwnedMCSubtargetInfo {
12    info_unique: NonNull<llvm::MCSubtargetInfo>,
13}
14
15impl OwnedMCSubtargetInfo {
16    pub(crate) fn new(
17        triple: &CStr,
18        cpu: &CStr,
19        features: &CStr,
20    ) -> Result<Self, LlvmError<'static>> {
21        // SAFETY: llvm::LLVMRustCreateMCSubtargetInfo copies pointed-to data.
22        let info_ptr = unsafe {
23            llvm::LLVMRustCreateMCSubtargetInfo(triple.as_ptr(), cpu.as_ptr(), features.as_ptr())
24        };
25
26        NonNull::new(info_ptr)
27            .map(|info_unique| Self { info_unique })
28            .ok_or_else(|| LlvmError::CreateMCSubtargetInfo { triple: SmallCStr::from(triple) })
29    }
30
31    pub(crate) fn has_feature(&self, feature: &CStr) -> bool {
32        // SAFETY: `new` ensures we have a valid pointer created by
33        // `llvm::LLVMRustCreateMCSubtargetInfo`.
34        unsafe {
35            llvm::LLVMRustMCSubtargetInfoHasFeature(self.info_unique.as_ref(), feature.as_ptr())
36        }
37    }
38}
39
40impl Drop for OwnedMCSubtargetInfo {
41    fn drop(&mut self) {
42        // SAFETY: `new` ensures we have a valid pointer created by
43        // `llvm::LLVMRustCreateMCSubtargetInfo` and `OwnedMCSubtargetInfo` is not copyable so
44        // there is no double free or use after free.
45        unsafe {
46            llvm::LLVMRustDisposeMCSubtargetInfo(self.info_unique);
47        }
48    }
49}