11use ffi:: core;
22use ffi:: prelude:: LLVMBasicBlockRef ;
3+ use std:: iter:: { Iterator , DoubleEndedIterator , IntoIterator } ;
34use std:: marker:: PhantomData ;
45use std:: mem;
56use 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