Skip to content

Commit e1fb4b4

Browse files
committed
Add block iterator
1 parent f8e80ee commit e1fb4b4

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

src/block.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use ffi::core;
22
use ffi::prelude::LLVMBasicBlockRef;
3+
use std::iter::{Iterator, DoubleEndedIterator, IntoIterator};
34
use std::marker::PhantomData;
45
use std::mem;
56
use value::{Function, Value};
@@ -60,3 +61,47 @@ impl BasicBlock {
6061
core::LLVMDeleteBasicBlock(self.into())
6162
}
6263
}
64+
65+
/// Iterates through all the blocks contained in a function.
66+
pub struct BlockIter<'a> {
67+
pub min: &'a BasicBlock,
68+
pub max: &'a BasicBlock
69+
}
70+
71+
impl<'a> IntoIterator for &'a Function {
72+
type IntoIter = BlockIter<'a>;
73+
type Item = &'a BasicBlock;
74+
fn into_iter(self) -> BlockIter<'a> {
75+
BlockIter {
76+
min: unsafe { core::LLVMGetFirstBasicBlock(self.into()).into() },
77+
max: unsafe { core::LLVMGetLastBasicBlock(self.into()).into() }
78+
}
79+
}
80+
}
81+
impl<'a> Iterator for BlockIter<'a> {
82+
type Item = &'a BasicBlock;
83+
fn next(&mut self) -> Option<&'a BasicBlock> {
84+
if self.min == self.max {
85+
None
86+
} else {
87+
unsafe {
88+
let _block = self.min;
89+
self.min = core::LLVMGetNextBasicBlock(self.min.into()).into();
90+
Some(_block)
91+
}
92+
}
93+
}
94+
}
95+
impl<'a> DoubleEndedIterator for BlockIter<'a> {
96+
fn next_back(&mut self) -> Option<&'a BasicBlock> {
97+
if self.min == self.max {
98+
None
99+
} else {
100+
unsafe {
101+
let _block = self.max;
102+
self.max = core::LLVMGetPreviousBasicBlock(self.max.into()).into();
103+
Some(_block)
104+
}
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)