1 //==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This class implements an iterator to walk through the constants referenced by 11 // a method. This is used by the Bitcode & Assembly writers to build constant 12 // pools. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H 17 #define LLVM_ANALYSIS_CONSTANTSSCANNER_H 18 19 #include "llvm/Support/InstIterator.h" 20 21 namespace llvm { 22 23 class Constant; 24 25 class constant_iterator : public std::iterator<std::forward_iterator_tag, 26 const Constant, ptrdiff_t> { 27 const_inst_iterator InstI; // Method instruction iterator 28 unsigned OpIdx; // Operand index 29 30 typedef constant_iterator _Self; 31 32 inline bool isAtConstant() const { 33 assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() && 34 "isAtConstant called with invalid arguments!"); 35 return isa<Constant>(InstI->getOperand(OpIdx)); 36 } 37 38 public: 39 inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) { 40 // Advance to first constant... if we are not already at constant or end 41 if (InstI != inst_end(F) && // InstI is valid? 42 (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant? 43 operator++(); 44 } 45 46 inline constant_iterator(const Function *F, bool) // end ctor 47 : InstI(inst_end(F)), OpIdx(0) { 48 } 49 50 inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx && 51 InstI == x.InstI; } 52 inline bool operator!=(const _Self& x) const { return !operator==(x); } 53 54 inline pointer operator*() const { 55 assert(isAtConstant() && "Dereferenced an iterator at the end!"); 56 return cast<Constant>(InstI->getOperand(OpIdx)); 57 } 58 inline pointer operator->() const { return operator*(); } 59 60 inline _Self& operator++() { // Preincrement implementation 61 ++OpIdx; 62 do { 63 unsigned NumOperands = InstI->getNumOperands(); 64 while (OpIdx < NumOperands && !isAtConstant()) { 65 ++OpIdx; 66 } 67 68 if (OpIdx < NumOperands) return *this; // Found a constant! 69 ++InstI; 70 OpIdx = 0; 71 } while (!InstI.atEnd()); 72 73 return *this; // At the end of the method 74 } 75 76 inline _Self operator++(int) { // Postincrement 77 _Self tmp = *this; ++*this; return tmp; 78 } 79 80 inline bool atEnd() const { return InstI.atEnd(); } 81 }; 82 83 inline constant_iterator constant_begin(const Function *F) { 84 return constant_iterator(F); 85 } 86 87 inline constant_iterator constant_end(const Function *F) { 88 return constant_iterator(F, true); 89 } 90 91 } // End llvm namespace 92 93 #endif 94