LLVM API Documentation
00001 //==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This class implements an iterator to walk through the constants referenced by 00011 // a method. This is used by the Bytecode & Assembly writers to build constant 00012 // pools. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H 00017 #define LLVM_ANALYSIS_CONSTANTSSCANNER_H 00018 00019 #include "llvm/Support/InstIterator.h" 00020 #include "llvm/Instruction.h" 00021 #include "llvm/ADT/iterator" 00022 00023 namespace llvm { 00024 00025 class Constant; 00026 00027 class constant_iterator : public forward_iterator<const Constant, ptrdiff_t> { 00028 const_inst_iterator InstI; // Method instruction iterator 00029 unsigned OpIdx; // Operand index 00030 00031 typedef constant_iterator _Self; 00032 00033 inline bool isAtConstant() const { 00034 assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() && 00035 "isAtConstant called with invalid arguments!"); 00036 return isa<Constant>(InstI->getOperand(OpIdx)); 00037 } 00038 00039 public: 00040 inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) { 00041 // Advance to first constant... if we are not already at constant or end 00042 if (InstI != inst_end(F) && // InstI is valid? 00043 (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant? 00044 operator++(); 00045 } 00046 00047 inline constant_iterator(const Function *F, bool) // end ctor 00048 : InstI(inst_end(F)), OpIdx(0) { 00049 } 00050 00051 inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx && 00052 InstI == x.InstI; } 00053 inline bool operator!=(const _Self& x) const { return !operator==(x); } 00054 00055 inline pointer operator*() const { 00056 assert(isAtConstant() && "Dereferenced an iterator at the end!"); 00057 return cast<Constant>(InstI->getOperand(OpIdx)); 00058 } 00059 inline pointer operator->() const { return operator*(); } 00060 00061 inline _Self& operator++() { // Preincrement implementation 00062 ++OpIdx; 00063 do { 00064 unsigned NumOperands = InstI->getNumOperands(); 00065 while (OpIdx < NumOperands && !isAtConstant()) { 00066 ++OpIdx; 00067 } 00068 00069 if (OpIdx < NumOperands) return *this; // Found a constant! 00070 ++InstI; 00071 OpIdx = 0; 00072 } while (!InstI.atEnd()); 00073 00074 return *this; // At the end of the method 00075 } 00076 00077 inline _Self operator++(int) { // Postincrement 00078 _Self tmp = *this; ++*this; return tmp; 00079 } 00080 00081 inline bool atEnd() const { return InstI.atEnd(); } 00082 }; 00083 00084 inline constant_iterator constant_begin(const Function *F) { 00085 return constant_iterator(F); 00086 } 00087 00088 inline constant_iterator constant_end(const Function *F) { 00089 return constant_iterator(F, true); 00090 } 00091 00092 } // End llvm namespace 00093 00094 #endif