| //===- 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 |