use libc::c_uint;
use ffi::prelude::LLVMPassManagerRef;
use ffi::{core, target};
use ffi::transforms::pass_manager_builder as builder;
use ffi::transforms::pass_manager_builder::LLVMPassManagerBuilderRef;
use module::Module;
use target::TargetData;
pub struct PassManager {
manager: LLVMPassManagerRef
}
native_ref!(PassManager, manager: LLVMPassManagerRef);
impl PassManager {
pub fn new() -> PassManager {
unsafe { core::LLVMCreatePassManager() }.into()
}
pub fn add_target_data(&self, data: &TargetData) {
unsafe { target::LLVMAddTargetData(data.into(), self.into()) }
}
pub fn run(&self, module: &Module) -> Result<(), ()> {
if unsafe { core::LLVMRunPassManager(self.into(), module.into()) } == 0 {
Ok(())
} else {
Err(())
}
}
pub fn populate(&self, builder: PassManagerBuilder) {
unsafe { builder::LLVMPassManagerBuilderPopulateModulePassManager(builder.into(), self.into()) }
}
}
impl Drop for PassManager {
fn drop(&mut self) {
unsafe { core::LLVMDisposePassManager(self.into()) }
}
}
pub struct PassManagerBuilder {
builder: LLVMPassManagerBuilderRef
}
native_ref!(PassManagerBuilder, builder: LLVMPassManagerBuilderRef);
impl PassManagerBuilder {
pub fn new() -> PassManagerBuilder {
unsafe { builder::LLVMPassManagerBuilderCreate().into() }
}
pub fn with_opt_level(self, level: usize) -> PassManagerBuilder {
unsafe { builder::LLVMPassManagerBuilderSetOptLevel((&self).into(), level as c_uint) };
self
}
pub fn with_size_level(self, size: usize) -> PassManagerBuilder {
unsafe { builder::LLVMPassManagerBuilderSetOptLevel((&self).into(), size as c_uint) };
self
}
pub fn with_inliner(self, threshold: usize) -> PassManagerBuilder {
unsafe { builder::LLVMPassManagerBuilderUseInlinerWithThreshold((&self).into(), threshold as c_uint) };
self
}
}
impl Drop for PassManagerBuilder {
fn drop(&mut self) {
unsafe { builder::LLVMPassManagerBuilderDispose(self.into()) }
}
}