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#if LLVM_VERSION_MAJOR >= 11
80 Type* CT = CurTy.getPointer();
81 if (auto ST = dyn_cast<StructType>(CT))
82 return ST->getTypeAtIndex(getOperand());
83 else if (auto Array = dyn_cast<ArrayType>(CT))
84 return Array->getElementType();
85 else if (auto Vector = dyn_cast<VectorType>(CT))
86 return Vector->getElementType();
87 else
88 return CT;
89#else
90 CompositeType *CT = llvm::cast<CompositeType>( CurTy.getPointer() );
91 return CT->getTypeAtIndex(getOperand());
92#endif
93 }
94
95 // non-standard operators, these may not need be bridged but seems it's
96 // prudent to do so...
97 Type* operator->() const
98 {
99 return operator*();
100 }
101
102 Value* getOperand() const
103 {
104 return const_cast<Value*>(&**OpIt);
105 }
106
107
109 {
110 if ( CurTy.getInt() )
111 {
112 CurTy.setInt(false);
113 }
114#if LLVM_VERSION_MAJOR >= 11
115 else if ( Type* CT = CurTy.getPointer() )
116 {
117 if (auto ST = dyn_cast<StructType>(CT))
118 CurTy.setPointer(ST->getTypeAtIndex(getOperand()));
119 else if (auto Array = dyn_cast<ArrayType>(CT))
120 CurTy.setPointer(Array->getElementType());
121 else if (auto Vector = dyn_cast<VectorType>(CT))
122 CurTy.setPointer(Vector->getElementType());
123 else
124 CurTy.setPointer(nullptr);
125 }
126#else
127 else if ( CompositeType * CT = dyn_cast<CompositeType>(CurTy.getPointer()) )
128 {
129 CurTy.setPointer(CT->getTypeAtIndex(getOperand()));
130 }
131#endif
132 else
133 {
134 CurTy.setPointer(nullptr);
135 }
136 ++OpIt;
137 return *this;
138 }
139
140
142 {
144 ++*this;
145 return tmp;
146 }
147
148};
149
150
152
154{
155 auto *GEPOp = llvm::cast<GEPOperator>(GEP);
156 return bridge_gep_iterator::begin(GEPOp->getSourceElementType(),
157 llvm::cast<PointerType>(GEPOp->getPointerOperandType()->getScalarType())->getAddressSpace(),
158 GEP->op_begin() + 1);
159}
160
161inline bridge_gep_iterator bridge_gep_end(const User* GEP)
162{
163 return bridge_gep_iterator::end(GEP->op_end());
164}
165
167{
168 auto &GEPOp = llvm::cast<GEPOperator>(GEP);
169 return bridge_gep_iterator::begin( GEPOp.getSourceElementType(),
170 llvm::cast<PointerType>(GEPOp.getPointerOperandType()->getScalarType())->getAddressSpace(),
171 GEP.op_begin() + 1);
172}
173
174inline bridge_gep_iterator bridge_gep_end(const User &GEP)
175{
176 return bridge_gep_iterator::end(GEP.op_end());
177}
178
179template<typename T>
180inline generic_bridge_gep_type_iterator<const T*> bridge_gep_end( Type* /*Op0*/, ArrayRef<T> A )
181{
183}
184
185} // End namespace llvm
186
187#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