Skip to content

Commit 395ce6a

Browse files
committed
Allow obtaining BasicBlock from get_used_value
1 parent bba370c commit 395ce6a

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

src/values/basic_value_use.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
use values::{BasicValueEnum, InstructionValue};
2-
use llvm_sys::core::{LLVMGetNextUse, LLVMGetUser, LLVMGetUsedValue};
1+
use either::{Either, Either::{Left, Right}};
2+
use llvm_sys::core::{LLVMGetNextUse, LLVMGetUser, LLVMGetUsedValue, LLVMIsABasicBlock, LLVMValueAsBasicBlock};
33
use llvm_sys::prelude::LLVMUseRef;
44

5+
use basic_block::BasicBlock;
6+
use values::{BasicValueEnum, InstructionValue};
7+
58
/// A usage of a `BasicValue` in an `InstructionValue`.
69
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
710
pub struct BasicValueUse(LLVMUseRef);
@@ -118,7 +121,7 @@ impl BasicValueUse {
118121
InstructionValue::new(user)
119122
}
120123

121-
/// Gets the used value(a `BasicValueEnum`) of this use.
124+
/// Gets the used value(a `BasicValueEnum` or `BasicBlock`) of this use.
122125
///
123126
/// ```no_run
124127
/// use inkwell::AddressSpace;
@@ -149,15 +152,29 @@ impl BasicValueUse {
149152
/// let bitcast_use_value = free_operand0_instruction
150153
/// .get_first_use()
151154
/// .unwrap()
152-
/// .get_used_value();
155+
/// .get_used_value()
156+
/// .left()
157+
/// .unwrap();
153158
///
154159
/// assert_eq!(bitcast_use_value, free_operand0);
155160
/// ```
156-
pub fn get_used_value(&self) -> BasicValueEnum {
161+
pub fn get_used_value(&self) -> Either<BasicValueEnum, BasicBlock> {
157162
let used_value = unsafe {
158163
LLVMGetUsedValue(self.0)
159164
};
160165

161-
BasicValueEnum::new(used_value)
166+
let is_basic_block = unsafe {
167+
!LLVMIsABasicBlock(used_value).is_null()
168+
};
169+
170+
if is_basic_block {
171+
let used_value = unsafe {
172+
LLVMValueAsBasicBlock(used_value)
173+
};
174+
175+
Right(BasicBlock::new(used_value).expect("BasicBlock should be valid"))
176+
} else {
177+
Left(BasicValueEnum::new(used_value))
178+
}
162179
}
163180
}

tests/all/test_instruction_values.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ fn test_operands() {
8383
let bitcast_use_value = free_operand0_instruction
8484
.get_first_use()
8585
.unwrap()
86-
.get_used_value();
86+
.get_used_value()
87+
.left()
88+
.unwrap();
8789
let free_call_param = free_instruction.get_operand(0).unwrap().left().unwrap();
8890

8991
assert_eq!(bitcast_use_value, free_call_param);
@@ -109,8 +111,8 @@ fn test_operands() {
109111

110112
assert_eq!(store_operand_use0.get_user(), store_instruction);
111113
assert_eq!(store_operand_use1.get_user(), store_instruction);
112-
assert_eq!(store_operand_use0.get_used_value(), f32_val);
113-
assert_eq!(store_operand_use1.get_used_value(), arg1);
114+
assert_eq!(store_operand_use0.get_used_value().left().unwrap(), f32_val);
115+
assert_eq!(store_operand_use1.get_used_value().left().unwrap(), arg1);
114116

115117
assert!(store_instruction.get_operand_use(2).is_none());
116118
assert!(store_instruction.get_operand_use(3).is_none());
@@ -150,6 +152,10 @@ fn test_basic_block_operand() {
150152

151153
assert_eq!(bb_operand, basic_block2);
152154

155+
let bb_operand_use = branch_instruction.get_operand_use(0).unwrap();
156+
157+
assert_eq!(bb_operand_use.get_used_value().right().unwrap(), basic_block2);
158+
153159
builder.position_at_end(&basic_block2);
154160
builder.build_return(None);
155161

0 commit comments

Comments
 (0)