]>
Commit | Line | Data |
---|---|---|
1a4d82fc | 1 | //===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===// |
223e47cc LB |
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 file implements an iterator for walking through the types indexed by | |
11 | // getelementptr instructions. | |
12 | // | |
13 | //===----------------------------------------------------------------------===// | |
14 | ||
1a4d82fc JJ |
15 | #ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H |
16 | #define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H | |
223e47cc | 17 | |
970d7e83 LB |
18 | #include "llvm/IR/DerivedTypes.h" |
19 | #include "llvm/IR/User.h" | |
223e47cc LB |
20 | |
21 | namespace llvm { | |
22 | template<typename ItTy = User::const_op_iterator> | |
23 | class generic_gep_type_iterator | |
24 | : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> { | |
25 | typedef std::iterator<std::forward_iterator_tag, | |
26 | Type *, ptrdiff_t> super; | |
27 | ||
28 | ItTy OpIt; | |
29 | Type *CurTy; | |
30 | generic_gep_type_iterator() {} | |
31 | public: | |
32 | ||
33 | static generic_gep_type_iterator begin(Type *Ty, ItTy It) { | |
34 | generic_gep_type_iterator I; | |
35 | I.CurTy = Ty; | |
36 | I.OpIt = It; | |
37 | return I; | |
38 | } | |
39 | static generic_gep_type_iterator end(ItTy It) { | |
40 | generic_gep_type_iterator I; | |
1a4d82fc | 41 | I.CurTy = nullptr; |
223e47cc LB |
42 | I.OpIt = It; |
43 | return I; | |
44 | } | |
45 | ||
46 | bool operator==(const generic_gep_type_iterator& x) const { | |
47 | return OpIt == x.OpIt; | |
48 | } | |
49 | bool operator!=(const generic_gep_type_iterator& x) const { | |
50 | return !operator==(x); | |
51 | } | |
52 | ||
53 | Type *operator*() const { | |
54 | return CurTy; | |
55 | } | |
56 | ||
57 | Type *getIndexedType() const { | |
58 | CompositeType *CT = cast<CompositeType>(CurTy); | |
59 | return CT->getTypeAtIndex(getOperand()); | |
60 | } | |
61 | ||
62 | // This is a non-standard operator->. It allows you to call methods on the | |
63 | // current type directly. | |
64 | Type *operator->() const { return operator*(); } | |
65 | ||
66 | Value *getOperand() const { return *OpIt; } | |
67 | ||
68 | generic_gep_type_iterator& operator++() { // Preincrement | |
69 | if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) { | |
70 | CurTy = CT->getTypeAtIndex(getOperand()); | |
71 | } else { | |
1a4d82fc | 72 | CurTy = nullptr; |
223e47cc LB |
73 | } |
74 | ++OpIt; | |
75 | return *this; | |
76 | } | |
77 | ||
78 | generic_gep_type_iterator operator++(int) { // Postincrement | |
79 | generic_gep_type_iterator tmp = *this; ++*this; return tmp; | |
80 | } | |
81 | }; | |
82 | ||
83 | typedef generic_gep_type_iterator<> gep_type_iterator; | |
84 | ||
85 | inline gep_type_iterator gep_type_begin(const User *GEP) { | |
970d7e83 LB |
86 | return gep_type_iterator::begin |
87 | (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1); | |
223e47cc LB |
88 | } |
89 | inline gep_type_iterator gep_type_end(const User *GEP) { | |
90 | return gep_type_iterator::end(GEP->op_end()); | |
91 | } | |
92 | inline gep_type_iterator gep_type_begin(const User &GEP) { | |
970d7e83 LB |
93 | return gep_type_iterator::begin |
94 | (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1); | |
223e47cc LB |
95 | } |
96 | inline gep_type_iterator gep_type_end(const User &GEP) { | |
97 | return gep_type_iterator::end(GEP.op_end()); | |
98 | } | |
99 | ||
100 | template<typename T> | |
101 | inline generic_gep_type_iterator<const T *> | |
102 | gep_type_begin(Type *Op0, ArrayRef<T> A) { | |
103 | return generic_gep_type_iterator<const T *>::begin(Op0, A.begin()); | |
104 | } | |
105 | ||
106 | template<typename T> | |
107 | inline generic_gep_type_iterator<const T *> | |
1a4d82fc | 108 | gep_type_end(Type * /*Op0*/, ArrayRef<T> A) { |
223e47cc LB |
109 | return generic_gep_type_iterator<const T *>::end(A.end()); |
110 | } | |
111 | } // end namespace llvm | |
112 | ||
113 | #endif |