//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class implements an iterator to walk through the constants referenced by
// a method.  This is used by the Bitcode & Assembly writers to build constant
// pools.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H
#define LLVM_ANALYSIS_CONSTANTSSCANNER_H

#include "llvm/Support/InstIterator.h"

namespace llvm {

class Constant;

class constant_iterator : public std::iterator<std::forward_iterator_tag,
                                               const Constant, ptrdiff_t> {
  const_inst_iterator InstI;                // Method instruction iterator
  unsigned OpIdx;                           // Operand index

  typedef constant_iterator _Self;

  inline bool isAtConstant() const {
    assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
           "isAtConstant called with invalid arguments!");
    return isa<Constant>(InstI->getOperand(OpIdx));
  }

public:
  inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
    // Advance to first constant... if we are not already at constant or end
    if (InstI != inst_end(F) &&                            // InstI is valid?
        (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
      operator++();
  }

  inline constant_iterator(const Function *F, bool)   // end ctor
    : InstI(inst_end(F)), OpIdx(0) {
  }

  inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
                                                        InstI == x.InstI; }
  inline bool operator!=(const _Self& x) const { return !operator==(x); }

  inline pointer operator*() const {
    assert(isAtConstant() && "Dereferenced an iterator at the end!");
    return cast<Constant>(InstI->getOperand(OpIdx));
  }
  inline pointer operator->() const { return operator*(); }

  inline _Self& operator++() {   // Preincrement implementation
    ++OpIdx;
    do {
      unsigned NumOperands = InstI->getNumOperands();
      while (OpIdx < NumOperands && !isAtConstant()) {
        ++OpIdx;
      }

      if (OpIdx < NumOperands) return *this;  // Found a constant!
      ++InstI;
      OpIdx = 0;
    } while (!InstI.atEnd());

    return *this;  // At the end of the method
  }

  inline _Self operator++(int) { // Postincrement
    _Self tmp = *this; ++*this; return tmp;
  }

  inline bool atEnd() const { return InstI.atEnd(); }
};

inline constant_iterator constant_begin(const Function *F) {
  return constant_iterator(F);
}

inline constant_iterator constant_end(const Function *F) {
  return constant_iterator(F, true);
}

} // End llvm namespace

#endif
