[][src]Struct inkwell::builder::Builder

pub struct Builder<'ctx> { /* fields omitted */ }

Implementations

impl<'ctx> Builder<'ctx>[src]

pub fn build_return(
    &self,
    value: Option<&dyn BasicValue<'ctx>>
) -> InstructionValue<'ctx>
[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 = context.append_basic_block(fn_value, "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<'ctx>]
) -> InstructionValue<'ctx>
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>],
    name: &str
) -> CallSiteValue<'ctx> where
    F: Into<Either<FunctionValue<'ctx>, PointerValue<'ctx>>>, 
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>,
    ordered_indexes: &[IntValue<'ctx>],
    name: &str
) -> PointerValue<'ctx>
[src]

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<'ctx>,
    ordered_indexes: &[IntValue<'ctx>],
    name: &str
) -> PointerValue<'ctx>
[src]

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_struct_gep(
    &self,
    ptr: PointerValue<'ctx>,
    index: u32,
    name: &str
) -> Result<PointerValue<'ctx>, ()>
[src]

Builds a GEP instruction on a struct pointer. Returns Err(()) if input PointerValue doesn't point to a struct or if index is out of bounds.

Example

use inkwell::AddressSpace;
use inkwell::context::Context;

let context = Context::create();
let builder = context.create_builder();
let module = context.create_module("struct_gep");
let void_type = context.void_type();
let i32_ty = context.i32_type();
let i32_ptr_ty = i32_ty.ptr_type(AddressSpace::Generic);
let field_types = &[i32_ty.into(), i32_ty.into()];
let struct_ty = context.struct_type(field_types, false);
let struct_ptr_ty = struct_ty.ptr_type(AddressSpace::Generic);
let fn_type = void_type.fn_type(&[i32_ptr_ty.into(), struct_ptr_ty.into()], false);
let fn_value = module.add_function("", fn_type, None);
let entry = context.append_basic_block(fn_value, "entry");

builder.position_at_end(entry);

let i32_ptr = fn_value.get_first_param().unwrap().into_pointer_value();
let struct_ptr = fn_value.get_last_param().unwrap().into_pointer_value();

assert!(builder.build_struct_gep(i32_ptr, 0, "struct_gep").is_err());
assert!(builder.build_struct_gep(i32_ptr, 10, "struct_gep").is_err());
assert!(builder.build_struct_gep(struct_ptr, 0, "struct_gep").is_ok());
assert!(builder.build_struct_gep(struct_ptr, 1, "struct_gep").is_ok());
assert!(builder.build_struct_gep(struct_ptr, 2, "struct_gep").is_err());

pub fn build_ptr_diff(
    &self,
    lhs_ptr: PointerValue<'ctx>,
    rhs_ptr: PointerValue<'ctx>,
    name: &str
) -> IntValue<'ctx>
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>>(
    &self,
    type_: T,
    name: &str
) -> PhiValue<'ctx>
[src]

pub fn build_store<V: BasicValue<'ctx>>(
    &self,
    ptr: PointerValue<'ctx>,
    value: V
) -> InstructionValue<'ctx>
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>,
    name: &str
) -> BasicValueEnum<'ctx>
[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 = context.append_basic_block(fn_value, "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<'ctx>>(
    &self,
    ty: T,
    name: &str
) -> PointerValue<'ctx>
[src]

pub fn build_array_alloca<T: BasicType<'ctx>>(
    &self,
    ty: T,
    size: IntValue<'ctx>,
    name: &str
) -> PointerValue<'ctx>
[src]

pub fn build_memcpy(
    &self,
    dest: PointerValue<'ctx>,
    dest_align_bytes: u32,
    src: PointerValue<'ctx>,
    src_align_bytes: u32,
    size: IntValue<'ctx>
) -> Result<PointerValue<'ctx>, &'static str>
[src]

Build a memcpy instruction.

Alignment arguments are specified in bytes, and should always be both a power of 2 and under 2^64.

The final argument should be a pointer-sized integer.

TargetData::ptr_sized_int_type_in_context will get you one of those.

pub fn build_memmove(
    &self,
    dest: PointerValue<'ctx>,
    dest_align_bytes: u32,
    src: PointerValue<'ctx>,
    src_align_bytes: u32,
    size: IntValue<'ctx>
) -> Result<PointerValue<'ctx>, &'static str>
[src]

Build a memmove instruction.

Alignment arguments are specified in bytes, and should always be both a power of 2 and under 2^64.

The final argument should be a pointer-sized integer.

TargetData::ptr_sized_int_type_in_context will get you one of those.

pub fn build_malloc<T: BasicType<'ctx>>(
    &self,
    ty: T,
    name: &str
) -> Result<PointerValue<'ctx>, &'static str>
[src]

pub fn build_array_malloc<T: BasicType<'ctx>>(
    &self,
    ty: T,
    size: IntValue<'ctx>,
    name: &str
) -> Result<PointerValue<'ctx>, &'static str>
[src]

pub fn build_free(&self, ptr: PointerValue<'ctx>) -> InstructionValue<'ctx>[src]

pub fn insert_instruction(
    &self,
    instruction: &InstructionValue<'ctx>,
    name: Option<&str>
)
[src]

pub fn get_insert_block(&self) -> Option<BasicBlock<'ctx>>[src]

pub fn build_int_unsigned_div<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_signed_div<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_exact_signed_div<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_unsigned_rem<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_signed_rem<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_s_extend<T: IntMathValue<'ctx>>(
    &self,
    int_value: T,
    int_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_address_space_cast(
    &self,
    ptr_val: PointerValue<'ctx>,
    ptr_type: PointerType<'ctx>,
    name: &str
) -> PointerValue<'ctx>
[src]

pub fn build_bitcast<T, V>(
    &self,
    val: V,
    ty: T,
    name: &str
) -> BasicValueEnum<'ctx> where
    T: BasicType<'ctx>,
    V: BasicValue<'ctx>, 
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>>(
    &self,
    int_value: T,
    int_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_int_z_extend<T: IntMathValue<'ctx>>(
    &self,
    int_value: T,
    int_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_int_z_extend_or_bit_cast<T: IntMathValue<'ctx>>(
    &self,
    int_value: T,
    int_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_int_truncate<T: IntMathValue<'ctx>>(
    &self,
    int_value: T,
    int_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_int_truncate_or_bit_cast<T: IntMathValue<'ctx>>(
    &self,
    int_value: T,
    int_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_float_rem<T: FloatMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_float_to_unsigned_int<T: FloatMathValue<'ctx>>(
    &self,
    float: T,
    int_type: <T::BaseType as FloatMathType<'ctx>>::MathConvType,
    name: &str
) -> <<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType
[src]

pub fn build_float_to_signed_int<T: FloatMathValue<'ctx>>(
    &self,
    float: T,
    int_type: <T::BaseType as FloatMathType<'ctx>>::MathConvType,
    name: &str
) -> <<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType
[src]

pub fn build_unsigned_int_to_float<T: IntMathValue<'ctx>>(
    &self,
    int: T,
    float_type: <T::BaseType as IntMathType<'ctx>>::MathConvType,
    name: &str
) -> <<T::BaseType as IntMathType<'ctx>>::MathConvType as FloatMathType<'ctx>>::ValueType
[src]

pub fn build_signed_int_to_float<T: IntMathValue<'ctx>>(
    &self,
    int: T,
    float_type: <T::BaseType as IntMathType<'ctx>>::MathConvType,
    name: &str
) -> <<T::BaseType as IntMathType<'ctx>>::MathConvType as FloatMathType<'ctx>>::ValueType
[src]

pub fn build_float_trunc<T: FloatMathValue<'ctx>>(
    &self,
    float: T,
    float_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_float_ext<T: FloatMathValue<'ctx>>(
    &self,
    float: T,
    float_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_float_cast<T: FloatMathValue<'ctx>>(
    &self,
    float: T,
    float_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_int_cast<T: IntMathValue<'ctx>>(
    &self,
    int: T,
    int_type: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_float_div<T: FloatMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_add<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_nsw_add<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_nuw_add<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_float_add<T: FloatMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_xor<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> T[src]

pub fn build_and<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> T[src]

pub fn build_or<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> T[src]

pub fn build_left_shift<T: IntMathValue<'ctx>>(
    &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 = context.append_basic_block(function, "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<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    sign_extend: bool,
    name: &str
) -> T
[src]

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 = context.append_basic_block(function, "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<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_nsw_sub<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_nuw_sub<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_float_sub<T: FloatMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_mul<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_nsw_mul<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_int_nuw_mul<T: IntMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_float_mul<T: FloatMathValue<'ctx>>(
    &self,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_cast<T: BasicType<'ctx>, V: BasicValue<'ctx>>(
    &self,
    op: InstructionOpcode,
    from_value: V,
    to_type: T,
    name: &str
) -> BasicValueEnum<'ctx>
[src]

pub fn build_pointer_cast<T: PointerMathValue<'ctx>>(
    &self,
    from: T,
    to: T::BaseType,
    name: &str
) -> T
[src]

pub fn build_int_compare<T: IntMathValue<'ctx>>(
    &self,
    op: IntPredicate,
    lhs: T,
    rhs: T,
    name: &str
) -> T
[src]

pub fn build_float_compare<T: FloatMathValue<'ctx>>(
    &self,
    op: FloatPredicate,
    lhs: T,
    rhs: T,
    name: &str
) -> <<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType
[src]

pub fn build_unconditional_branch(
    &self,
    destination_block: BasicBlock<'ctx>
) -> InstructionValue<'ctx>
[src]

pub fn build_conditional_branch(
    &self,
    comparison: IntValue<'ctx>,
    then_block: BasicBlock<'ctx>,
    else_block: BasicBlock<'ctx>
) -> InstructionValue<'ctx>
[src]

pub fn build_indirect_branch<BV: BasicValue<'ctx>>(
    &self,
    address: BV,
    destinations: &[BasicBlock<'ctx>]
) -> InstructionValue<'ctx>
[src]

pub fn build_int_neg<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> T[src]

pub fn build_int_nsw_neg<T: IntMathValue<'ctx>>(
    &self,
    value: T,
    name: &str
) -> T
[src]

pub fn build_int_nuw_neg<T: IntMathValue<'ctx>>(
    &self,
    value: T,
    name: &str
) -> T
[src]

pub fn build_float_neg<T: FloatMathValue<'ctx>>(
    &self,
    value: T,
    name: &str
) -> T
[src]

pub fn build_not<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> T[src]

pub fn position_at(
    &self,
    basic_block: BasicBlock<'ctx>,
    instruction: &InstructionValue<'ctx>
)
[src]

pub fn position_before(&self, instruction: &InstructionValue<'ctx>)[src]

pub fn position_at_end(&self, basic_block: BasicBlock<'ctx>)[src]

pub fn build_extract_value<AV: AggregateValue<'ctx>>(
    &self,
    agg: AV,
    index: u32,
    name: &str
) -> Option<BasicValueEnum<'ctx>>
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>> where
    AV: AggregateValue<'ctx>,
    BV: BasicValue<'ctx>, 
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>,
    index: IntValue<'ctx>,
    name: &str
) -> BasicValueEnum<'ctx>
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>>(
    &self,
    vector: VectorValue<'ctx>,
    element: V,
    index: IntValue<'ctx>,
    name: &str
) -> VectorValue<'ctx>
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>[src]

pub fn build_fence(
    &self,
    atomic_ordering: AtomicOrdering,
    num: i32,
    name: &str
) -> InstructionValue<'ctx>
[src]

pub fn build_is_null<T: PointerMathValue<'ctx>>(
    &self,
    ptr: T,
    name: &str
) -> <<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType
[src]

pub fn build_is_not_null<T: PointerMathValue<'ctx>>(
    &self,
    ptr: T,
    name: &str
) -> <<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType
[src]

pub fn build_int_to_ptr<T: IntMathValue<'ctx>>(
    &self,
    int: T,
    ptr_type: <T::BaseType as IntMathType<'ctx>>::PtrConvType,
    name: &str
) -> <<T::BaseType as IntMathType<'ctx>>::PtrConvType as PointerMathType<'ctx>>::ValueType
[src]

pub fn build_ptr_to_int<T: PointerMathValue<'ctx>>(
    &self,
    ptr: T,
    int_type: <T::BaseType as PointerMathType<'ctx>>::PtrConvType,
    name: &str
) -> <<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType
[src]

pub fn clear_insertion_position(&self)[src]

pub fn build_switch(
    &self,
    value: IntValue<'ctx>,
    else_block: BasicBlock<'ctx>,
    cases: &[(IntValue<'ctx>, BasicBlock<'ctx>)]
) -> InstructionValue<'ctx>
[src]

pub fn build_select<BV: BasicValue<'ctx>, IMV: IntMathValue<'ctx>>(
    &self,
    condition: IMV,
    then: BV,
    else_: BV,
    name: &str
) -> BasicValueEnum<'ctx>
[src]

pub unsafe fn build_global_string(
    &self,
    value: &str,
    name: &str
) -> GlobalValue<'ctx>
[src]

pub fn build_global_string_ptr(
    &self,
    value: &str,
    name: &str
) -> GlobalValue<'ctx>
[src]

pub fn build_shuffle_vector(
    &self,
    left: VectorValue<'ctx>,
    right: VectorValue<'ctx>,
    mask: VectorValue<'ctx>,
    name: &str
) -> VectorValue<'ctx>
[src]

pub fn build_va_arg<BT: BasicType<'ctx>>(
    &self,
    list: PointerValue<'ctx>,
    type_: BT,
    name: &str
) -> BasicValueEnum<'ctx>
[src]

pub fn build_atomicrmw(
    &self,
    op: AtomicRMWBinOp,
    ptr: PointerValue<'ctx>,
    value: IntValue<'ctx>,
    ordering: AtomicOrdering
) -> Result<IntValue<'ctx>, &'static str>
[src]

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 = context.append_basic_block(fn_value, "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<'ctx>>(
    &self,
    ptr: PointerValue<'ctx>,
    cmp: V,
    new: V,
    success: AtomicOrdering,
    failure: AtomicOrdering
) -> Result<StructValue<'ctx>, &'static str>
[src]

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 = context.append_basic_block(fn_value, "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);

pub fn set_current_debug_location(
    &self,
    context: &'ctx Context,
    location: DILocation<'ctx>
)
[src]

Set the debug info source location of the instruction currently pointed at by the builder

pub fn get_current_debug_location(&self) -> Option<DILocation<'ctx>>[src]

Get the debug info source location of the instruction currently pointed at by the builder, if available.

pub fn unset_current_debug_location(&self)[src]

Unset the debug info source location of the instruction currently pointed at by the builder. If there isn't any debug info, this is a no-op.

Trait Implementations

impl<'ctx> Debug for Builder<'ctx>[src]

impl<'_> Drop for Builder<'_>[src]

Auto Trait Implementations

impl<'ctx> RefUnwindSafe for Builder<'ctx>

impl<'ctx> !Send for Builder<'ctx>

impl<'ctx> !Sync for Builder<'ctx>

impl<'ctx> Unpin for Builder<'ctx>

impl<'ctx> UnwindSafe for Builder<'ctx>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.