/// LLVM target machine options provide another way to create target machines,
/// used with [Target::create_target_machine_from_options].
///
/// The option structure exposes an additional setting (i.e., the target ABI)
/// and provides default values for unspecified settings.
#[llvm_versions(18..)]
#[derive(Default, Debug)]
pub struct TargetMachineOptions(Option<LLVMTargetMachineOptionsRef>);
It stores an Option internally, but not for any particular reason besides lazy initialization, which doesn't seem necessary.
#[llvm_versions(18..)]
impl TargetMachineOptions {
pub fn new() -> Self {
Default::default()
}
pub fn set_cpu(mut self, cpu: &str) -> Self {
let cpu = to_c_str(cpu);
unsafe { LLVMTargetMachineOptionsSetCPU(self.inner(), cpu.as_ptr()) };
self
}
pub fn set_features(mut self, features: &str) -> Self {
let features = to_c_str(features);
unsafe { LLVMTargetMachineOptionsSetFeatures(self.inner(), features.as_ptr()) };
self
}
pub fn set_abi(mut self, abi: &str) -> Self {
let abi = to_c_str(abi);
unsafe { LLVMTargetMachineOptionsSetABI(self.inner(), abi.as_ptr()) };
self
}
pub fn set_level(mut self, level: OptimizationLevel) -> Self {
unsafe { LLVMTargetMachineOptionsSetCodeGenOptLevel(self.inner(), level.into()) };
self
}
pub fn set_reloc_mode(mut self, reloc_mode: RelocMode) -> Self {
unsafe { LLVMTargetMachineOptionsSetRelocMode(self.inner(), reloc_mode.into()) }
self
}
pub fn set_code_model(mut self, code_model: CodeModel) -> Self {
unsafe { LLVMTargetMachineOptionsSetCodeModel(self.inner(), code_model.into()) };
self
}
fn into_target_machine(mut self, target: LLVMTargetRef, triple: &TargetTriple) -> Option<TargetMachine> {
let target_machine = unsafe { LLVMCreateTargetMachineWithOptions(target, triple.as_ptr(), self.inner()) };
if target_machine.is_null() {
return None;
}
unsafe { Some(TargetMachine::new(target_machine)) }
}
/// SAFETY:
/// - The internal `LLVMCreateTargetMachineOptionsRef` structure leaks memory
/// if not disposed via `fn LLVMCreateTargetMachineWithOptions()`.
/// - The only way to access it is via this private method.
/// - Disposal is taken care of automatically in `Drop::drop`.
unsafe fn inner(&mut self) -> LLVMTargetMachineOptionsRef {
unsafe { *self.0.get_or_insert_with(|| LLVMCreateTargetMachineOptions()) }
}
}
#[llvm_versions(18..)]
impl Drop for TargetMachineOptions {
fn drop(&mut self) {
if let Some(inner) = self.0 {
unsafe { LLVMDisposeTargetMachineOptions(inner) };
}
}
}
It stores an
Optioninternally, but not for any particular reason besides lazy initialization, which doesn't seem necessary.