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