[−][src]Struct inkwell::builder::Builder
Methods
impl Builder
[src]
pub fn create() -> Self
[src]
Creates a Builder
belonging to the global Context
.
Example
use inkwell::builder::Builder; let builder = Builder::create();
pub fn build_return(&self, value: Option<&dyn BasicValue>) -> InstructionValue
[src]
Builds a function return instruction. It should be provided with None
if the return type
is void otherwise Some(&value)
should be provided.
Example
use inkwell::context::Context; // A simple function which returns its argument: let context = Context::create(); let module = context.create_module("ret"); let builder = context.create_builder(); let i32_type = context.i32_type(); let arg_types = [i32_type.into()]; let fn_type = i32_type.fn_type(&arg_types, false); let fn_value = module.add_function("ret", fn_type, None); let entry = fn_value.append_basic_block("entry"); let i32_arg = fn_value.get_first_param().unwrap(); builder.position_at_end(&entry); builder.build_return(Some(&i32_arg));
pub fn build_aggregate_return(
&self,
values: &[BasicValueEnum]
) -> InstructionValue
[src]
&self,
values: &[BasicValueEnum]
) -> InstructionValue
Builds a function return instruction for a return type which is an aggregate type (ie structs and arrays).
It is not necessary to use this over build_return
but may be more convenient to use.
Example
use inkwell::context::Context; // This builds a simple function which returns a struct (tuple) of two ints. let context = Context::create(); let module = context.create_module("ret"); let builder = context.create_builder(); let i32_type = context.i32_type(); let i32_three = i32_type.const_int(3, false); let i32_seven = i32_type.const_int(7, false); let struct_type = context.struct_type(&[i32_type.into(), i32_type.into()], false); let fn_type = struct_type.fn_type(&[], false); let fn_value = module.add_function("ret", fn_type, None); let entry = fn_value.append_basic_block("entry"); builder.position_at_end(&entry); builder.build_aggregate_return(&[i32_three.into(), i32_seven.into()]);
pub fn build_call<F>(
&self,
function: F,
args: &[BasicValueEnum],
name: &str
) -> CallSiteValue where
F: Into<Either<FunctionValue, PointerValue>>,
[src]
&self,
function: F,
args: &[BasicValueEnum],
name: &str
) -> CallSiteValue where
F: Into<Either<FunctionValue, PointerValue>>,
Builds a function call instruction. It can take either a FunctionValue
or a PointerValue
which is a function pointer. It will panic if the PointerValue
is not a function pointer.
This may be turned into a Result in the future, however.
Example
use inkwell::context::Context; // A simple function which calls itself: let context = Context::create(); let module = context.create_module("ret"); let builder = context.create_builder(); let i32_type = context.i32_type(); let fn_type = i32_type.fn_type(&[i32_type.into()], false); let fn_value = module.add_function("ret", fn_type, None); let entry = fn_value.append_basic_block("entry"); let i32_arg = fn_value.get_first_param().unwrap(); builder.position_at_end(&entry); let ret_val = builder.build_call(fn_value, &[i32_arg], "call") .try_as_basic_value() .left() .unwrap(); builder.build_return(Some(&ret_val));
pub unsafe fn build_gep(
&self,
ptr: PointerValue,
ordered_indexes: &[IntValue],
name: &str
) -> PointerValue
[src]
&self,
ptr: PointerValue,
ordered_indexes: &[IntValue],
name: &str
) -> PointerValue
GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future.
pub unsafe fn build_in_bounds_gep(
&self,
ptr: PointerValue,
ordered_indexes: &[IntValue],
name: &str
) -> PointerValue
[src]
&self,
ptr: PointerValue,
ordered_indexes: &[IntValue],
name: &str
) -> PointerValue
GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future.
pub unsafe fn build_struct_gep(
&self,
ptr: PointerValue,
index: u32,
name: &str
) -> PointerValue
[src]
&self,
ptr: PointerValue,
index: u32,
name: &str
) -> PointerValue
GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future.
pub fn build_ptr_diff(
&self,
lhs_ptr: PointerValue,
rhs_ptr: PointerValue,
name: &str
) -> IntValue
[src]
&self,
lhs_ptr: PointerValue,
rhs_ptr: PointerValue,
name: &str
) -> IntValue
Builds an instruction which calculates the difference of two pointers.
Example
use inkwell::context::Context; use inkwell::AddressSpace; // Builds a function which diffs two pointers let context = Context::create(); let module = context.create_module("ret"); let builder = context.create_builder(); let void_type = context.void_type(); let i32_type = context.i32_type(); let i32_ptr_type = i32_type.ptr_type(AddressSpace::Generic); let fn_type = void_type.fn_type(&[i32_ptr_type.into(), i32_ptr_type.into()], false); let fn_value = module.add_function("ret", fn_type, None); let entry = fn_value.append_basic_block("entry"); let i32_ptr_param1 = fn_value.get_first_param().unwrap().into_pointer_value(); let i32_ptr_param2 = fn_value.get_nth_param(1).unwrap().into_pointer_value(); builder.position_at_end(&entry); builder.build_ptr_diff(i32_ptr_param1, i32_ptr_param2, "diff"); builder.build_return(None);
pub fn build_phi<T: BasicType>(&self, type_: T, name: &str) -> PhiValue
[src]
pub fn build_store<V: BasicValue>(
&self,
ptr: PointerValue,
value: V
) -> InstructionValue
[src]
&self,
ptr: PointerValue,
value: V
) -> InstructionValue
Builds a store instruction. It allows you to store a value of type T
in a pointer to a type T
.
Example
use inkwell::context::Context; use inkwell::AddressSpace; // Builds a function which takes an i32 pointer and stores a 7 in it. let context = Context::create(); let module = context.create_module("ret"); let builder = context.create_builder(); let void_type = context.void_type(); let i32_type = context.i32_type(); let i32_ptr_type = i32_type.ptr_type(AddressSpace::Generic); let i32_seven = i32_type.const_int(7, false); let fn_type = void_type.fn_type(&[i32_ptr_type.into()], false); let fn_value = module.add_function("ret", fn_type, None); let entry = fn_value.append_basic_block("entry"); let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value(); builder.position_at_end(&entry); builder.build_store(i32_ptr_param, i32_seven); builder.build_return(None);
pub fn build_load(&self, ptr: PointerValue, name: &str) -> BasicValueEnum
[src]
Builds a load instruction. It allows you to retrieve a value of type T
from a pointer to a type T
.
Example
use inkwell::context::Context; use inkwell::AddressSpace; // Builds a function which takes an i32 pointer and returns the pointed at i32. let context = Context::create(); let module = context.create_module("ret"); let builder = context.create_builder(); let i32_type = context.i32_type(); let i32_ptr_type = i32_type.ptr_type(AddressSpace::Generic); let fn_type = i32_type.fn_type(&[i32_ptr_type.into()], false); let fn_value = module.add_function("ret", fn_type, None); let entry = fn_value.append_basic_block("entry"); let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value(); builder.position_at_end(&entry); let pointee = builder.build_load(i32_ptr_param, "load"); builder.build_return(Some(&pointee));
pub fn build_alloca<T: BasicType>(&self, ty: T, name: &str) -> PointerValue
[src]
pub fn build_array_alloca<T: BasicType>(
&self,
ty: T,
size: IntValue,
name: &str
) -> PointerValue
[src]
&self,
ty: T,
size: IntValue,
name: &str
) -> PointerValue
pub fn build_malloc<T: BasicType>(&self, ty: T, name: &str) -> PointerValue
[src]
pub fn build_array_malloc<T: BasicType>(
&self,
ty: T,
size: IntValue,
name: &str
) -> PointerValue
[src]
&self,
ty: T,
size: IntValue,
name: &str
) -> PointerValue
pub fn build_free(&self, ptr: PointerValue) -> InstructionValue
[src]
pub fn insert_instruction(
&self,
instruction: &InstructionValue,
name: Option<&str>
)
[src]
&self,
instruction: &InstructionValue,
name: Option<&str>
)
pub fn get_insert_block(&self) -> Option<BasicBlock>
[src]
pub fn build_int_unsigned_div<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_signed_div<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_exact_signed_div<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_unsigned_rem<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_signed_rem<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_s_extend<T: IntMathValue>(
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
[src]
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
pub fn build_address_space_cast(
&self,
ptr_val: PointerValue,
ptr_type: PointerType,
name: &str
) -> PointerValue
[src]
&self,
ptr_val: PointerValue,
ptr_type: PointerType,
name: &str
) -> PointerValue
pub fn build_bitcast<T, V>(&self, val: V, ty: T, name: &str) -> BasicValueEnum where
T: BasicType,
V: BasicValue,
[src]
T: BasicType,
V: BasicValue,
Builds a bitcast instruction. A bitcast reinterprets the bits of one value into a value of another type which has the same bit width.
Example
use inkwell::context::Context; let context = Context::create(); let module = context.create_module("bc"); let void_type = context.void_type(); let f32_type = context.f32_type(); let i32_type = context.i32_type(); let arg_types = [i32_type.into()]; let fn_type = void_type.fn_type(&arg_types, false); let fn_value = module.add_function("bc", fn_type, None); let builder = context.create_builder(); let entry = fn_value.append_basic_block("entry"); let i32_arg = fn_value.get_first_param().unwrap(); builder.position_at_end(&entry); builder.build_bitcast(i32_arg, f32_type, "i32tof32"); builder.build_return(None); assert!(module.verify().is_ok());
pub fn build_int_s_extend_or_bit_cast<T: IntMathValue>(
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
[src]
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
pub fn build_int_z_extend<T: IntMathValue>(
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
[src]
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
pub fn build_int_z_extend_or_bit_cast<T: IntMathValue>(
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
[src]
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
pub fn build_int_truncate<T: IntMathValue>(
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
[src]
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
pub fn build_int_truncate_or_bit_cast<T: IntMathValue>(
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
[src]
&self,
int_value: T,
int_type: T::BaseType,
name: &str
) -> T
pub fn build_float_rem<T: FloatMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_float_to_unsigned_int<T: FloatMathValue>(
&self,
float: T,
int_type: <T::BaseType as FloatMathType>::MathConvType,
name: &str
) -> <<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType
[src]
&self,
float: T,
int_type: <T::BaseType as FloatMathType>::MathConvType,
name: &str
) -> <<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType
pub fn build_float_to_signed_int<T: FloatMathValue>(
&self,
float: T,
int_type: <T::BaseType as FloatMathType>::MathConvType,
name: &str
) -> <<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType
[src]
&self,
float: T,
int_type: <T::BaseType as FloatMathType>::MathConvType,
name: &str
) -> <<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType
pub fn build_unsigned_int_to_float<T: IntMathValue>(
&self,
int: T,
float_type: <T::BaseType as IntMathType>::MathConvType,
name: &str
) -> <<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType
[src]
&self,
int: T,
float_type: <T::BaseType as IntMathType>::MathConvType,
name: &str
) -> <<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType
pub fn build_signed_int_to_float<T: IntMathValue>(
&self,
int: T,
float_type: <T::BaseType as IntMathType>::MathConvType,
name: &str
) -> <<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType
[src]
&self,
int: T,
float_type: <T::BaseType as IntMathType>::MathConvType,
name: &str
) -> <<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType
pub fn build_float_trunc<T: FloatMathValue>(
&self,
float: T,
float_type: T::BaseType,
name: &str
) -> T
[src]
&self,
float: T,
float_type: T::BaseType,
name: &str
) -> T
pub fn build_float_ext<T: FloatMathValue>(
&self,
float: T,
float_type: T::BaseType,
name: &str
) -> T
[src]
&self,
float: T,
float_type: T::BaseType,
name: &str
) -> T
pub fn build_float_cast<T: FloatMathValue>(
&self,
float: T,
float_type: T::BaseType,
name: &str
) -> T
[src]
&self,
float: T,
float_type: T::BaseType,
name: &str
) -> T
pub fn build_int_cast<T: IntMathValue>(
&self,
int: T,
int_type: T::BaseType,
name: &str
) -> T
[src]
&self,
int: T,
int_type: T::BaseType,
name: &str
) -> T
pub fn build_float_div<T: FloatMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_add<T: IntMathValue>(&self, lhs: T, rhs: T, name: &str) -> T
[src]
pub fn build_int_nsw_add<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_nuw_add<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_float_add<T: FloatMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_xor<T: IntMathValue>(&self, lhs: T, rhs: T, name: &str) -> T
[src]
pub fn build_and<T: IntMathValue>(&self, lhs: T, rhs: T, name: &str) -> T
[src]
pub fn build_or<T: IntMathValue>(&self, lhs: T, rhs: T, name: &str) -> T
[src]
pub fn build_left_shift<T: IntMathValue>(&self, lhs: T, rhs: T, name: &str) -> T
[src]
Builds an IntValue
containing the result of a logical left shift instruction.
Example
A logical left shift is an operation in which an integer value's bits are shifted left by N number of positions.
assert_eq!(0b0000_0001 << 0, 0b0000_0001); assert_eq!(0b0000_0001 << 1, 0b0000_0010); assert_eq!(0b0000_0011 << 2, 0b0000_1100);
In Rust, a function that could do this for 8bit values looks like:
fn left_shift(value: u8, n: u8) -> u8 { value << n }
And in Inkwell, the corresponding function would look roughly like:
use inkwell::context::Context; // Setup let context = Context::create(); let module = context.create_module("my_module"); let builder = context.create_builder(); let i8_type = context.i8_type(); let fn_type = i8_type.fn_type(&[i8_type.into(), i8_type.into()], false); // Function Definition let function = module.add_function("left_shift", fn_type, None); let value = function.get_first_param().unwrap().into_int_value(); let n = function.get_nth_param(1).unwrap().into_int_value(); let entry_block = function.append_basic_block("entry"); builder.position_at_end(&entry_block); let shift = builder.build_left_shift(value, n, "left_shift"); // value << n builder.build_return(Some(&shift));
pub fn build_right_shift<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
sign_extend: bool,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
sign_extend: bool,
name: &str
) -> T
Builds an IntValue
containing the result of a right shift instruction.
Example
A right shift is an operation in which an integer value's bits are shifted right by N number of positions. It may either be logical and have its leftmost N bit(s) filled with zeros or sign extended and filled with ones if the leftmost bit was one.
//fix doc error about overflowing_literals //rendered rfc: https://github.com/rust-lang/rfcs/blob/master/text/2438-deny-integer-literal-overflow-lint.md //tracking issue: https://github.com/rust-lang/rust/issues/54502 #![allow(overflowing_literals)] // Logical Right Shift assert_eq!(0b1100_0000u8 >> 2, 0b0011_0000); assert_eq!(0b0000_0010u8 >> 1, 0b0000_0001); assert_eq!(0b0000_1100u8 >> 2, 0b0000_0011); // Sign Extended Right Shift assert_eq!(0b0100_0000i8 >> 2, 0b0001_0000); assert_eq!(0b1110_0000u8 as i8 >> 1, 0b1111_0000u8 as i8); assert_eq!(0b1100_0000u8 as i8 >> 2, 0b1111_0000u8 as i8);
In Rust, functions that could do this for 8bit values look like:
fn logical_right_shift(value: u8, n: u8) -> u8 { value >> n } fn sign_extended_right_shift(value: i8, n: u8) -> i8 { value >> n }
Notice that, in Rust (and most other languages), whether or not a value is sign extended depends wholly on whether or not the type is signed (ie an i8 is a signed 8 bit value). LLVM does not make this distinction for you.
In Inkwell, the corresponding functions would look roughly like:
use inkwell::context::Context; // Setup let context = Context::create(); let module = context.create_module("my_module"); let builder = context.create_builder(); let i8_type = context.i8_type(); let fn_type = i8_type.fn_type(&[i8_type.into(), i8_type.into()], false); // Function Definition let function = module.add_function("right_shift", fn_type, None); let value = function.get_first_param().unwrap().into_int_value(); let n = function.get_nth_param(1).unwrap().into_int_value(); let entry_block = function.append_basic_block("entry"); builder.position_at_end(&entry_block); // Whether or not your right shift is sign extended (true) or logical (false) depends // on the boolean input parameter: let shift = builder.build_right_shift(value, n, false, "right_shift"); // value >> n builder.build_return(Some(&shift));
pub fn build_int_sub<T: IntMathValue>(&self, lhs: T, rhs: T, name: &str) -> T
[src]
pub fn build_int_nsw_sub<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_nuw_sub<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_float_sub<T: FloatMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_mul<T: IntMathValue>(&self, lhs: T, rhs: T, name: &str) -> T
[src]
pub fn build_int_nsw_mul<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_int_nuw_mul<T: IntMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_float_mul<T: FloatMathValue>(
&self,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_cast<T: BasicType, V: BasicValue>(
&self,
op: InstructionOpcode,
from_value: V,
to_type: T,
name: &str
) -> BasicValueEnum
[src]
&self,
op: InstructionOpcode,
from_value: V,
to_type: T,
name: &str
) -> BasicValueEnum
pub fn build_pointer_cast<T: PointerMathValue>(
&self,
from: T,
to: T::BaseType,
name: &str
) -> T
[src]
&self,
from: T,
to: T::BaseType,
name: &str
) -> T
pub fn build_int_compare<T: IntMathValue>(
&self,
op: IntPredicate,
lhs: T,
rhs: T,
name: &str
) -> T
[src]
&self,
op: IntPredicate,
lhs: T,
rhs: T,
name: &str
) -> T
pub fn build_float_compare<T: FloatMathValue>(
&self,
op: FloatPredicate,
lhs: T,
rhs: T,
name: &str
) -> <<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType
[src]
&self,
op: FloatPredicate,
lhs: T,
rhs: T,
name: &str
) -> <<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType
pub fn build_unconditional_branch(
&self,
destination_block: &BasicBlock
) -> InstructionValue
[src]
&self,
destination_block: &BasicBlock
) -> InstructionValue
pub fn build_conditional_branch(
&self,
comparison: IntValue,
then_block: &BasicBlock,
else_block: &BasicBlock
) -> InstructionValue
[src]
&self,
comparison: IntValue,
then_block: &BasicBlock,
else_block: &BasicBlock
) -> InstructionValue
pub fn build_indirect_branch<BV: BasicValue>(
&self,
address: BV,
destinations: &[&BasicBlock]
) -> InstructionValue
[src]
&self,
address: BV,
destinations: &[&BasicBlock]
) -> InstructionValue
pub fn build_int_neg<T: IntMathValue>(&self, value: T, name: &str) -> T
[src]
pub fn build_int_nsw_neg<T: IntMathValue>(&self, value: T, name: &str) -> T
[src]
pub fn build_int_nuw_neg<T: IntMathValue>(&self, value: T, name: &str) -> T
[src]
pub fn build_float_neg<T: FloatMathValue>(&self, value: T, name: &str) -> T
[src]
pub fn build_not<T: IntMathValue>(&self, value: T, name: &str) -> T
[src]
pub fn position_at(
&self,
basic_block: &BasicBlock,
instruction: &InstructionValue
)
[src]
&self,
basic_block: &BasicBlock,
instruction: &InstructionValue
)
pub fn position_before(&self, instruction: &InstructionValue)
[src]
pub fn position_at_end(&self, basic_block: &BasicBlock)
[src]
pub fn build_extract_value<AV: AggregateValue>(
&self,
agg: AV,
index: u32,
name: &str
) -> Option<BasicValueEnum>
[src]
&self,
agg: AV,
index: u32,
name: &str
) -> Option<BasicValueEnum>
Builds an extract value instruction which extracts a BasicValueEnum
from a struct or array.
Example
use inkwell::context::Context; let context = Context::create(); let module = context.create_module("av"); let void_type = context.void_type(); let f32_type = context.f32_type(); let i32_type = context.i32_type(); let struct_type = context.struct_type(&[i32_type.into(), f32_type.into()], false); let array_type = i32_type.array_type(3); let fn_type = void_type.fn_type(&[], false); let fn_value = module.add_function("av_fn", fn_type, None); let builder = context.create_builder(); let entry = fn_value.append_basic_block("entry"); builder.position_at_end(&entry); let array_alloca = builder.build_alloca(array_type, "array_alloca"); let array = builder.build_load(array_alloca, "array_load").into_array_value(); let const_int1 = i32_type.const_int(2, false); let const_int2 = i32_type.const_int(5, false); let const_int3 = i32_type.const_int(6, false); assert!(builder.build_insert_value(array, const_int1, 0, "insert").is_some()); assert!(builder.build_insert_value(array, const_int2, 1, "insert").is_some()); assert!(builder.build_insert_value(array, const_int3, 2, "insert").is_some()); assert!(builder.build_insert_value(array, const_int3, 3, "insert").is_none()); assert!(builder.build_extract_value(array, 0, "extract").unwrap().is_int_value()); assert!(builder.build_extract_value(array, 1, "extract").unwrap().is_int_value()); assert!(builder.build_extract_value(array, 2, "extract").unwrap().is_int_value()); assert!(builder.build_extract_value(array, 3, "extract").is_none());
pub fn build_insert_value<AV, BV>(
&self,
agg: AV,
value: BV,
index: u32,
name: &str
) -> Option<AggregateValueEnum> where
AV: AggregateValue,
BV: BasicValue,
[src]
&self,
agg: AV,
value: BV,
index: u32,
name: &str
) -> Option<AggregateValueEnum> where
AV: AggregateValue,
BV: BasicValue,
Builds an insert value instruction which inserts a BasicValue
into a struct
or array and returns the resulting aggregate value.
Example
use inkwell::context::Context; let context = Context::create(); let module = context.create_module("av"); let void_type = context.void_type(); let f32_type = context.f32_type(); let i32_type = context.i32_type(); let struct_type = context.struct_type(&[i32_type.into(), f32_type.into()], false); let array_type = i32_type.array_type(3); let fn_type = void_type.fn_type(&[], false); let fn_value = module.add_function("av_fn", fn_type, None); let builder = context.create_builder(); let entry = fn_value.append_basic_block("entry"); builder.position_at_end(&entry); let array_alloca = builder.build_alloca(array_type, "array_alloca"); let array = builder.build_load(array_alloca, "array_load").into_array_value(); let const_int1 = i32_type.const_int(2, false); let const_int2 = i32_type.const_int(5, false); let const_int3 = i32_type.const_int(6, false); assert!(builder.build_insert_value(array, const_int1, 0, "insert").is_some()); assert!(builder.build_insert_value(array, const_int2, 1, "insert").is_some()); assert!(builder.build_insert_value(array, const_int3, 2, "insert").is_some()); assert!(builder.build_insert_value(array, const_int3, 3, "insert").is_none());
pub fn build_extract_element(
&self,
vector: VectorValue,
index: IntValue,
name: &str
) -> BasicValueEnum
[src]
&self,
vector: VectorValue,
index: IntValue,
name: &str
) -> BasicValueEnum
Builds an extract element instruction which extracts a BasicValueEnum
from a vector.
Example
use inkwell::context::Context; let context = Context::create(); let module = context.create_module("av"); let i32_type = context.i32_type(); let i32_zero = i32_type.const_int(0, false); let vec_type = i32_type.vec_type(2); let fn_type = i32_type.fn_type(&[vec_type.into()], false); let fn_value = module.add_function("vec_fn", fn_type, None); let builder = context.create_builder(); let entry = fn_value.append_basic_block("entry"); let vector_param = fn_value.get_first_param().unwrap().into_vector_value(); builder.position_at_end(&entry); let extracted = builder.build_extract_element(vector_param, i32_zero, "insert"); builder.build_return(Some(&extracted));
pub fn build_insert_element<V: BasicValue>(
&self,
vector: VectorValue,
element: V,
index: IntValue,
name: &str
) -> VectorValue
[src]
&self,
vector: VectorValue,
element: V,
index: IntValue,
name: &str
) -> VectorValue
Builds an insert element instruction which inserts a BasicValue
into a vector
and returns the resulting vector.
Example
use inkwell::context::Context; let context = Context::create(); let module = context.create_module("av"); let void_type = context.void_type(); let i32_type = context.i32_type(); let i32_zero = i32_type.const_int(0, false); let i32_seven = i32_type.const_int(7, false); let vec_type = i32_type.vec_type(2); let fn_type = void_type.fn_type(&[vec_type.into()], false); let fn_value = module.add_function("vec_fn", fn_type, None); let builder = context.create_builder(); let entry = fn_value.append_basic_block("entry"); let vector_param = fn_value.get_first_param().unwrap().into_vector_value(); builder.position_at_end(&entry); builder.build_insert_element(vector_param, i32_seven, i32_zero, "insert"); builder.build_return(None);
pub fn build_unreachable(&self) -> InstructionValue
[src]
pub fn build_fence(
&self,
atomic_ordering: AtomicOrdering,
num: i32,
name: &str
) -> InstructionValue
[src]
&self,
atomic_ordering: AtomicOrdering,
num: i32,
name: &str
) -> InstructionValue
pub fn build_is_null<T: PointerMathValue>(
&self,
ptr: T,
name: &str
) -> <<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType
[src]
&self,
ptr: T,
name: &str
) -> <<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType
pub fn build_is_not_null<T: PointerMathValue>(
&self,
ptr: T,
name: &str
) -> <<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType
[src]
&self,
ptr: T,
name: &str
) -> <<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType
pub fn build_int_to_ptr<T: IntMathValue>(
&self,
int: T,
ptr_type: <T::BaseType as IntMathType>::PtrConvType,
name: &str
) -> <<T::BaseType as IntMathType>::PtrConvType as PointerMathType>::ValueType
[src]
&self,
int: T,
ptr_type: <T::BaseType as IntMathType>::PtrConvType,
name: &str
) -> <<T::BaseType as IntMathType>::PtrConvType as PointerMathType>::ValueType
pub fn build_ptr_to_int<T: PointerMathValue>(
&self,
ptr: T,
int_type: <T::BaseType as PointerMathType>::PtrConvType,
name: &str
) -> <<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType
[src]
&self,
ptr: T,
int_type: <T::BaseType as PointerMathType>::PtrConvType,
name: &str
) -> <<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType
pub fn clear_insertion_position(&self)
[src]
pub fn build_switch(
&self,
value: IntValue,
else_block: &BasicBlock,
cases: &[(IntValue, &BasicBlock)]
) -> InstructionValue
[src]
&self,
value: IntValue,
else_block: &BasicBlock,
cases: &[(IntValue, &BasicBlock)]
) -> InstructionValue
pub fn build_select<BV: BasicValue, IMV: IntMathValue>(
&self,
condition: IMV,
then: BV,
else_: BV,
name: &str
) -> BasicValueEnum
[src]
&self,
condition: IMV,
then: BV,
else_: BV,
name: &str
) -> BasicValueEnum
pub unsafe fn build_global_string(&self, value: &str, name: &str) -> GlobalValue
[src]
pub fn build_global_string_ptr(&self, value: &str, name: &str) -> GlobalValue
[src]
pub fn build_shuffle_vector(
&self,
left: VectorValue,
right: VectorValue,
mask: VectorValue,
name: &str
) -> VectorValue
[src]
&self,
left: VectorValue,
right: VectorValue,
mask: VectorValue,
name: &str
) -> VectorValue
pub fn build_va_arg<BT: BasicType>(
&self,
list: PointerValue,
type_: BT,
name: &str
) -> BasicValueEnum
[src]
&self,
list: PointerValue,
type_: BT,
name: &str
) -> BasicValueEnum
pub fn build_atomicrmw(
&self,
op: AtomicRMWBinOp,
ptr: PointerValue,
value: IntValue,
ordering: AtomicOrdering
) -> Result<IntValue, &'static str>
[src]
&self,
op: AtomicRMWBinOp,
ptr: PointerValue,
value: IntValue,
ordering: AtomicOrdering
) -> Result<IntValue, &'static str>
Builds an atomicrmw instruction. It allows you to atomically modify memory.
Example
use inkwell::context::Context; use inkwell::{AddressSpace, AtomicOrdering, AtomicRMWBinOp}; let context = Context::create(); let module = context.create_module("rmw"); let void_type = context.void_type(); let i32_type = context.i32_type(); let i32_seven = i32_type.const_int(7, false); let i32_ptr_type = i32_type.ptr_type(AddressSpace::Generic); let fn_type = void_type.fn_type(&[i32_ptr_type.into()], false); let fn_value = module.add_function("rmw", fn_type, None); let entry = fn_value.append_basic_block("entry"); let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value(); let builder = context.create_builder(); builder.position_at_end(&entry); builder.build_atomicrmw(AtomicRMWBinOp::Add, i32_ptr_param, i32_seven, AtomicOrdering::Unordered); builder.build_return(None);
pub fn build_cmpxchg<V: BasicValue>(
&self,
ptr: PointerValue,
cmp: V,
new: V,
success: AtomicOrdering,
failure: AtomicOrdering
) -> Result<StructValue, &'static str>
[src]
&self,
ptr: PointerValue,
cmp: V,
new: V,
success: AtomicOrdering,
failure: AtomicOrdering
) -> Result<StructValue, &'static str>
Builds a cmpxchg instruction. It allows you to atomically compare and replace memory.
Example
use inkwell::context::Context; use inkwell::{AddressSpace, AtomicOrdering}; let context = Context::create(); let module = context.create_module("cmpxchg"); let void_type = context.void_type(); let i32_type = context.i32_type(); let i32_ptr_type = i32_type.ptr_type(AddressSpace::Generic); let fn_type = void_type.fn_type(&[i32_ptr_type.into()], false); let fn_value = module.add_function("", fn_type, None); let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value(); let i32_seven = i32_type.const_int(7, false); let i32_eight = i32_type.const_int(8, false); let entry = fn_value.append_basic_block("entry"); let builder = context.create_builder(); builder.position_at_end(&entry); builder.build_cmpxchg(i32_ptr_param, i32_seven, i32_eight, AtomicOrdering::AcquireRelease, AtomicOrdering::Monotonic); builder.build_return(None);
Trait Implementations
Auto Trait Implementations
impl !Sync for Builder
impl !Send for Builder
impl Unpin for Builder
impl UnwindSafe for Builder
impl RefUnwindSafe for Builder
Blanket Implementations
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From<T> for T
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,