|  | //===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file contains definitions of two iterators for iterating over the | 
|  | // instructions in a function.  This is effectively a wrapper around a two level | 
|  | // iterator that can probably be genericized later. | 
|  | // | 
|  | // Note that this iterator gets invalidated any time that basic blocks or | 
|  | // instructions are moved around. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_SUPPORT_INSTITERATOR_H | 
|  | #define LLVM_SUPPORT_INSTITERATOR_H | 
|  |  | 
|  | #include "llvm/BasicBlock.h" | 
|  | #include "llvm/Function.h" | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | // This class implements inst_begin() & inst_end() for | 
|  | // inst_iterator and const_inst_iterator's. | 
|  | // | 
|  | template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t> | 
|  | class InstIterator { | 
|  | typedef _BB_t   BBty; | 
|  | typedef _BB_i_t BBIty; | 
|  | typedef _BI_t   BIty; | 
|  | typedef _II_t   IIty; | 
|  | _BB_t  *BBs;      // BasicBlocksType | 
|  | _BB_i_t BB;       // BasicBlocksType::iterator | 
|  | _BI_t   BI;       // BasicBlock::iterator | 
|  | public: | 
|  | typedef std::bidirectional_iterator_tag iterator_category; | 
|  | typedef IIty                            value_type; | 
|  | typedef signed                        difference_type; | 
|  | typedef IIty*                           pointer; | 
|  | typedef IIty&                           reference; | 
|  |  | 
|  | // Default constructor | 
|  | InstIterator() {} | 
|  |  | 
|  | // Copy constructor... | 
|  | template<typename A, typename B, typename C, typename D> | 
|  | InstIterator(const InstIterator<A,B,C,D> &II) | 
|  | : BBs(II.BBs), BB(II.BB), BI(II.BI) {} | 
|  |  | 
|  | template<typename A, typename B, typename C, typename D> | 
|  | InstIterator(InstIterator<A,B,C,D> &II) | 
|  | : BBs(II.BBs), BB(II.BB), BI(II.BI) {} | 
|  |  | 
|  | template<class M> InstIterator(M &m) | 
|  | : BBs(&m.getBasicBlockList()), BB(BBs->begin()) {    // begin ctor | 
|  | if (BB != BBs->end()) { | 
|  | BI = BB->begin(); | 
|  | advanceToNextBB(); | 
|  | } | 
|  | } | 
|  |  | 
|  | template<class M> InstIterator(M &m, bool) | 
|  | : BBs(&m.getBasicBlockList()), BB(BBs->end()) {    // end ctor | 
|  | } | 
|  |  | 
|  | // Accessors to get at the underlying iterators... | 
|  | inline BBIty &getBasicBlockIterator()  { return BB; } | 
|  | inline BIty  &getInstructionIterator() { return BI; } | 
|  |  | 
|  | inline reference operator*()  const { return *BI; } | 
|  | inline pointer operator->() const { return &operator*(); } | 
|  |  | 
|  | inline bool operator==(const InstIterator &y) const { | 
|  | return BB == y.BB && (BB == BBs->end() || BI == y.BI); | 
|  | } | 
|  | inline bool operator!=(const InstIterator& y) const { | 
|  | return !operator==(y); | 
|  | } | 
|  |  | 
|  | InstIterator& operator++() { | 
|  | ++BI; | 
|  | advanceToNextBB(); | 
|  | return *this; | 
|  | } | 
|  | inline InstIterator operator++(int) { | 
|  | InstIterator tmp = *this; ++*this; return tmp; | 
|  | } | 
|  |  | 
|  | InstIterator& operator--() { | 
|  | while (BB == BBs->end() || BI == BB->begin()) { | 
|  | --BB; | 
|  | BI = BB->end(); | 
|  | } | 
|  | --BI; | 
|  | return *this; | 
|  | } | 
|  | inline InstIterator  operator--(int) { | 
|  | InstIterator tmp = *this; --*this; return tmp; | 
|  | } | 
|  |  | 
|  | inline bool atEnd() const { return BB == BBs->end(); } | 
|  |  | 
|  | private: | 
|  | inline void advanceToNextBB() { | 
|  | // The only way that the II could be broken is if it is now pointing to | 
|  | // the end() of the current BasicBlock and there are successor BBs. | 
|  | while (BI == BB->end()) { | 
|  | ++BB; | 
|  | if (BB == BBs->end()) break; | 
|  | BI = BB->begin(); | 
|  | } | 
|  | } | 
|  | }; | 
|  |  | 
|  |  | 
|  | typedef InstIterator<iplist<BasicBlock>, | 
|  | Function::iterator, BasicBlock::iterator, | 
|  | Instruction> inst_iterator; | 
|  | typedef InstIterator<const iplist<BasicBlock>, | 
|  | Function::const_iterator, | 
|  | BasicBlock::const_iterator, | 
|  | const Instruction> const_inst_iterator; | 
|  |  | 
|  | inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); } | 
|  | inline inst_iterator inst_end(Function *F)   { return inst_iterator(*F, true); } | 
|  | inline const_inst_iterator inst_begin(const Function *F) { | 
|  | return const_inst_iterator(*F); | 
|  | } | 
|  | inline const_inst_iterator inst_end(const Function *F) { | 
|  | return const_inst_iterator(*F, true); | 
|  | } | 
|  | inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); } | 
|  | inline inst_iterator inst_end(Function &F)   { return inst_iterator(F, true); } | 
|  | inline const_inst_iterator inst_begin(const Function &F) { | 
|  | return const_inst_iterator(F); | 
|  | } | 
|  | inline const_inst_iterator inst_end(const Function &F) { | 
|  | return const_inst_iterator(F, true); | 
|  | } | 
|  |  | 
|  | } // End llvm namespace | 
|  |  | 
|  | #endif |