|
1 | 1 | //! A `BasicBlock` is a container of instructions.
|
2 | 2 |
|
3 |
| -use llvm_sys::core::{LLVMGetBasicBlockParent, LLVMGetBasicBlockTerminator, LLVMGetNextBasicBlock, LLVMIsABasicBlock, LLVMIsConstant, LLVMMoveBasicBlockAfter, LLVMMoveBasicBlockBefore, LLVMPrintTypeToString, LLVMPrintValueToString, LLVMTypeOf, LLVMDeleteBasicBlock, LLVMGetPreviousBasicBlock, LLVMRemoveBasicBlockFromParent, LLVMGetFirstInstruction, LLVMGetLastInstruction, LLVMGetTypeContext, LLVMBasicBlockAsValue, LLVMReplaceAllUsesWith}; |
| 3 | +use llvm_sys::core::{LLVMGetBasicBlockParent, LLVMGetBasicBlockTerminator, LLVMGetNextBasicBlock, LLVMIsABasicBlock, LLVMIsConstant, LLVMMoveBasicBlockAfter, LLVMMoveBasicBlockBefore, LLVMPrintTypeToString, LLVMPrintValueToString, LLVMTypeOf, LLVMDeleteBasicBlock, LLVMGetPreviousBasicBlock, LLVMRemoveBasicBlockFromParent, LLVMGetFirstInstruction, LLVMGetLastInstruction, LLVMGetTypeContext, LLVMBasicBlockAsValue, LLVMReplaceAllUsesWith, LLVMGetFirstUse}; |
4 | 4 | #[llvm_versions(3.9..=latest)]
|
5 | 5 | use llvm_sys::core::LLVMGetBasicBlockName;
|
6 | 6 | use llvm_sys::prelude::{LLVMValueRef, LLVMBasicBlockRef};
|
7 | 7 |
|
8 | 8 | use crate::context::ContextRef;
|
9 |
| -use crate::values::{FunctionValue, InstructionValue}; |
| 9 | +use crate::values::{BasicValueUse, FunctionValue, InstructionValue}; |
10 | 10 |
|
11 | 11 | use std::fmt;
|
12 | 12 | use std::ffi::CStr;
|
@@ -485,6 +485,42 @@ impl<'ctx> BasicBlock<'ctx> {
|
485 | 485 | }
|
486 | 486 | }
|
487 | 487 | }
|
| 488 | + |
| 489 | + /// Gets the first use of this `BasicBlock` if any. |
| 490 | + /// |
| 491 | + /// The following example, |
| 492 | + /// |
| 493 | + /// ```no_run |
| 494 | + /// use inkwell::AddressSpace; |
| 495 | + /// use inkwell::context::Context; |
| 496 | + /// use inkwell::values::BasicValue; |
| 497 | + /// |
| 498 | + /// let context = Context::create(); |
| 499 | + /// let module = context.create_module("ivs"); |
| 500 | + /// let builder = context.create_builder(); |
| 501 | + /// let void_type = context.void_type(); |
| 502 | + /// let fn_type = void_type.fn_type(&[], false); |
| 503 | + /// let fn_val = module.add_function("my_fn", fn_type, None); |
| 504 | + /// let entry = context.append_basic_block(fn_val, "entry"); |
| 505 | + /// let bb1 = context.append_basic_block(fn_val, "bb1"); |
| 506 | + /// let bb2 = context.append_basic_block(fn_val, "bb2"); |
| 507 | + /// builder.position_at_end(entry); |
| 508 | + /// let branch_inst = builder.build_unconditional_branch(bb1); |
| 509 | + /// |
| 510 | + /// assert!(bb2.get_first_use().is_none()); |
| 511 | + /// assert!(bb1.get_first_use().is_some()); |
| 512 | + /// ``` |
| 513 | + pub fn get_first_use(&self) -> Option<BasicValueUse> { |
| 514 | + let use_ = unsafe { |
| 515 | + LLVMGetFirstUse(LLVMBasicBlockAsValue(self.basic_block)) |
| 516 | + }; |
| 517 | + |
| 518 | + if use_.is_null() { |
| 519 | + return None; |
| 520 | + } |
| 521 | + |
| 522 | + Some(BasicValueUse::new(use_)) |
| 523 | + } |
488 | 524 | }
|
489 | 525 |
|
490 | 526 | impl fmt::Debug for BasicBlock<'_> {
|
|
0 commit comments