1
1
use ffi:: core;
2
2
use ffi:: prelude:: LLVMBasicBlockRef ;
3
+ use std:: iter:: { Iterator , DoubleEndedIterator , IntoIterator } ;
3
4
use std:: marker:: PhantomData ;
4
5
use std:: mem;
5
6
use value:: { Function , Value } ;
@@ -60,3 +61,47 @@ impl BasicBlock {
60
61
core:: LLVMDeleteBasicBlock ( self . into ( ) )
61
62
}
62
63
}
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