Static Value-Flow Analysis
Loading...
Searching...
No Matches
GEPTypeBridgeIterator.h
Go to the documentation of this file.
1// GEPTypeBridgeIterator
2//
3//
4#ifndef SVF_GEPTYPEBRIDGEITERATOR_H
5#define SVF_GEPTYPEBRIDGEITERATOR_H
6
7#include "llvm/IR/DerivedTypes.h"
8#include "llvm/IR/Operator.h"
9#include "llvm/IR/User.h"
10#include "llvm/ADT/PointerIntPair.h"
11#include "llvm/IR/GetElementPtrTypeIterator.h"
12
13namespace llvm
14{
15
16template<typename ItTy = User::const_op_iterator>
18{
19
20 ItTy OpIt;
21 PointerIntPair<Type*,1> CurTy;
22 unsigned AddrSpace;
24public:
25 using iterator_category = std::forward_iterator_tag;
26 using value_type = Type*;
27 using difference_type = ptrdiff_t;
28 using pointer = Type**;
29 using reference = Type*&;
30
31 static generic_bridge_gep_type_iterator begin(Type* Ty, ItTy It)
32 {
34 I.CurTy.setPointer(Ty);
35 I.OpIt = It;
36 return I;
37 }
38
40 ItTy It)
41 {
43 I.CurTy.setPointer(Ty);
44 I.CurTy.setInt(true);
46 I.OpIt = It;
47 return I;
48 }
49
51 {
53 I.OpIt = It;
54 return I;
55 }
56
58 {
59 return OpIt == x.OpIt;
60 }
61
63 {
64 return !operator==(x);
65 }
66
67 Type* operator*() const
68 {
69 if ( CurTy.getInt() )
70 return PointerType::get(CurTy.getPointer()->getContext(), AddrSpace);
71 return CurTy.getPointer();
72 }
73
74 Type* getIndexedType() const
75 {
76 assert(false && "needs to be refactored");
77 if ( CurTy.getInt() )
78 return CurTy.getPointer();
79 Type* CT = CurTy.getPointer();
80 if (auto ST = dyn_cast<StructType>(CT))
81 return ST->getTypeAtIndex(getOperand());
82 else if (auto Array = dyn_cast<ArrayType>(CT))
83 return Array->getElementType();
84 else if (auto Vector = dyn_cast<VectorType>(CT))
85 return Vector->getElementType();
86 else
87 return CT;
88 }
89
90// non-standard operators, these may not need be bridged but seems it's
91// prudent to do so...
92 Type* operator->() const
93 {
94 return operator*();
95 }
96
97 Value* getOperand() const
98 {
99 return const_cast<Value*>(&**OpIt);
100 }
101
102
104 {
105 if ( CurTy.getInt() )
106 {
107 CurTy.setInt(false);
108 }
109 else if ( Type* CT = CurTy.getPointer() )
110 {
111 if (auto ST = dyn_cast<StructType>(CT))
112 CurTy.setPointer(ST->getTypeAtIndex(getOperand()));
113 else if (auto Array = dyn_cast<ArrayType>(CT))
114 CurTy.setPointer(Array->getElementType());
115 else if (auto Vector = dyn_cast<VectorType>(CT))
116 CurTy.setPointer(Vector->getElementType());
117 else
118 CurTy.setPointer(nullptr);
119 }
120 else
121 {
122 CurTy.setPointer(nullptr);
123 }
124 ++OpIt;
125 return *this;
126 }
127
128
130 {
132 ++*this;
133 return tmp;
134 }
135
136};
137
138
140
142{
143 auto *GEPOp = llvm::cast<GEPOperator>(GEP);
144 return bridge_gep_iterator::begin(GEPOp->getSourceElementType(),
145 llvm::cast<PointerType>(GEPOp->getPointerOperandType()->getScalarType())->getAddressSpace(),
146 GEP->op_begin() + 1);
147}
148
149inline bridge_gep_iterator bridge_gep_end(const User* GEP)
150{
151 return bridge_gep_iterator::end(GEP->op_end());
152}
153
155{
156 auto &GEPOp = llvm::cast<GEPOperator>(GEP);
157 return bridge_gep_iterator::begin( GEPOp.getSourceElementType(),
158 llvm::cast<PointerType>(GEPOp.getPointerOperandType()->getScalarType())->getAddressSpace(),
159 GEP.op_begin() + 1);
160}
161
162inline bridge_gep_iterator bridge_gep_end(const User &GEP)
163{
164 return bridge_gep_iterator::end(GEP.op_end());
165}
166
167template<typename T>
168inline generic_bridge_gep_type_iterator<const T*> bridge_gep_end( Type* /*Op0*/, ArrayRef<T> A )
169{
171}
172
173} // End namespace llvm
174
175#endif
bool operator==(const generic_bridge_gep_type_iterator &x) const
static generic_bridge_gep_type_iterator begin(Type *Ty, unsigned AddrSpace, ItTy It)
static generic_bridge_gep_type_iterator end(ItTy It)
generic_bridge_gep_type_iterator operator++(int)
generic_bridge_gep_type_iterator & operator++()
static generic_bridge_gep_type_iterator begin(Type *Ty, ItTy It)
bool operator!=(const generic_bridge_gep_type_iterator &x) const
bridge_gep_iterator bridge_gep_end(const User *GEP)
bridge_gep_iterator bridge_gep_begin(const User *GEP)
generic_bridge_gep_type_iterator bridge_gep_iterator