Change references to the Method class to be references to the Function
[oota-llvm.git] / include / llvm / Support / InstIterator.h
1 //===-- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*--=//
2 //
3 // This file contains definitions of two iterators for iterating over the
4 // instructions in a function.  This is effectively a wrapper around a two level
5 // iterator that can probably be genericized later.
6 //
7 // Note that this iterator gets invalidated any time that basic blocks or
8 // instructions are moved around.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #ifndef LLVM_INST_ITERATOR_H
13 #define LLVM_INST_ITERATOR_H
14
15 #include "llvm/BasicBlock.h"
16 #include "llvm/Function.h"
17
18 // This class is implements inst_begin() & inst_end() for
19 // inst_iterator and const_inst_iterator's.
20 //
21 template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
22 class InstIterator {
23   typedef _BB_t   BBty;
24   typedef _BB_i_t BBIty;
25   typedef _BI_t   BIty;
26   typedef _II_t   IIty;
27   _BB_t  &BBs;      // BasicBlocksType
28   _BB_i_t BB;       // BasicBlocksType::iterator
29   _BI_t   BI;       // BasicBlock::iterator
30 public:
31   typedef std::bidirectional_iterator_tag iterator_category;
32   typedef IIty                            value_type;
33   typedef unsigned                        difference_type;
34   typedef BIty                            pointer;
35   typedef IIty                            reference;
36   
37   template<class M> InstIterator(M &m) 
38     : BBs(m.getBasicBlocks()), BB(BBs.begin()) {    // begin ctor
39     if (BB != BBs.end()) {
40       BI = (*BB)->begin();
41       advanceToNextBB();
42     }
43   }
44
45   template<class M> InstIterator(M &m, bool) 
46     : BBs(m.getBasicBlocks()), BB(BBs.end()) {    // end ctor
47   }
48
49   // Accessors to get at the underlying iterators...
50   inline BBIty &getBasicBlockIterator()  { return BB; }
51   inline BIty  &getInstructionIterator() { return BI; }
52   
53   inline IIty operator*()  const { return *BI; }
54   inline IIty operator->() const { return operator*(); }
55   
56   inline bool operator==(const InstIterator &y) const { 
57     return BB == y.BB && (BB == BBs.end() || BI == y.BI);
58   }
59   inline bool operator!=(const InstIterator& y) const { 
60     return !operator==(y);
61   }
62
63   InstIterator& operator++() { 
64     ++BI;
65     advanceToNextBB();
66     return *this; 
67   }
68   inline InstIterator operator++(int) { 
69     InstIterator tmp = *this; ++*this; return tmp; 
70   }
71     
72   InstIterator& operator--() { 
73     while (BB == BBs.end() || BI == (*BB)->begin()) {
74       --BB;
75       BI = (*BB)->end();
76     }
77     --BI;
78     return *this; 
79   }
80   inline InstIterator  operator--(int) { 
81     InstIterator tmp = *this; --*this; return tmp; 
82   }
83
84   inline bool atEnd() const { return BB == BBs.end(); }
85
86 private:
87   inline void advanceToNextBB() {
88     // The only way that the II could be broken is if it is now pointing to
89     // the end() of the current BasicBlock and there are successor BBs.
90     while (BI == (*BB)->end()) {
91       ++BB;
92       if (BB == BBs.end()) break;
93       BI = (*BB)->begin();
94     }
95   }
96 };
97
98
99 typedef InstIterator<ValueHolder<BasicBlock, Function, Function>,
100                      Function::iterator, BasicBlock::iterator,
101                      Instruction*> inst_iterator;
102 typedef InstIterator<const ValueHolder<BasicBlock, Function, Function>,
103                      Function::const_iterator, 
104                      BasicBlock::const_iterator,
105                      const Instruction*> const_inst_iterator;
106
107 inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
108 inline inst_iterator inst_end(Function *F)   { return inst_iterator(*F, true); }
109 inline const_inst_iterator inst_begin(const Function *F) {
110   return const_inst_iterator(*F);
111 }
112 inline const_inst_iterator inst_end(const Function *F) {
113   return const_inst_iterator(*F, true);
114 }
115
116 #endif