aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Analysis/ConstantsScanner.h
blob: 9ea9ed6ce66cca1d0d19b205c88accfe17ef432c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and 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"
#include "llvm/Instruction.h"
#include "llvm/ADT/iterator"

namespace llvm {

class Constant;

class constant_iterator : public forward_iterator<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