pub struct BasicBlock<'ctx> { /* private fields */ }
Expand description
A BasicBlock
is a container of instructions.
BasicBlock
s are values because they can be referenced by instructions (ie branching and switches).
A well formed BasicBlock
is a list of non terminating instructions followed by a single terminating
instruction. BasicBlock
s are allowed to be malformed prior to running validation because it may be useful
when constructing or modifying a program.
Implementations§
Source§impl<'ctx> BasicBlock<'ctx>
impl<'ctx> BasicBlock<'ctx>
Sourcepub fn as_mut_ptr(&self) -> LLVMBasicBlockRef
pub fn as_mut_ptr(&self) -> LLVMBasicBlockRef
Acquires the underlying raw pointer belonging to this BasicBlock
type.
Sourcepub fn get_parent(self) -> Option<FunctionValue<'ctx>>
pub fn get_parent(self) -> Option<FunctionValue<'ctx>>
Obtains the FunctionValue
that this BasicBlock
belongs to, if any.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
let context = Context::create();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
assert_eq!(basic_block.get_parent().unwrap(), function);
basic_block.remove_from_function();
assert!(basic_block.get_parent().is_none());
Sourcepub fn get_previous_basic_block(self) -> Option<BasicBlock<'ctx>>
pub fn get_previous_basic_block(self) -> Option<BasicBlock<'ctx>>
Gets the BasicBlock
preceding the current one, in its own scope, if any.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
let context = Context::create();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function1 = module.add_function("do_nothing", fn_type, None);
let basic_block1 = context.append_basic_block(function1, "entry");
assert!(basic_block1.get_previous_basic_block().is_none());
let function2 = module.add_function("do_nothing", fn_type, None);
let basic_block2 = context.append_basic_block(function2, "entry");
let basic_block3 = context.append_basic_block(function2, "next");
assert!(basic_block2.get_previous_basic_block().is_none());
assert_eq!(basic_block3.get_previous_basic_block().unwrap(), basic_block2);
Sourcepub fn get_next_basic_block(self) -> Option<BasicBlock<'ctx>>
pub fn get_next_basic_block(self) -> Option<BasicBlock<'ctx>>
Gets the BasicBlock
succeeding the current one, in its own scope, if any.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
let context = Context::create();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function1 = module.add_function("do_nothing", fn_type, None);
let basic_block1 = context.append_basic_block(function1, "entry");
assert!(basic_block1.get_next_basic_block().is_none());
let function2 = module.add_function("do_nothing", fn_type, None);
let basic_block2 = context.append_basic_block(function2, "entry");
let basic_block3 = context.append_basic_block(function2, "next");
assert!(basic_block1.get_next_basic_block().is_none());
assert_eq!(basic_block2.get_next_basic_block().unwrap(), basic_block3);
assert!(basic_block3.get_next_basic_block().is_none());
Sourcepub fn move_before(self, basic_block: BasicBlock<'ctx>) -> Result<(), ()>
pub fn move_before(self, basic_block: BasicBlock<'ctx>) -> Result<(), ()>
Prepends one BasicBlock
before another.
It returns Err(())
when either BasicBlock
has no parent, as LLVM assumes they both have parents.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
let context = Context::create();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block1 = context.append_basic_block(function, "entry");
let basic_block2 = context.append_basic_block(function, "next");
basic_block2.move_before(basic_block1);
assert!(basic_block1.get_next_basic_block().is_none());
assert_eq!(basic_block2.get_next_basic_block().unwrap(), basic_block1);
Sourcepub fn move_after(self, basic_block: BasicBlock<'ctx>) -> Result<(), ()>
pub fn move_after(self, basic_block: BasicBlock<'ctx>) -> Result<(), ()>
Appends one BasicBlock
after another.
It returns Err(())
when either BasicBlock
has no parent, as LLVM assumes they both have parents.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
let context = Context::create();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block1 = context.append_basic_block(function, "entry");
let basic_block2 = context.append_basic_block(function, "next");
basic_block1.move_after(basic_block2);
assert!(basic_block1.get_next_basic_block().is_none());
assert_eq!(basic_block2.get_next_basic_block().unwrap(), basic_block1);
Sourcepub fn get_first_instruction(self) -> Option<InstructionValue<'ctx>>
pub fn get_first_instruction(self) -> Option<InstructionValue<'ctx>>
Obtains the first InstructionValue
in this BasicBlock
, if any.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
use inkwell::values::InstructionOpcode;
let context = Context::create();
let builder = context.create_builder();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
builder.position_at_end(basic_block);
builder.build_return(None);
assert_eq!(basic_block.get_first_instruction().unwrap().get_opcode(), InstructionOpcode::Return);
Sourcepub fn get_last_instruction(self) -> Option<InstructionValue<'ctx>>
pub fn get_last_instruction(self) -> Option<InstructionValue<'ctx>>
Obtains the last InstructionValue
in this BasicBlock
, if any. A BasicBlock
must have a last instruction to be valid.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
use inkwell::values::InstructionOpcode;
let context = Context::create();
let builder = context.create_builder();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
builder.position_at_end(basic_block);
builder.build_return(None);
assert_eq!(basic_block.get_last_instruction().unwrap().get_opcode(), InstructionOpcode::Return);
Sourcepub fn get_instruction_with_name(
self,
name: &str,
) -> Option<InstructionValue<'ctx>>
pub fn get_instruction_with_name( self, name: &str, ) -> Option<InstructionValue<'ctx>>
Performs a linear lookup to obtain a instruction based on the name
§Example
use inkwell::context::Context;
use inkwell::AddressSpace;
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();
#[cfg(not(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0")))]
let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
#[cfg(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-0"))]
let i32_ptr_type = context.ptr_type(AddressSpace::default());
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");
builder.position_at_end(entry);
let var = builder.build_alloca(i32_type, "some_number").unwrap();
builder.build_store(var, i32_type.const_int(1 as u64, false)).unwrap();
builder.build_return(None).unwrap();
let block = fn_value.get_first_basic_block().unwrap();
let some_number = block.get_instruction_with_name("some_number");
assert!(some_number.is_some());
assert_eq!(some_number.unwrap().get_name().unwrap().to_str(), Ok("some_number"))
Sourcepub fn get_terminator(self) -> Option<InstructionValue<'ctx>>
pub fn get_terminator(self) -> Option<InstructionValue<'ctx>>
Obtains the terminating InstructionValue
in this BasicBlock
, if any. A BasicBlock
must have a terminating instruction to be valid.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
use inkwell::values::InstructionOpcode;
let context = Context::create();
let builder = context.create_builder();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
builder.position_at_end(basic_block);
builder.build_return(None);
assert_eq!(basic_block.get_terminator().unwrap().get_opcode(), InstructionOpcode::Return);
Sourcepub fn get_instructions(self) -> InstructionIter<'ctx> ⓘ
pub fn get_instructions(self) -> InstructionIter<'ctx> ⓘ
Get an instruction iterator
Sourcepub fn remove_from_function(self) -> Result<(), ()>
pub fn remove_from_function(self) -> Result<(), ()>
Removes this BasicBlock
from its parent FunctionValue
.
It returns Err(())
when it has no parent to remove from.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
let context = Context::create();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
assert_eq!(basic_block.get_parent().unwrap(), function);
basic_block.remove_from_function();
assert!(basic_block.get_parent().is_none());
Sourcepub unsafe fn delete(self) -> Result<(), ()>
pub unsafe fn delete(self) -> Result<(), ()>
Removes this BasicBlock
completely from memory. This is unsafe because you could easily have other references to the same BasicBlock
.
It returns Err(())
when it has no parent to delete from, as LLVM assumes it has a parent.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
let context = Context::create();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
unsafe {
basic_block.delete();
}
assert!(function.get_basic_blocks().is_empty());
Sourcepub fn get_context(self) -> ContextRef<'ctx>
pub fn get_context(self) -> ContextRef<'ctx>
Obtains the ContextRef
this BasicBlock
belongs to.
§Example
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::builder::Builder;
let context = Context::create();
let module = context.create_module("my_module");
let void_type = context.void_type();
let fn_type = void_type.fn_type(&[], false);
let function = module.add_function("do_nothing", fn_type, None);
let basic_block = context.append_basic_block(function, "entry");
assert_eq!(context, basic_block.get_context());
Sourcepub fn get_name(&self) -> &CStr
pub fn get_name(&self) -> &CStr
Gets the name of a BasicBlock
.
§Example
use inkwell::context::Context;
let context = Context::create();
let builder = context.create_builder();
let module = context.create_module("my_mod");
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 bb = context.append_basic_block(fn_val, "entry");
assert_eq!(bb.get_name().to_str(), Ok("entry"));
Sourcepub fn replace_all_uses_with(self, other: &BasicBlock<'ctx>)
pub fn replace_all_uses_with(self, other: &BasicBlock<'ctx>)
Replaces all uses of this basic block with another.
§Example
use inkwell::context::Context;
let context = Context::create();
let builder = context.create_builder();
let module = context.create_module("my_mod");
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 entry = context.append_basic_block(fn_val, "entry");
let bb1 = context.append_basic_block(fn_val, "bb1");
let bb2 = context.append_basic_block(fn_val, "bb2");
builder.position_at_end(entry);
let branch_inst = builder.build_unconditional_branch(bb1).unwrap();
bb1.replace_all_uses_with(&bb2);
assert_eq!(branch_inst.get_operand(0).unwrap().right().unwrap(), bb2);
Sourcepub fn get_first_use(self) -> Option<BasicValueUse<'ctx>>
pub fn get_first_use(self) -> Option<BasicValueUse<'ctx>>
Gets the first use of this BasicBlock
if any.
The following example,
use inkwell::AddressSpace;
use inkwell::context::Context;
use inkwell::values::BasicValue;
let context = Context::create();
let module = context.create_module("ivs");
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 entry = context.append_basic_block(fn_val, "entry");
let bb1 = context.append_basic_block(fn_val, "bb1");
let bb2 = context.append_basic_block(fn_val, "bb2");
builder.position_at_end(entry);
let branch_inst = builder.build_unconditional_branch(bb1);
assert!(bb2.get_first_use().is_none());
assert!(bb1.get_first_use().is_some());
Sourcepub unsafe fn get_address(self) -> Option<PointerValue<'ctx>>
pub unsafe fn get_address(self) -> Option<PointerValue<'ctx>>
Gets the address of this BasicBlock
if possible. Returns None
if self
is the entry block to a function.
§Safety
The returned PointerValue may only be used for call
and indirect_branch
instructions
§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_val = module.add_function("my_fn", fn_type, None);
let entry_bb = context.append_basic_block(fn_val, "entry");
let next_bb = context.append_basic_block(fn_val, "next");
assert!(unsafe { entry_bb.get_address() }.is_none());
assert!(unsafe { next_bb.get_address() }.is_some());
Trait Implementations§
Source§impl<'ctx> Clone for BasicBlock<'ctx>
impl<'ctx> Clone for BasicBlock<'ctx>
Source§fn clone(&self) -> BasicBlock<'ctx>
fn clone(&self) -> BasicBlock<'ctx>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for BasicBlock<'_>
impl Debug for BasicBlock<'_>
Source§impl<'ctx> Hash for BasicBlock<'ctx>
impl<'ctx> Hash for BasicBlock<'ctx>
Source§impl<'ctx> PartialEq for BasicBlock<'ctx>
impl<'ctx> PartialEq for BasicBlock<'ctx>
impl<'ctx> Copy for BasicBlock<'ctx>
impl<'ctx> Eq for BasicBlock<'ctx>
impl<'ctx> StructuralPartialEq for BasicBlock<'ctx>
Auto Trait Implementations§
impl<'ctx> Freeze for BasicBlock<'ctx>
impl<'ctx> RefUnwindSafe for BasicBlock<'ctx>
impl<'ctx> !Send for BasicBlock<'ctx>
impl<'ctx> !Sync for BasicBlock<'ctx>
impl<'ctx> Unpin for BasicBlock<'ctx>
impl<'ctx> UnwindSafe for BasicBlock<'ctx>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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