Struct inkwell::context::Context

source ·
pub struct Context { /* private fields */ }
Expand description

A Context is a container for all LLVM entities including Modules.

A Context is not thread safe and cannot be shared across threads. Multiple Contexts can, however, execute on different threads simultaneously according to the LLVM docs.

Implementations§

source§

impl Context

source

pub fn create() -> Self

Creates a new Context.

§Example
use inkwell::context::Context;

let context = Context::create();
source

pub unsafe fn get_global<F, R>(func: F) -> R
where F: FnOnce(&Context) -> R,

Gets a Mutex<Context> which points to the global context singleton. This function is marked unsafe because another program within the same process could easily gain access to the same LLVM context pointer and bypass our Mutex. Therefore, using Context::create() is the preferred context creation function when you do not specifically need the global context.

§Example
use inkwell::context::Context;

let context = unsafe {
    Context::get_global(|_global_context| {
        // do stuff
    })
};
source

pub fn create_builder(&self) -> Builder<'_>

Creates a new Builder for a Context.

§Example
use inkwell::context::Context;

let context = Context::create();
let builder = context.create_builder();
source

pub fn create_module(&self, name: &str) -> Module<'_>

Creates a new Module for a Context.

§Example
use inkwell::context::Context;

let context = Context::create();
let module = context.create_module("my_module");
source

pub fn create_module_from_ir( &self, memory_buffer: MemoryBuffer ) -> Result<Module<'_>, LLVMString>

Creates a new Module for the current Context from a MemoryBuffer.

§Example
use inkwell::context::Context;

let context = Context::create();
let module = context.create_module("my_module");
let builder = context.create_builder();
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let fn_val = module.add_function("my_fn", fn_type, None);
let basic_block = context.append_basic_block(fn_val, "entry");

builder.position_at_end(basic_block);
builder.build_return(None).unwrap();

let memory_buffer = module.write_bitcode_to_memory();

let module2 = context.create_module_from_ir(memory_buffer).unwrap();
source

pub fn create_inline_asm<'ctx>( &'ctx self, ty: FunctionType<'ctx>, assembly: String, constraints: String, sideeffects: bool, alignstack: bool, dialect: Option<InlineAsmDialect>, can_throw: bool ) -> PointerValue<'ctx>

Creates a inline asm function pointer.

§Example
use std::convert::TryFrom;
use inkwell::context::Context;

let context = Context::create();
let module = context.create_module("my_module");
let builder = context.create_builder();
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let fn_val = module.add_function("my_fn", fn_type, None);
let basic_block = context.append_basic_block(fn_val, "entry");

builder.position_at_end(basic_block);
let asm_fn = context.i64_type().fn_type(&[context.i64_type().into(), context.i64_type().into()], false);
let asm = context.create_inline_asm(
    asm_fn,
    "syscall".to_string(),
    "=r,{rax},{rdi}".to_string(),
    true,
    false,
    #[cfg(not(any(feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0")))] None,
    #[cfg(not(any(
        feature = "llvm4-0",
        feature = "llvm5-0",
        feature = "llvm6-0",
        feature = "llvm7-0",
        feature = "llvm8-0",
        feature = "llvm9-0",
        feature = "llvm10-0",
        feature = "llvm11-0",
        feature = "llvm12-0"
    )))]
    false,
);
let params = &[context.i64_type().const_int(60, false).into(), context.i64_type().const_int(1, false).into()];

#[cfg(any(
    feature = "llvm4-0",
    feature = "llvm5-0",
    feature = "llvm6-0",
    feature = "llvm7-0",
    feature = "llvm8-0",
    feature = "llvm9-0",
    feature = "llvm10-0",
    feature = "llvm11-0",
    feature = "llvm12-0",
    feature = "llvm13-0",
    feature = "llvm14-0"
))]
{
    use inkwell::values::CallableValue;
    let callable_value = CallableValue::try_from(asm).unwrap();
    builder.build_call(callable_value, params, "exit").unwrap();
}

#[cfg(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0"))]
builder.build_indirect_call(asm_fn, asm, params, "exit").unwrap();

builder.build_return(None).unwrap();
source

pub fn void_type(&self) -> VoidType<'_>

Gets the VoidType. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();
let void_type = context.void_type();

assert_eq!(void_type.get_context(), context);
source

pub fn bool_type(&self) -> IntType<'_>

Gets the IntType representing 1 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();
let bool_type = context.bool_type();

assert_eq!(bool_type.get_bit_width(), 1);
assert_eq!(bool_type.get_context(), context);
source

pub fn i8_type(&self) -> IntType<'_>

Gets the IntType representing 8 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();
let i8_type = context.i8_type();

assert_eq!(i8_type.get_bit_width(), 8);
assert_eq!(i8_type.get_context(), context);
source

pub fn i16_type(&self) -> IntType<'_>

Gets the IntType representing 16 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();
let i16_type = context.i16_type();

assert_eq!(i16_type.get_bit_width(), 16);
assert_eq!(i16_type.get_context(), context);
source

pub fn i32_type(&self) -> IntType<'_>

Gets the IntType representing 32 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();
let i32_type = context.i32_type();

assert_eq!(i32_type.get_bit_width(), 32);
assert_eq!(i32_type.get_context(), context);
source

pub fn i64_type(&self) -> IntType<'_>

Gets the IntType representing 64 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();
let i64_type = context.i64_type();

assert_eq!(i64_type.get_bit_width(), 64);
assert_eq!(i64_type.get_context(), context);
source

pub fn i128_type(&self) -> IntType<'_>

Gets the IntType representing 128 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();
let i128_type = context.i128_type();

assert_eq!(i128_type.get_bit_width(), 128);
assert_eq!(i128_type.get_context(), context);
source

pub fn custom_width_int_type(&self, bits: u32) -> IntType<'_>

Gets the IntType representing a custom bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();
let i42_type = context.custom_width_int_type(42);

assert_eq!(i42_type.get_bit_width(), 42);
assert_eq!(i42_type.get_context(), context);
source

pub fn metadata_type(&self) -> MetadataType<'_>

Gets the MetadataType representing 128 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;
use inkwell::values::IntValue;

let context = Context::create();
let md_type = context.metadata_type();

assert_eq!(md_type.get_context(), context);
source

pub fn ptr_sized_int_type( &self, target_data: &TargetData, address_space: Option<AddressSpace> ) -> IntType<'_>

Gets the IntType representing a bit width of a pointer. It will be assigned the referenced context.

§Example
use inkwell::OptimizationLevel;
use inkwell::context::Context;
use inkwell::targets::{InitializationConfig, Target};

Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");

let context = Context::create();
let module = context.create_module("sum");
let execution_engine = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
let target_data = execution_engine.get_target_data();
let int_type = context.ptr_sized_int_type(&target_data, None);
source

pub fn f16_type(&self) -> FloatType<'_>

Gets the FloatType representing a 16 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();

let f16_type = context.f16_type();

assert_eq!(f16_type.get_context(), context);
source

pub fn f32_type(&self) -> FloatType<'_>

Gets the FloatType representing a 32 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();

let f32_type = context.f32_type();

assert_eq!(f32_type.get_context(), context);
source

pub fn f64_type(&self) -> FloatType<'_>

Gets the FloatType representing a 64 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();

let f64_type = context.f64_type();

assert_eq!(f64_type.get_context(), context);
source

pub fn x86_f80_type(&self) -> FloatType<'_>

Gets the FloatType representing a 80 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();

let x86_f80_type = context.x86_f80_type();

assert_eq!(x86_f80_type.get_context(), context);
source

pub fn f128_type(&self) -> FloatType<'_>

Gets the FloatType representing a 128 bit width. It will be assigned the current context.

§Example
use inkwell::context::Context;

let context = Context::create();

let f128_type = context.f128_type();

assert_eq!(f128_type.get_context(), context);
source

pub fn ppc_f128_type(&self) -> FloatType<'_>

Gets the FloatType representing a 128 bit width. It will be assigned the current context.

PPC is two 64 bits side by side rather than one single 128 bit float.

§Example
use inkwell::context::Context;

let context = Context::create();

let f128_type = context.ppc_f128_type();

assert_eq!(f128_type.get_context(), context);
source

pub fn ptr_type(&self, address_space: AddressSpace) -> PointerType<'_>

Gets the PointerType. It will be assigned the current context.

§Example
use inkwell::context::Context;
use inkwell::AddressSpace;

let context = Context::create();
let ptr_type = context.ptr_type(AddressSpace::default());

assert_eq!(ptr_type.get_address_space(), AddressSpace::default());
assert_eq!(ptr_type.get_context(), context);
source

pub fn struct_type( &self, field_types: &[BasicTypeEnum<'_>], packed: bool ) -> StructType<'_>

Creates a StructType definition from heterogeneous types in the current Context.

§Example
use inkwell::context::Context;

let context = Context::create();
let f32_type = context.f32_type();
let i16_type = context.i16_type();
let struct_type = context.struct_type(&[i16_type.into(), f32_type.into()], false);

assert_eq!(struct_type.get_field_types(), &[i16_type.into(), f32_type.into()]);
source

pub fn opaque_struct_type(&self, name: &str) -> StructType<'_>

Creates an opaque StructType with no type definition yet defined.

§Example
use inkwell::context::Context;

let context = Context::create();
let f32_type = context.f32_type();
let i16_type = context.i16_type();
let struct_type = context.opaque_struct_type("my_struct");

assert_eq!(struct_type.get_field_types(), &[]);
source

pub fn get_struct_type<'ctx>(&self, name: &str) -> Option<StructType<'ctx>>

Gets a named StructType from this Context.

§Example
use inkwell::context::Context;

let context = Context::create();

assert!(context.get_struct_type("foo").is_none());

let opaque = context.opaque_struct_type("foo");

assert_eq!(context.get_struct_type("foo").unwrap(), opaque);
source

pub fn const_struct( &self, values: &[BasicValueEnum<'_>], packed: bool ) -> StructValue<'_>

Creates a constant StructValue from constant values.

§Example
use inkwell::context::Context;

let context = Context::create();
let f32_type = context.f32_type();
let i16_type = context.i16_type();
let f32_one = f32_type.const_float(1.);
let i16_two = i16_type.const_int(2, false);
let const_struct = context.const_struct(&[i16_two.into(), f32_one.into()], false);

assert_eq!(const_struct.get_type().get_field_types(), &[i16_type.into(), f32_type.into()]);
source

pub fn append_basic_block<'ctx>( &'ctx self, function: FunctionValue<'ctx>, name: &str ) -> BasicBlock<'ctx>

Append a named BasicBlock at the end of the referenced FunctionValue.

§Example
use inkwell::context::Context;

let context = Context::create();
let module = context.create_module("my_mod");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let fn_value = module.add_function("my_fn", fn_type, None);
let entry_basic_block = context.append_basic_block(fn_value, "entry");

assert_eq!(fn_value.count_basic_blocks(), 1);

let last_basic_block = context.append_basic_block(fn_value, "last");

assert_eq!(fn_value.count_basic_blocks(), 2);
assert_eq!(fn_value.get_first_basic_block().unwrap(), entry_basic_block);
assert_eq!(fn_value.get_last_basic_block().unwrap(), last_basic_block);
source

pub fn insert_basic_block_after<'ctx>( &'ctx self, basic_block: BasicBlock<'ctx>, name: &str ) -> BasicBlock<'ctx>

Append a named BasicBlock after the referenced BasicBlock.

§Example
use inkwell::context::Context;

let context = Context::create();
let module = context.create_module("my_mod");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let fn_value = module.add_function("my_fn", fn_type, None);
let entry_basic_block = context.append_basic_block(fn_value, "entry");

assert_eq!(fn_value.count_basic_blocks(), 1);

let last_basic_block = context.insert_basic_block_after(entry_basic_block, "last");

assert_eq!(fn_value.count_basic_blocks(), 2);
assert_eq!(fn_value.get_first_basic_block().unwrap(), entry_basic_block);
assert_eq!(fn_value.get_last_basic_block().unwrap(), last_basic_block);
source

pub fn prepend_basic_block<'ctx>( &'ctx self, basic_block: BasicBlock<'ctx>, name: &str ) -> BasicBlock<'ctx>

Prepend a named BasicBlock before the referenced BasicBlock.

§Example
use inkwell::context::Context;

let context = Context::create();
let module = context.create_module("my_mod");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let fn_value = module.add_function("my_fn", fn_type, None);
let entry_basic_block = context.append_basic_block(fn_value, "entry");

assert_eq!(fn_value.count_basic_blocks(), 1);

let first_basic_block = context.prepend_basic_block(entry_basic_block, "first");

assert_eq!(fn_value.count_basic_blocks(), 2);
assert_eq!(fn_value.get_first_basic_block().unwrap(), first_basic_block);
assert_eq!(fn_value.get_last_basic_block().unwrap(), entry_basic_block);
source

pub fn metadata_node<'ctx>( &'ctx self, values: &[BasicMetadataValueEnum<'ctx>] ) -> MetadataValue<'ctx>

Creates a MetadataValue tuple of heterogeneous types (a “Node”) for the current context. It can be assigned to a value.

§Example
use inkwell::context::Context;

let context = Context::create();
let i8_type = context.i8_type();
let i8_two = i8_type.const_int(2, false);
let f32_type = context.f32_type();
let f32_zero = f32_type.const_float(0.);
let md_node = context.metadata_node(&[i8_two.into(), f32_zero.into()]);
let f32_one = f32_type.const_float(1.);
let void_type = context.void_type();

let builder = context.create_builder();
let module = context.create_module("my_mod");
let fn_type = void_type.fn_type(&[f32_type.into()], false);
let fn_value = module.add_function("my_func", fn_type, None);
let entry_block = context.append_basic_block(fn_value, "entry");

builder.position_at_end(entry_block);

let ret_instr = builder.build_return(None).unwrap();

assert!(md_node.is_node());

ret_instr.set_metadata(md_node, 0);
source

pub fn metadata_string(&self, string: &str) -> MetadataValue<'_>

Creates a MetadataValue string for the current context. It can be assigned to a value.

§Example
use inkwell::context::Context;

let context = Context::create();
let md_string = context.metadata_string("Floats are awesome!");
let f32_type = context.f32_type();
let f32_one = f32_type.const_float(1.);
let void_type = context.void_type();

let builder = context.create_builder();
let module = context.create_module("my_mod");
let fn_type = void_type.fn_type(&[f32_type.into()], false);
let fn_value = module.add_function("my_func", fn_type, None);
let entry_block = context.append_basic_block(fn_value, "entry");

builder.position_at_end(entry_block);

let ret_instr = builder.build_return(None).unwrap();

assert!(md_string.is_string());

ret_instr.set_metadata(md_string, 0);
source

pub fn get_kind_id(&self, key: &str) -> u32

Obtains the index of a metadata kind id. If the string doesn’t exist, LLVM will add it at index FIRST_CUSTOM_METADATA_KIND_ID onward.

§Example
use inkwell::context::Context;
use inkwell::values::FIRST_CUSTOM_METADATA_KIND_ID;

let context = Context::create();

assert_eq!(context.get_kind_id("dbg"), 0);
assert_eq!(context.get_kind_id("tbaa"), 1);
assert_eq!(context.get_kind_id("prof"), 2);

// Custom kind id doesn't exist in LLVM until now:
assert_eq!(context.get_kind_id("foo"), FIRST_CUSTOM_METADATA_KIND_ID);
source

pub fn create_enum_attribute(&self, kind_id: u32, val: u64) -> Attribute

Creates an enum Attribute in this Context.

§Example
use inkwell::context::Context;

let context = Context::create();
let enum_attribute = context.create_enum_attribute(0, 10);

assert!(enum_attribute.is_enum());
source

pub fn create_string_attribute(&self, key: &str, val: &str) -> Attribute

Creates a string Attribute in this Context.

§Example
use inkwell::context::Context;

let context = Context::create();
let string_attribute = context.create_string_attribute("my_key_123", "my_val");

assert!(string_attribute.is_string());
source

pub fn create_type_attribute( &self, kind_id: u32, type_ref: AnyTypeEnum<'_> ) -> Attribute

Create an enum Attribute with an AnyTypeEnum attached to it.

§Example
use inkwell::context::Context;
use inkwell::attributes::Attribute;
use inkwell::types::AnyType;

let context = Context::create();
let kind_id = Attribute::get_named_enum_kind_id("sret");
let any_type = context.i32_type().as_any_type_enum();
let type_attribute = context.create_type_attribute(
    kind_id,
    any_type,
);

assert!(type_attribute.is_type());
assert_eq!(type_attribute.get_type_value(), any_type);
assert_ne!(type_attribute.get_type_value(), context.i64_type().as_any_type_enum());
source

pub fn const_string( &self, string: &[u8], null_terminated: bool ) -> ArrayValue<'_>

Creates a const string which may be null terminated.

§Example
use inkwell::context::Context;
use inkwell::values::AnyValue;

let context = Context::create();
let string = context.const_string(b"my_string", false);

assert_eq!(string.print_to_string().to_string(), "[9 x i8] c\"my_string\"");

Trait Implementations§

source§

impl<'ctx> AsContextRef<'ctx> for &'ctx Context

source§

fn as_ctx_ref(&self) -> LLVMContextRef

Acquires the underlying raw pointer belonging to this Context type.

source§

impl Debug for Context

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Drop for Context

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl PartialEq<Context> for ContextRef<'_>

source§

fn eq(&self, other: &Context) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<ContextRef<'_>> for Context

source§

fn eq(&self, other: &ContextRef<'_>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Context

source§

fn eq(&self, other: &Context) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl Eq for Context

source§

impl Send for Context

source§

impl StructuralPartialEq for Context

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

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

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.