Skip to main content

inkwell/
basic_block.rs

1//! A `BasicBlock` is a container of instructions.
2
3use llvm_sys::core::{
4    LLVMBasicBlockAsValue, LLVMBlockAddress, LLVMDeleteBasicBlock, LLVMGetBasicBlockName, LLVMGetBasicBlockParent,
5    LLVMGetBasicBlockTerminator, LLVMGetFirstInstruction, LLVMGetFirstUse, LLVMGetLastInstruction,
6    LLVMGetNextBasicBlock, LLVMGetPreviousBasicBlock, LLVMGetTypeContext, LLVMIsABasicBlock, LLVMIsConstant,
7    LLVMMoveBasicBlockAfter, LLVMMoveBasicBlockBefore, LLVMPrintTypeToString, LLVMPrintValueToString,
8    LLVMRemoveBasicBlockFromParent, LLVMReplaceAllUsesWith, LLVMSetValueName2, LLVMTypeOf,
9};
10use llvm_sys::prelude::{LLVMBasicBlockRef, LLVMValueRef};
11
12use crate::context::ContextRef;
13use crate::support::to_c_str;
14use crate::values::{AsValueRef, BasicValueUse, FunctionValue, InstructionValue, PointerValue};
15
16use std::ffi::CStr;
17use std::fmt;
18use std::marker::PhantomData;
19
20/// A `BasicBlock` is a container of instructions.
21///
22/// `BasicBlock`s are values because they can be referenced by instructions (ie branching and switches).
23///
24/// A well formed `BasicBlock` is a list of non terminating instructions followed by a single terminating
25/// instruction. `BasicBlock`s are allowed to be malformed prior to running validation because it may be useful
26/// when constructing or modifying a program.
27#[derive(PartialEq, Eq, Clone, Copy, Hash)]
28pub struct BasicBlock<'ctx> {
29    pub(crate) basic_block: LLVMBasicBlockRef,
30    _marker: PhantomData<&'ctx ()>,
31}
32
33impl<'ctx> BasicBlock<'ctx> {
34    /// Create a basic block from an [LLVMBasicBlockRef].
35    ///
36    /// # Safety
37    ///
38    /// The ref must be valid and point to a valid LLVM basic block.
39    pub unsafe fn new(basic_block: LLVMBasicBlockRef) -> Option<Self> {
40        if basic_block.is_null() {
41            return None;
42        }
43
44        // NOTE: There is a LLVMBasicBlockAsValue but it might be the same as casting
45        assert!(!LLVMIsABasicBlock(basic_block as LLVMValueRef).is_null());
46
47        Some(BasicBlock {
48            basic_block,
49            _marker: PhantomData,
50        })
51    }
52
53    /// Acquires the underlying raw pointer belonging to this `BasicBlock` type.
54    pub fn as_mut_ptr(&self) -> LLVMBasicBlockRef {
55        self.basic_block
56    }
57
58    /// Obtains the `FunctionValue` that this `BasicBlock` belongs to, if any.
59    ///
60    /// # Example
61    /// ```no_run
62    /// use inkwell::context::Context;
63    /// use inkwell::module::Module;
64    /// use inkwell::builder::Builder;
65    ///
66    /// let context = Context::create();
67    /// let module = context.create_module("my_module");
68    /// let void_type = context.void_type();
69    /// let fn_type = void_type.fn_type(&[], false);
70    /// let function = module.add_function("do_nothing", fn_type, None);
71    ///
72    /// let basic_block = context.append_basic_block(function, "entry");
73    ///
74    /// assert_eq!(basic_block.get_parent().unwrap(), function);
75    ///
76    /// basic_block.remove_from_function();
77    ///
78    /// assert!(basic_block.get_parent().is_none());
79    /// ```
80    pub fn get_parent(self) -> Option<FunctionValue<'ctx>> {
81        unsafe { FunctionValue::new(LLVMGetBasicBlockParent(self.basic_block)) }
82    }
83
84    /// Gets the `BasicBlock` preceding the current one, in its own scope, if any.
85    ///
86    /// # Example
87    /// ```no_run
88    /// use inkwell::context::Context;
89    /// use inkwell::module::Module;
90    /// use inkwell::builder::Builder;
91    ///
92    /// let context = Context::create();
93    /// let module = context.create_module("my_module");
94    /// let void_type = context.void_type();
95    /// let fn_type = void_type.fn_type(&[], false);
96    /// let function1 = module.add_function("do_nothing", fn_type, None);
97    ///
98    /// let basic_block1 = context.append_basic_block(function1, "entry");
99    ///
100    /// assert!(basic_block1.get_previous_basic_block().is_none());
101    ///
102    /// let function2 = module.add_function("do_nothing", fn_type, None);
103    ///
104    /// let basic_block2 = context.append_basic_block(function2, "entry");
105    /// let basic_block3 = context.append_basic_block(function2, "next");
106    ///
107    /// assert!(basic_block2.get_previous_basic_block().is_none());
108    /// assert_eq!(basic_block3.get_previous_basic_block().unwrap(), basic_block2);
109    /// ```
110    pub fn get_previous_basic_block(self) -> Option<BasicBlock<'ctx>> {
111        self.get_parent()?;
112
113        unsafe { BasicBlock::new(LLVMGetPreviousBasicBlock(self.basic_block)) }
114    }
115
116    /// Gets the `BasicBlock` succeeding the current one, in its own scope, if any.
117    ///
118    /// # Example
119    /// ```no_run
120    /// use inkwell::context::Context;
121    /// use inkwell::module::Module;
122    /// use inkwell::builder::Builder;
123    ///
124    /// let context = Context::create();
125    /// let module = context.create_module("my_module");
126    /// let void_type = context.void_type();
127    /// let fn_type = void_type.fn_type(&[], false);
128    /// let function1 = module.add_function("do_nothing", fn_type, None);
129    ///
130    /// let basic_block1 = context.append_basic_block(function1, "entry");
131    ///
132    /// assert!(basic_block1.get_next_basic_block().is_none());
133    ///
134    /// let function2 = module.add_function("do_nothing", fn_type, None);
135    ///
136    /// let basic_block2 = context.append_basic_block(function2, "entry");
137    /// let basic_block3 = context.append_basic_block(function2, "next");
138    ///
139    /// assert!(basic_block1.get_next_basic_block().is_none());
140    /// assert_eq!(basic_block2.get_next_basic_block().unwrap(), basic_block3);
141    /// assert!(basic_block3.get_next_basic_block().is_none());
142    /// ```
143    pub fn get_next_basic_block(self) -> Option<BasicBlock<'ctx>> {
144        self.get_parent()?;
145
146        unsafe { BasicBlock::new(LLVMGetNextBasicBlock(self.basic_block)) }
147    }
148
149    /// Prepends one `BasicBlock` before another.
150    /// It returns `Err(())` when either `BasicBlock` has no parent, as LLVM assumes they both have parents.
151    ///
152    /// # Example
153    /// ```no_run
154    /// use inkwell::context::Context;
155    /// use inkwell::module::Module;
156    /// use inkwell::builder::Builder;
157    ///
158    /// let context = Context::create();
159    /// let module = context.create_module("my_module");
160    /// let void_type = context.void_type();
161    /// let fn_type = void_type.fn_type(&[], false);
162    /// let function = module.add_function("do_nothing", fn_type, None);
163    ///
164    /// let basic_block1 = context.append_basic_block(function, "entry");
165    /// let basic_block2 = context.append_basic_block(function, "next");
166    ///
167    /// basic_block2.move_before(basic_block1);
168    ///
169    /// assert!(basic_block1.get_next_basic_block().is_none());
170    /// assert_eq!(basic_block2.get_next_basic_block().unwrap(), basic_block1);
171    /// ```
172    // REVIEW: What happens if blocks are from different scopes?
173    pub fn move_before(self, basic_block: BasicBlock<'ctx>) -> Result<(), ()> {
174        // This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
175        if self.get_parent().is_none() || basic_block.get_parent().is_none() {
176            return Err(());
177        }
178
179        unsafe { LLVMMoveBasicBlockBefore(self.basic_block, basic_block.basic_block) }
180
181        Ok(())
182    }
183
184    /// Appends one `BasicBlock` after another.
185    /// It returns `Err(())` when either `BasicBlock` has no parent, as LLVM assumes they both have parents.
186    ///
187    /// # Example
188    /// ```no_run
189    /// use inkwell::context::Context;
190    /// use inkwell::module::Module;
191    /// use inkwell::builder::Builder;
192    ///
193    /// let context = Context::create();
194    /// let module = context.create_module("my_module");
195    /// let void_type = context.void_type();
196    /// let fn_type = void_type.fn_type(&[], false);
197    /// let function = module.add_function("do_nothing", fn_type, None);
198    ///
199    /// let basic_block1 = context.append_basic_block(function, "entry");
200    /// let basic_block2 = context.append_basic_block(function, "next");
201    ///
202    /// basic_block1.move_after(basic_block2);
203    ///
204    /// assert!(basic_block1.get_next_basic_block().is_none());
205    /// assert_eq!(basic_block2.get_next_basic_block().unwrap(), basic_block1);
206    /// ```
207    // REVIEW: What happens if blocks are from different scopes?
208    pub fn move_after(self, basic_block: BasicBlock<'ctx>) -> Result<(), ()> {
209        // This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
210        if self.get_parent().is_none() || basic_block.get_parent().is_none() {
211            return Err(());
212        }
213
214        unsafe { LLVMMoveBasicBlockAfter(self.basic_block, basic_block.basic_block) }
215
216        Ok(())
217    }
218
219    /// Obtains the first `InstructionValue` in this `BasicBlock`, if any.
220    ///
221    /// # Example
222    /// ```no_run
223    /// use inkwell::context::Context;
224    /// use inkwell::module::Module;
225    /// use inkwell::builder::Builder;
226    /// use inkwell::values::InstructionOpcode;
227    ///
228    /// let context = Context::create();
229    /// let builder = context.create_builder();
230    /// let module = context.create_module("my_module");
231    /// let void_type = context.void_type();
232    /// let fn_type = void_type.fn_type(&[], false);
233    /// let function = module.add_function("do_nothing", fn_type, None);
234    /// let basic_block = context.append_basic_block(function, "entry");
235    ///
236    /// builder.position_at_end(basic_block);
237    /// builder.build_return(None);
238    ///
239    /// assert_eq!(basic_block.get_first_instruction().unwrap().get_opcode(), InstructionOpcode::Return);
240    /// ```
241    pub fn get_first_instruction(self) -> Option<InstructionValue<'ctx>> {
242        let value = unsafe { LLVMGetFirstInstruction(self.basic_block) };
243
244        if value.is_null() {
245            return None;
246        }
247
248        unsafe { Some(InstructionValue::new(value)) }
249    }
250
251    /// Obtains the last `InstructionValue` in this `BasicBlock`, if any. A `BasicBlock` must have a last instruction to be valid.
252    ///
253    /// # Example
254    /// ```no_run
255    /// use inkwell::context::Context;
256    /// use inkwell::module::Module;
257    /// use inkwell::builder::Builder;
258    /// use inkwell::values::InstructionOpcode;
259    ///
260    /// let context = Context::create();
261    /// let builder = context.create_builder();
262    /// let module = context.create_module("my_module");
263    /// let void_type = context.void_type();
264    /// let fn_type = void_type.fn_type(&[], false);
265    /// let function = module.add_function("do_nothing", fn_type, None);
266    /// let basic_block = context.append_basic_block(function, "entry");
267    ///
268    /// builder.position_at_end(basic_block);
269    /// builder.build_return(None);
270    ///
271    /// assert_eq!(basic_block.get_last_instruction().unwrap().get_opcode(), InstructionOpcode::Return);
272    /// ```
273    pub fn get_last_instruction(self) -> Option<InstructionValue<'ctx>> {
274        let value = unsafe { LLVMGetLastInstruction(self.basic_block) };
275
276        if value.is_null() {
277            return None;
278        }
279
280        unsafe { Some(InstructionValue::new(value)) }
281    }
282
283    /// Performs a linear lookup to obtain a instruction based on the name
284    ///
285    /// # Example
286    /// ```rust
287    /// use inkwell::context::Context;
288    /// use inkwell::AddressSpace;
289    ///
290    /// let context = Context::create();
291    /// let module = context.create_module("ret");
292    /// let builder = context.create_builder();
293    ///
294    /// let void_type = context.void_type();
295    /// let i32_type = context.i32_type();
296    /// #[cfg(feature = "typed-pointers")]
297    /// let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
298    /// #[cfg(not(feature = "typed-pointers"))]
299    /// let i32_ptr_type = context.ptr_type(AddressSpace::default());
300    ///
301    /// let fn_type = void_type.fn_type(&[i32_ptr_type.into()], false);
302    /// let fn_value = module.add_function("ret", fn_type, None);
303    /// let entry = context.append_basic_block(fn_value, "entry");
304    /// builder.position_at_end(entry);
305    ///
306    /// let var = builder.build_alloca(i32_type, "some_number").unwrap();
307    /// builder.build_store(var, i32_type.const_int(1 as u64, false)).unwrap();
308    /// builder.build_return(None).unwrap();
309    ///
310    /// let block = fn_value.get_first_basic_block().unwrap();
311    /// let some_number = block.get_instruction_with_name("some_number");
312    ///
313    /// assert!(some_number.is_some());
314    /// assert_eq!(some_number.unwrap().get_name().unwrap().to_str(), Ok("some_number"))
315    /// ```
316    pub fn get_instruction_with_name(self, name: &str) -> Option<InstructionValue<'ctx>> {
317        let instruction = self.get_first_instruction()?;
318        instruction.get_instruction_with_name(name)
319    }
320
321    /// Obtains the terminating `InstructionValue` in this `BasicBlock`, if any. A `BasicBlock` must have a terminating instruction to be valid.
322    ///
323    /// # Example
324    /// ```no_run
325    /// use inkwell::context::Context;
326    /// use inkwell::module::Module;
327    /// use inkwell::builder::Builder;
328    /// use inkwell::values::InstructionOpcode;
329    ///
330    /// let context = Context::create();
331    /// let builder = context.create_builder();
332    /// let module = context.create_module("my_module");
333    /// let void_type = context.void_type();
334    /// let fn_type = void_type.fn_type(&[], false);
335    /// let function = module.add_function("do_nothing", fn_type, None);
336    /// let basic_block = context.append_basic_block(function, "entry");
337    ///
338    /// builder.position_at_end(basic_block);
339    /// builder.build_return(None);
340    ///
341    /// assert_eq!(basic_block.get_terminator().unwrap().get_opcode(), InstructionOpcode::Return);
342    /// ```
343    // REVIEW: If we wanted the return type could be Option<Either<BasicValueEnum, InstructionValue>>
344    // if getting a value over an instruction is preferable
345    // TODOC: Every BB must have a terminating instruction or else it is invalid
346    // REVIEW: Unclear how this differs from get_last_instruction
347    pub fn get_terminator(self) -> Option<InstructionValue<'ctx>> {
348        let value = unsafe { LLVMGetBasicBlockTerminator(self.basic_block) };
349
350        if value.is_null() {
351            return None;
352        }
353
354        unsafe { Some(InstructionValue::new(value)) }
355    }
356
357    /// Get an instruction iterator
358    pub fn get_instructions(self) -> InstructionIter<'ctx> {
359        InstructionIter(self.get_first_instruction())
360    }
361
362    /// Removes this `BasicBlock` from its parent `FunctionValue`.
363    /// It returns `Err(())` when it has no parent to remove from.
364    ///
365    /// # Example
366    /// ```no_run
367    /// use inkwell::context::Context;
368    /// use inkwell::module::Module;
369    /// use inkwell::builder::Builder;
370    ///
371    /// let context = Context::create();
372    /// let module = context.create_module("my_module");
373    /// let void_type = context.void_type();
374    /// let fn_type = void_type.fn_type(&[], false);
375    /// let function = module.add_function("do_nothing", fn_type, None);
376    /// let basic_block = context.append_basic_block(function, "entry");
377    ///
378    /// assert_eq!(basic_block.get_parent().unwrap(), function);
379    ///
380    /// basic_block.remove_from_function();
381    ///
382    /// assert!(basic_block.get_parent().is_none());
383    /// ```
384    // SubTypes: Don't need to call get_parent for a BasicBlock<HasParent> and would return BasicBlock<Orphan>
385    // by taking ownership of self (though BasicBlock's are not uniquely obtained...)
386    // might have to make some methods do something like -> Result<..., BasicBlock<Orphan>> for BasicBlock<HasParent>
387    // and would move_before/after make it no longer orphaned? etc..
388    pub fn remove_from_function(self) -> Result<(), ()> {
389        // This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
390        if self.get_parent().is_none() {
391            return Err(());
392        }
393
394        unsafe { LLVMRemoveBasicBlockFromParent(self.basic_block) }
395
396        Ok(())
397    }
398
399    /// Removes this `BasicBlock` completely from memory. This is unsafe because you could easily have other references to the same `BasicBlock`.
400    /// It returns `Err(())` when it has no parent to delete from, as LLVM assumes it has a parent.
401    ///
402    /// # Example
403    /// ```no_run
404    /// use inkwell::context::Context;
405    /// use inkwell::module::Module;
406    /// use inkwell::builder::Builder;
407    ///
408    /// let context = Context::create();
409    /// let module = context.create_module("my_module");
410    /// let void_type = context.void_type();
411    /// let fn_type = void_type.fn_type(&[], false);
412    /// let function = module.add_function("do_nothing", fn_type, None);
413    /// let basic_block = context.append_basic_block(function, "entry");
414    ///
415    /// unsafe {
416    ///     basic_block.delete();
417    /// }
418    /// assert!(function.get_basic_blocks().is_empty());
419    /// ```
420    pub unsafe fn delete(self) -> Result<(), ()> {
421        // This method is UB if the parent no longer exists, so we must check for parent (or encode into type system)
422        if self.get_parent().is_none() {
423            return Err(());
424        }
425
426        LLVMDeleteBasicBlock(self.basic_block);
427
428        Ok(())
429    }
430
431    /// Obtains the `ContextRef` this `BasicBlock` belongs to.
432    ///
433    /// # Example
434    /// ```no_run
435    /// use inkwell::context::Context;
436    /// use inkwell::module::Module;
437    /// use inkwell::builder::Builder;
438    ///
439    /// let context = Context::create();
440    /// let module = context.create_module("my_module");
441    /// let void_type = context.void_type();
442    /// let fn_type = void_type.fn_type(&[], false);
443    /// let function = module.add_function("do_nothing", fn_type, None);
444    /// let basic_block = context.append_basic_block(function, "entry");
445    ///
446    /// assert_eq!(context, basic_block.get_context());
447    /// ```
448    pub fn get_context(self) -> ContextRef<'ctx> {
449        unsafe { ContextRef::new(LLVMGetTypeContext(LLVMTypeOf(LLVMBasicBlockAsValue(self.basic_block)))) }
450    }
451
452    /// Gets the name of a `BasicBlock`.
453    ///
454    /// # Example
455    ///
456    /// ```no_run
457    /// use inkwell::context::Context;
458    ///
459    /// let context = Context::create();
460    /// let builder = context.create_builder();
461    /// let module = context.create_module("my_mod");
462    /// let void_type = context.void_type();
463    /// let fn_type = void_type.fn_type(&[], false);
464    /// let fn_val = module.add_function("my_fn", fn_type, None);
465    /// let bb = context.append_basic_block(fn_val, "entry");
466    ///
467    /// assert_eq!(bb.get_name().to_str(), Ok("entry"));
468    /// ```
469    pub fn get_name(&self) -> &CStr {
470        let ptr = unsafe { LLVMGetBasicBlockName(self.basic_block) };
471
472        unsafe { CStr::from_ptr(ptr) }
473    }
474
475    /// Set name of the `BasicBlock`.
476    pub fn set_name(&self, name: &str) {
477        let c_string = to_c_str(name);
478
479        unsafe {
480            LLVMSetValueName2(
481                LLVMBasicBlockAsValue(self.basic_block),
482                c_string.as_ptr(),
483                c_string.to_bytes().len(),
484            )
485        };
486    }
487
488    /// Replaces all uses of this basic block with another.
489    ///
490    /// # Example
491    ///
492    /// ```
493    /// use inkwell::context::Context;
494    ///
495    /// let context = Context::create();
496    /// let builder = context.create_builder();
497    /// let module = context.create_module("my_mod");
498    /// let void_type = context.void_type();
499    /// let fn_type = void_type.fn_type(&[], false);
500    /// let fn_val = module.add_function("my_fn", fn_type, None);
501    /// let entry = context.append_basic_block(fn_val, "entry");
502    /// let bb1 = context.append_basic_block(fn_val, "bb1");
503    /// let bb2 = context.append_basic_block(fn_val, "bb2");
504    /// builder.position_at_end(entry);
505    /// let branch_inst = builder.build_unconditional_branch(bb1).unwrap();
506    ///
507    /// bb1.replace_all_uses_with(&bb2);
508    ///
509    /// assert_eq!(branch_inst.get_operand(0).unwrap().unwrap_block(), bb2);
510    /// ```
511    pub fn replace_all_uses_with(self, other: &BasicBlock<'ctx>) {
512        let value = unsafe { LLVMBasicBlockAsValue(self.basic_block) };
513        let other = unsafe { LLVMBasicBlockAsValue(other.basic_block) };
514
515        // LLVM may infinite-loop when they aren't distinct, which is UB in C++.
516        if value != other {
517            unsafe {
518                LLVMReplaceAllUsesWith(value, other);
519            }
520        }
521    }
522
523    /// Gets the first use of this `BasicBlock` if any.
524    ///
525    /// The following example,
526    ///
527    /// ```no_run
528    /// use inkwell::AddressSpace;
529    /// use inkwell::context::Context;
530    /// use inkwell::values::BasicValue;
531    ///
532    /// let context = Context::create();
533    /// let module = context.create_module("ivs");
534    /// let builder = context.create_builder();
535    /// let void_type = context.void_type();
536    /// let fn_type = void_type.fn_type(&[], false);
537    /// let fn_val = module.add_function("my_fn", fn_type, None);
538    /// let entry = context.append_basic_block(fn_val, "entry");
539    /// let bb1 = context.append_basic_block(fn_val, "bb1");
540    /// let bb2 = context.append_basic_block(fn_val, "bb2");
541    /// builder.position_at_end(entry);
542    /// let branch_inst = builder.build_unconditional_branch(bb1);
543    ///
544    /// assert!(bb2.get_first_use().is_none());
545    /// assert!(bb1.get_first_use().is_some());
546    /// ```
547    pub fn get_first_use(self) -> Option<BasicValueUse<'ctx>> {
548        let use_ = unsafe { LLVMGetFirstUse(LLVMBasicBlockAsValue(self.basic_block)) };
549
550        if use_.is_null() {
551            return None;
552        }
553
554        unsafe { Some(BasicValueUse::new(use_)) }
555    }
556
557    /// Gets the address of this `BasicBlock` if possible. Returns `None` if `self` is the entry block to a function.
558    ///
559    /// # Safety
560    ///
561    /// The returned PointerValue may only be used for `call` and `indirect_branch` instructions
562    ///
563    /// # Example
564    ///
565    /// ```no_run
566    /// use inkwell::context::Context;
567    /// let context = Context::create();
568    /// let module = context.create_module("my_mod");
569    /// let void_type = context.void_type();
570    /// let fn_type = void_type.fn_type(&[], false);
571    /// let fn_val = module.add_function("my_fn", fn_type, None);
572    /// let entry_bb = context.append_basic_block(fn_val, "entry");
573    /// let next_bb = context.append_basic_block(fn_val, "next");
574    ///
575    /// assert!(unsafe { entry_bb.get_address() }.is_none());
576    /// assert!(unsafe { next_bb.get_address() }.is_some());
577    /// ```
578    pub unsafe fn get_address(self) -> Option<PointerValue<'ctx>> {
579        let parent = self.get_parent()?;
580
581        // Taking the address of the entry block is illegal.
582        self.get_previous_basic_block()?;
583
584        let value = PointerValue::new(LLVMBlockAddress(parent.as_value_ref(), self.basic_block));
585
586        if value.is_null() {
587            return None;
588        }
589
590        Some(value)
591    }
592}
593
594impl fmt::Debug for BasicBlock<'_> {
595    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
596        let llvm_value = unsafe { CStr::from_ptr(LLVMPrintValueToString(self.basic_block as LLVMValueRef)) };
597        let llvm_type = unsafe { CStr::from_ptr(LLVMPrintTypeToString(LLVMTypeOf(self.basic_block as LLVMValueRef))) };
598        let is_const = unsafe { LLVMIsConstant(self.basic_block as LLVMValueRef) == 1 };
599
600        f.debug_struct("BasicBlock")
601            .field("address", &self.basic_block)
602            .field("is_const", &is_const)
603            .field("llvm_value", &llvm_value)
604            .field("llvm_type", &llvm_type)
605            .finish()
606    }
607}
608
609/// Iterate over all `InstructionValue`s in a basic block.
610#[derive(Debug)]
611pub struct InstructionIter<'ctx>(Option<InstructionValue<'ctx>>);
612
613impl<'ctx> Iterator for InstructionIter<'ctx> {
614    type Item = InstructionValue<'ctx>;
615
616    fn next(&mut self) -> Option<Self::Item> {
617        if let Some(instr) = self.0 {
618            self.0 = instr.get_next_instruction();
619            Some(instr)
620        } else {
621            None
622        }
623    }
624}