diff options
Diffstat (limited to 'clang-r353983/include/llvm/IR/InstIterator.h')
| -rw-r--r-- | clang-r353983/include/llvm/IR/InstIterator.h | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/clang-r353983/include/llvm/IR/InstIterator.h b/clang-r353983/include/llvm/IR/InstIterator.h new file mode 100644 index 00000000..054fe4e9 --- /dev/null +++ b/clang-r353983/include/llvm/IR/InstIterator.h @@ -0,0 +1,162 @@ +//===- InstIterator.h - Classes for inst iteration --------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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_IR_INSTITERATOR_H +#define LLVM_IR_INSTITERATOR_H + +#include "llvm/ADT/iterator_range.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/SymbolTableListTraits.h" +#include <iterator> + +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 { + using BBty = BB_t; + using BBIty = BB_i_t; + using BIty = BI_t; + using IIty = II_t; + BB_t *BBs; // BasicBlocksType + BB_i_t BB; // BasicBlocksType::iterator + BI_t BI; // BasicBlock::iterator + +public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = IIty; + using difference_type = signed; + using pointer = IIty *; + using reference = IIty &; + + // Default constructor + InstIterator() = default; + + // 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(); + } + } +}; + +using inst_iterator = + InstIterator<SymbolTableList<BasicBlock>, Function::iterator, + BasicBlock::iterator, Instruction>; +using const_inst_iterator = + InstIterator<const SymbolTableList<BasicBlock>, + Function::const_iterator, BasicBlock::const_iterator, + const Instruction>; +using inst_range = iterator_range<inst_iterator>; +using const_inst_range = iterator_range<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 inst_range instructions(Function *F) { + return inst_range(inst_begin(F), inst_end(F)); +} +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 const_inst_range instructions(const Function *F) { + return const_inst_range(inst_begin(F), inst_end(F)); +} +inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); } +inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); } +inline inst_range instructions(Function &F) { + return inst_range(inst_begin(F), inst_end(F)); +} +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 const_inst_range instructions(const Function &F) { + return const_inst_range(inst_begin(F), inst_end(F)); +} + +} // end namespace llvm + +#endif // LLVM_IR_INSTITERATOR_H |
