LLVM API Documentation

ConstantsScanner.h
Go to the documentation of this file.
00001 //==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // 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 Bitcode & 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/IR/InstIterator.h"
00020 
00021 namespace llvm {
00022 
00023 class Constant;
00024 
00025 class constant_iterator : public std::iterator<std::forward_iterator_tag,
00026                                                const Constant, ptrdiff_t> {
00027   const_inst_iterator InstI;                // Method instruction iterator
00028   unsigned OpIdx;                           // Operand index
00029 
00030   typedef constant_iterator _Self;
00031 
00032   inline bool isAtConstant() const {
00033     assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
00034            "isAtConstant called with invalid arguments!");
00035     return isa<Constant>(InstI->getOperand(OpIdx));
00036   }
00037 
00038 public:
00039   inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
00040     // Advance to first constant... if we are not already at constant or end
00041     if (InstI != inst_end(F) &&                            // InstI is valid?
00042         (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
00043       operator++();
00044   }
00045 
00046   inline constant_iterator(const Function *F, bool)   // end ctor
00047     : InstI(inst_end(F)), OpIdx(0) {
00048   }
00049 
00050   inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
00051                                                         InstI == x.InstI; }
00052   inline bool operator!=(const _Self& x) const { return !operator==(x); }
00053 
00054   inline pointer operator*() const {
00055     assert(isAtConstant() && "Dereferenced an iterator at the end!");
00056     return cast<Constant>(InstI->getOperand(OpIdx));
00057   }
00058   inline pointer operator->() const { return operator*(); }
00059 
00060   inline _Self& operator++() {   // Preincrement implementation
00061     ++OpIdx;
00062     do {
00063       unsigned NumOperands = InstI->getNumOperands();
00064       while (OpIdx < NumOperands && !isAtConstant()) {
00065         ++OpIdx;
00066       }
00067 
00068       if (OpIdx < NumOperands) return *this;  // Found a constant!
00069       ++InstI;
00070       OpIdx = 0;
00071     } while (!InstI.atEnd());
00072 
00073     return *this;  // At the end of the method
00074   }
00075 
00076   inline _Self operator++(int) { // Postincrement
00077     _Self tmp = *this; ++*this; return tmp;
00078   }
00079 
00080   inline bool atEnd() const { return InstI.atEnd(); }
00081 };
00082 
00083 inline constant_iterator constant_begin(const Function *F) {
00084   return constant_iterator(F);
00085 }
00086 
00087 inline constant_iterator constant_end(const Function *F) {
00088   return constant_iterator(F, true);
00089 }
00090 
00091 } // End llvm namespace
00092 
00093 #endif