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::*;

use crate::opaque::Opaque;
use crate::type_tag::*;
use crate::*;

impl<T: TypeTag> Instruction<T> {
    pub fn has_metadata(&self) -> bool {
        unsafe { LLVMHasMetadata(self.as_raw()) != 0 }
    }

    pub fn get_metadata(&self, kind_id: u32) -> Option<&Value<metadata>> {
        unsafe { Value::from_ptr(LLVMGetMetadata(self.as_raw(), kind_id)) }
    }

    pub fn set_metadata(&self, kind_id: u32, node: Option<&Value<metadata>>) {
        unsafe {
            LLVMSetMetadata(
                self.as_raw(),
                kind_id,
                node.map(Value::as_raw).unwrap_or(null_mut()),
            )
        }
    }

    pub fn instruction_get_all_metadata_other_than_debug_loc(&self) -> ValueMetadataEntries {
        unsafe {
            let mut len = 0;
            let ptr = LLVMInstructionGetAllMetadataOtherThanDebugLoc(self.as_raw(), &mut len);
            ValueMetadataEntries::from_raw(ptr, len)
        }
    }

    pub fn get_instruction_parent(&self) -> &BasicBlock {
        unsafe { BasicBlock::from_raw(LLVMGetInstructionParent(self.as_raw())) }
    }

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

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

    pub fn instruction_remove_from_parent(&self) {
        unsafe { LLVMInstructionRemoveFromParent(self.as_raw()) }
    }

    pub unsafe fn instruction_erase_from_parent(&self) {
        unsafe { LLVMInstructionEraseFromParent(self.as_raw()) }
    }

    pub unsafe fn delete_instruction(&self) {
        unsafe { LLVMDeleteInstruction(self.as_raw()) }
    }

    pub fn get_instruction_opcode(&self) -> LLVMOpcode {
        unsafe { LLVMGetInstructionOpcode(self.as_raw()) }
    }

    pub fn get_i_cmp_predicate(&self) -> LLVMIntPredicate {
        unsafe { LLVMGetICmpPredicate(self.as_raw()) }
    }

    pub fn get_f_cmp_predicate(&self) -> LLVMRealPredicate {
        unsafe { LLVMGetFCmpPredicate(self.as_raw()) }
    }

    pub fn instruction_clone(&self) -> &Value<T> {
        unsafe { Value::from_raw(LLVMInstructionClone(self.as_raw())) }
    }

    pub fn is_a_terminator_inst(&self) -> Option<&Value<T>> {
        unsafe { Value::from_ptr(LLVMIsATerminatorInst(self.as_raw())) }
    }

    pub fn get_num_arg_operands(&self) -> u32 {
        unsafe { LLVMGetNumArgOperands(self.as_raw()) }
    }

    pub fn set_instruction_call_conv(&self, cc: u32) {
        unsafe { LLVMSetInstructionCallConv(self.as_raw(), cc) }
    }

    pub fn get_instruction_call_conv(&self) -> u32 {
        unsafe { LLVMGetInstructionCallConv(self.as_raw()) }
    }

    pub fn set_instr_param_alignment(&self, idx: LLVMAttributeIndex, align: u32) {
        unsafe { LLVMSetInstrParamAlignment(self.as_raw(), idx, align) }
    }

    pub fn add_call_site_attribute(&self, idx: LLVMAttributeIndex, a: &Attribute) {
        unsafe { LLVMAddCallSiteAttribute(self.as_raw(), idx, a.as_raw()) }
    }

    pub fn get_call_site_attribute_count(&self, idx: LLVMAttributeIndex) -> u32 {
        unsafe { LLVMGetCallSiteAttributeCount(self.as_raw(), idx) }
    }

    pub fn get_call_site_attributes<'s, 'c>(
        &'c self,
        idx: LLVMAttributeIndex,
        slice: &'s mut [Option<&'c Attribute>],
    ) -> &'s mut [&'c Attribute] {
        unsafe {
            LLVMGetCallSiteAttributes(self.as_raw(), idx, slice.as_mut_ptr() as _);
            std::mem::transmute(slice)
        }
    }

    pub fn get_call_site_enum_attribute(
        &self,
        idx: LLVMAttributeIndex,
        kind_id: u32,
    ) -> &Attribute {
        unsafe { Attribute::from_raw(LLVMGetCallSiteEnumAttribute(self.as_raw(), idx, kind_id)) }
    }

    pub fn get_call_site_string_attribute(&self, idx: LLVMAttributeIndex, k: &[u8]) -> &Attribute {
        unsafe {
            Attribute::from_raw(LLVMGetCallSiteStringAttribute(
                self.as_raw(),
                idx,
                k.as_ptr() as _,
                k.len() as _,
            ))
        }
    }

    pub fn remove_call_site_enum_attribute(&self, idx: LLVMAttributeIndex, kind_id: u32) {
        unsafe { LLVMRemoveCallSiteEnumAttribute(self.as_raw(), idx, kind_id) }
    }

    pub fn remove_call_site_string_attribute(&self, idx: LLVMAttributeIndex, k: &[u8]) {
        unsafe {
            LLVMRemoveCallSiteStringAttribute(self.as_raw(), idx, k.as_ptr() as _, k.len() as _)
        }
    }

    pub fn get_called_function_type(&self) -> Option<&Type<fun_any>> {
        unsafe { Type::from_ptr(LLVMGetCalledFunctionType(self.as_raw())) }
    }

    pub fn get_called_value(&self) -> &Value<fun_any> {
        unsafe { Value::from_raw(LLVMGetCalledValue(self.as_raw())) }
    }

    pub fn get_num_operand_bundles(&self) -> u32 {
        unsafe { LLVMGetNumOperandBundles(self.as_raw()) }
    }

    pub fn get_operand_bundle_as_index(&self, index: u32) -> &OperandBundle {
        unsafe { OperandBundle::from_raw(LLVMGetOperandBundleAtIndex(self.as_raw(), index)) }
    }

    pub fn is_tail_call(&self) -> bool {
        unsafe { LLVMIsTailCall(self.as_raw()) != 0 }
    }

    pub fn set_tail_call(&self, is_tail_call: bool) {
        unsafe { LLVMSetTailCall(self.as_raw(), is_tail_call as _) }
    }

    pub fn get_tail_call_kind(&self) -> LLVMTailCallKind {
        unsafe { LLVMGetTailCallKind(self.as_raw()) }
    }

    pub fn set_tail_call_kind(&self, kind: LLVMTailCallKind) {
        unsafe { LLVMSetTailCallKind(self.as_raw(), kind) }
    }

    pub fn get_normal_dest(&self) -> &BasicBlock {
        unsafe { BasicBlock::from_raw(LLVMGetNormalDest(self.as_raw())) }
    }

    pub fn get_unwind_dest(&self) -> &BasicBlock {
        unsafe { BasicBlock::from_raw(LLVMGetUnwindDest(self.as_raw())) }
    }

    pub fn set_normal_dest(&self, b: &BasicBlock) {
        unsafe { LLVMSetNormalDest(self.as_raw(), b.as_raw()) }
    }

    pub fn set_unwind_dest(&self, b: &BasicBlock) {
        unsafe { LLVMSetUnwindDest(self.as_raw(), b.as_raw()) }
    }
}

impl<T: TypeTag> Instruction<T> {
    pub fn get_num_successors(&self) -> u32 {
        unsafe { LLVMGetNumSuccessors(self.as_raw()) }
    }

    pub fn get_successor(&self, i: u32) -> &BasicBlock {
        unsafe { BasicBlock::from_raw(LLVMGetSuccessor(self.as_raw(), i)) }
    }

    pub fn set_successor(&self, i: u32, block: &BasicBlock) {
        unsafe { LLVMSetSuccessor(self.as_raw(), i, block.as_raw()) }
    }

    pub fn is_conditional(&self) -> bool {
        unsafe { LLVMIsConditional(self.as_raw()) != 0 }
    }

    pub fn get_conditional(&self) -> &Value<any> {
        unsafe { Value::from_raw(LLVMGetCondition(self.as_raw())) }
    }

    pub fn set_conditional(&self, cond: &Value<any>) {
        unsafe { LLVMSetCondition(self.as_raw(), cond.as_raw()) }
    }

    pub fn get_switch_default_dest(&self) -> &BasicBlock {
        unsafe { BasicBlock::from_raw(LLVMGetSwitchDefaultDest(self.as_raw())) }
    }
}

impl<T: TypeTag> Instruction<T> {
    pub fn get_allocated_type(&self) -> &Type<any> {
        unsafe { Type::from_raw(LLVMGetAllocatedType(self.as_raw())) }
    }
}

impl<T: TypeTag> Instruction<T> {
    pub fn is_in_bounds(&self) -> bool {
        unsafe { LLVMIsInBounds(self.as_raw()) != 0 }
    }

    pub fn set_is_in_bounds(&self, in_bounds: bool) {
        unsafe { LLVMSetIsInBounds(self.as_raw(), in_bounds as _) }
    }

    pub fn get_gep_source_element_type(&self) -> &Type<any> {
        unsafe { Type::from_raw(LLVMGetGEPSourceElementType(self.as_raw())) }
    }
}

impl<T: TypeTag> Instruction<T> {
    pub fn add_incoming(&self, v: &[&Value<any>], b: &[&BasicBlock]) {
        assert_eq!(v.len(), b.len());
        unsafe {
            LLVMAddIncoming(
                self.as_raw(),
                v.as_ptr() as _,
                b.as_ptr() as _,
                v.len() as _,
            )
        }
    }

    pub fn count_incoming(&self) -> u32 {
        unsafe { LLVMCountIncoming(self.as_raw()) }
    }

    pub fn get_incoming_value(&self, index: u32) -> &Value<any> {
        unsafe { Value::from_raw(LLVMGetIncomingValue(self.as_raw(), index)) }
    }

    pub fn get_incoming_block(&self, index: u32) -> &BasicBlock {
        unsafe { BasicBlock::from_raw(LLVMGetIncomingBlock(self.as_raw(), index)) }
    }
}