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}