Home | History | Annotate | Download | only in Analysis
      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