ConstantsScanner.h revision 1e1de493949eac34bfd00d44c77364f3fbac9534
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
21namespace llvm {
22
23class Constant;
24
25class constant_iterator : public std::iterator<std::forward_iterator_tag, const Constant, ptrdiff_t> {
26  const_inst_iterator InstI;                // Method instruction iterator
27  unsigned OpIdx;                           // Operand index
28
29  typedef constant_iterator _Self;
30
31  inline bool isAtConstant() const {
32    assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
33           "isAtConstant called with invalid arguments!");
34    return isa<Constant>(InstI->getOperand(OpIdx));
35  }
36
37public:
38  inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
39    // Advance to first constant... if we are not already at constant or end
40    if (InstI != inst_end(F) &&                            // InstI is valid?
41        (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
42      operator++();
43  }
44
45  inline constant_iterator(const Function *F, bool)   // end ctor
46    : InstI(inst_end(F)), OpIdx(0) {
47  }
48
49  inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
50                                                        InstI == x.InstI; }
51  inline bool operator!=(const _Self& x) const { return !operator==(x); }
52
53  inline pointer operator*() const {
54    assert(isAtConstant() && "Dereferenced an iterator at the end!");
55    return cast<Constant>(InstI->getOperand(OpIdx));
56  }
57  inline pointer operator->() const { return operator*(); }
58
59  inline _Self& operator++() {   // Preincrement implementation
60    ++OpIdx;
61    do {
62      unsigned NumOperands = InstI->getNumOperands();
63      while (OpIdx < NumOperands && !isAtConstant()) {
64        ++OpIdx;
65      }
66
67      if (OpIdx < NumOperands) return *this;  // Found a constant!
68      ++InstI;
69      OpIdx = 0;
70    } while (!InstI.atEnd());
71
72    return *this;  // At the end of the method
73  }
74
75  inline _Self operator++(int) { // Postincrement
76    _Self tmp = *this; ++*this; return tmp;
77  }
78
79  inline bool atEnd() const { return InstI.atEnd(); }
80};
81
82inline constant_iterator constant_begin(const Function *F) {
83  return constant_iterator(F);
84}
85
86inline constant_iterator constant_end(const Function *F) {
87  return constant_iterator(F, true);
88}
89
90} // End llvm namespace
91
92#endif
93