llvm_quick 181.0.0-alpha.7

Rust's wrapper for llvm.
Documentation
use std::ptr::null_mut;

use llvm_sys::core::*;
use llvm_sys::LLVMOpaqueOperandBundle;

use crate::owning::{OpaqueDrop, Owning};
use crate::type_tag::*;
use crate::*;

impl<'c> OperandBundle<'c> {
    pub fn create<T: TypeTag>(tag: &[u8], args: &[&'c Value<T>]) -> Owning<Self> {
        unsafe {
            Owning::from_raw(LLVMCreateOperandBundle(
                tag.as_ptr() as _,
                tag.len(),
                args.as_ptr() as _,
                args.len() as _,
            ))
        }
    }
}

impl OpaqueDrop for LLVMOpaqueOperandBundle {
    unsafe fn drop_raw(ptr: *mut Self) {
        unsafe { LLVMDisposeOperandBundle(ptr) }
    }
}

impl<'c> OperandBundle<'c> {
    pub fn get_tag(&self) -> &[u8] {
        unsafe {
            let mut len = 0;
            let ptr = LLVMGetOperandBundleTag(self.as_raw(), &mut len);
            std::slice::from_raw_parts(ptr as _, len)
        }
    }

    pub fn get_num_args(&self) -> u32 {
        unsafe { LLVMGetNumOperandBundleArgs(self.as_raw()) }
    }

    pub fn get_arg_at_index(&self, index: u32) -> &'c Value<any> {
        unsafe { Value::from_raw(LLVMGetOperandBundleArgAtIndex(self.as_raw(), index)) }
    }
}

impl<'c> Module<'c> {
    pub fn get_named_global_i_func(&self, name: &[u8]) -> &'c Value<any> {
        unsafe {
            Value::from_raw(LLVMGetNamedGlobalIFunc(
                self.as_raw(),
                name.as_ptr() as _,
                name.len(),
            ))
        }
    }

    pub fn get_first_global_i_func(&self) -> &'c Value<any> {
        unsafe { Value::from_raw(LLVMGetFirstGlobalIFunc(self.as_raw())) }
    }

    pub fn get_last_global_i_func(&self) -> &'c Value<any> {
        unsafe { Value::from_raw(LLVMGetLastGlobalIFunc(self.as_raw())) }
    }
}

impl<T: TypeTag> Value<T> {
    pub fn get_next_global_i_func(&self) -> Option<&Value<any>> {
        unsafe { Value::from_ptr(LLVMGetNextGlobalIFunc(self.as_raw())) }
    }

    pub fn get_previous_global_i_func(&self) -> Option<&Value<any>> {
        unsafe { Value::from_ptr(LLVMGetPreviousGlobalIFunc(self.as_raw())) }
    }

    pub fn get_global_i_func_resolver(&self) -> Option<&Value<any>> {
        unsafe { Value::from_ptr(LLVMGetGlobalIFuncResolver(self.as_raw())) }
    }

    pub fn set_global_i_func_resolver<S: TypeTag>(&self, resolver: Option<&Value<S>>) {
        unsafe {
            LLVMSetGlobalIFuncResolver(
                self.as_raw(),
                resolver.map(Value::as_raw).unwrap_or(null_mut()),
            )
        }
    }

    pub fn erase_global_i_func(&self) {
        unsafe { LLVMEraseGlobalIFunc(self.as_raw()) }
    }

    pub fn remove_global_i_func(&self) {
        unsafe { LLVMRemoveGlobalIFunc(self.as_raw()) }
    }
}

impl Context {
    pub fn md_string(&self, str: &[u8]) -> &Metadata {
        unsafe {
            Metadata::from_raw(LLVMMDStringInContext2(
                self.as_raw(),
                str.as_ptr() as _,
                str.len(),
            ))
        }
    }

    pub fn md_node(&self, mds: &[&Metadata]) -> &Metadata {
        unsafe {
            Metadata::from_raw(LLVMMDNodeInContext2(
                self.as_raw(),
                mds.as_ptr() as _,
                mds.len(),
            ))
        }
    }
}

impl Metadata {
    pub fn as_value<'c>(&self, context: &'c Context) -> &'c Value<metadata> {
        unsafe { Value::from_raw(LLVMMetadataAsValue(context.as_raw(), self.as_raw())) }
    }
}

impl Value<metadata> {
    pub fn as_metadata(&self) -> &Metadata {
        unsafe { Metadata::from_raw(LLVMValueAsMetadata(self.as_raw())) }
    }
}

impl Value<metadata> {
    pub fn get_md_string(&self) -> Option<&[u8]> {
        unsafe {
            let mut len = 0;
            let ptr = LLVMGetMDString(self.as_raw(), &mut len);
            if ptr.is_null() {
                None
            } else {
                Some(std::slice::from_raw_parts(ptr as _, len as _))
            }
        }
    }

    pub fn get_md_node_num_operands(&self) -> u32 {
        unsafe { LLVMGetMDNodeNumOperands(self.as_raw()) }
    }

    pub fn get_md_node_operands<'s, 'c>(
        &self,
        dest: &'s mut [Option<&'c Value<metadata>>],
    ) -> &'s mut [&'c Value<metadata>] {
        unsafe {
            LLVMGetMDNodeOperands(self.as_raw(), dest.as_mut_ptr() as _);
            &mut *(dest as *mut [Option<&Value<metadata>>] as *mut [&Value<metadata>])
        }
    }

    pub fn replace_md_node_operand_with(&self, index: u32, replacement: &Metadata) {
        unsafe { LLVMReplaceMDNodeOperandWith(self.as_raw(), index, replacement.as_raw()) }
    }
}