1193323Sed//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This class implements an iterator to walk through the constants referenced by
11193323Sed// a method.  This is used by the Bitcode & Assembly writers to build constant
12193323Sed// pools.
13193323Sed//
14193323Sed//===----------------------------------------------------------------------===//
15193323Sed
16193323Sed#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H
17193323Sed#define LLVM_ANALYSIS_CONSTANTSSCANNER_H
18193323Sed
19193323Sed#include "llvm/Support/InstIterator.h"
20193323Sed
21193323Sednamespace llvm {
22193323Sed
23193323Sedclass Constant;
24193323Sed
25198090Srdivackyclass constant_iterator : public std::iterator<std::forward_iterator_tag,
26198090Srdivacky                                               const Constant, ptrdiff_t> {
27193323Sed  const_inst_iterator InstI;                // Method instruction iterator
28193323Sed  unsigned OpIdx;                           // Operand index
29193323Sed
30193323Sed  typedef constant_iterator _Self;
31193323Sed
32193323Sed  inline bool isAtConstant() const {
33193323Sed    assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
34193323Sed           "isAtConstant called with invalid arguments!");
35193323Sed    return isa<Constant>(InstI->getOperand(OpIdx));
36193323Sed  }
37193323Sed
38193323Sedpublic:
39193323Sed  inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
40193323Sed    // Advance to first constant... if we are not already at constant or end
41193323Sed    if (InstI != inst_end(F) &&                            // InstI is valid?
42193323Sed        (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
43193323Sed      operator++();
44193323Sed  }
45193323Sed
46193323Sed  inline constant_iterator(const Function *F, bool)   // end ctor
47193323Sed    : InstI(inst_end(F)), OpIdx(0) {
48193323Sed  }
49193323Sed
50193323Sed  inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
51193323Sed                                                        InstI == x.InstI; }
52193323Sed  inline bool operator!=(const _Self& x) const { return !operator==(x); }
53193323Sed
54193323Sed  inline pointer operator*() const {
55193323Sed    assert(isAtConstant() && "Dereferenced an iterator at the end!");
56193323Sed    return cast<Constant>(InstI->getOperand(OpIdx));
57193323Sed  }
58193323Sed  inline pointer operator->() const { return operator*(); }
59193323Sed
60193323Sed  inline _Self& operator++() {   // Preincrement implementation
61193323Sed    ++OpIdx;
62193323Sed    do {
63193323Sed      unsigned NumOperands = InstI->getNumOperands();
64193323Sed      while (OpIdx < NumOperands && !isAtConstant()) {
65193323Sed        ++OpIdx;
66193323Sed      }
67193323Sed
68193323Sed      if (OpIdx < NumOperands) return *this;  // Found a constant!
69193323Sed      ++InstI;
70193323Sed      OpIdx = 0;
71193323Sed    } while (!InstI.atEnd());
72193323Sed
73193323Sed    return *this;  // At the end of the method
74193323Sed  }
75193323Sed
76193323Sed  inline _Self operator++(int) { // Postincrement
77193323Sed    _Self tmp = *this; ++*this; return tmp;
78193323Sed  }
79193323Sed
80193323Sed  inline bool atEnd() const { return InstI.atEnd(); }
81193323Sed};
82193323Sed
83193323Sedinline constant_iterator constant_begin(const Function *F) {
84193323Sed  return constant_iterator(F);
85193323Sed}
86193323Sed
87193323Sedinline constant_iterator constant_end(const Function *F) {
88193323Sed  return constant_iterator(F, true);
89193323Sed}
90193323Sed
91193323Sed} // End llvm namespace
92193323Sed
93193323Sed#endif
94