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>
17class generic_bridge_gep_type_iterator : public std::iterator<std::forward_iterator_tag, Type*, ptrdiff_t>
18{
19
20 typedef std::iterator<std::forward_iterator_tag,Type*, ptrdiff_t> super;
21 ItTy OpIt;
22 PointerIntPair<Type*,1> CurTy;
23 unsigned AddrSpace;
25public:
26
27 static generic_bridge_gep_type_iterator begin(Type* Ty, ItTy It)
28 {
30 I.CurTy.setPointer(Ty);
31 I.OpIt = It;
32 return I;
33 }
34
36 ItTy It)
37 {
39 I.CurTy.setPointer(Ty);
40 I.CurTy.setInt(true);
42 I.OpIt = It;
43 return I;
44 }
45
47 {
49 I.OpIt = It;
50 return I;
51 }
52
54 {
55 return OpIt == x.OpIt;
56 }
57
59 {
60 return !operator==(x);
61 }
62
63 Type* operator*() const
64 {
65 if ( CurTy.getInt() )
66 return CurTy.getPointer()->getPointerTo(AddrSpace);
67 return CurTy.getPointer();
68 }
69
70 Type* getIndexedType() const
71 {
72 assert(false && "needs to be refactored");
73 if ( CurTy.getInt() )
74 return CurTy.getPointer();
75#if LLVM_VERSION_MAJOR >= 11
76 Type* CT = CurTy.getPointer();
77 if (auto ST = dyn_cast<StructType>(CT))
78 return ST->getTypeAtIndex(getOperand());
79 else if (auto Array = dyn_cast<ArrayType>(CT))
80 return Array->getElementType();
81 else if (auto Vector = dyn_cast<VectorType>(CT))
82 return Vector->getElementType();
83 else
84 return CT;
85#else
86 CompositeType *CT = llvm::cast<CompositeType>( CurTy.getPointer() );
87 return CT->getTypeAtIndex(getOperand());
88#endif
89 }
90
91 // non-standard operators, these may not need be bridged but seems it's
92 // prudent to do so...
93 Type* operator->() const
94 {
95 return operator*();
96 }
97
98 Value* getOperand() const
99 {
100 return const_cast<Value*>(&**OpIt);
101 }
102
103
105 {
106 if ( CurTy.getInt() )
107 {
108 CurTy.setInt(false);
109 }
110#if LLVM_VERSION_MAJOR >= 11
111 else if ( Type* CT = CurTy.getPointer() )
112 {
113 if (auto ST = dyn_cast<StructType>(CT))
114 CurTy.setPointer(ST->getTypeAtIndex(getOperand()));
115 else if (auto Array = dyn_cast<ArrayType>(CT))
116 CurTy.setPointer(Array->getElementType());
117 else if (auto Vector = dyn_cast<VectorType>(CT))
118 CurTy.setPointer(Vector->getElementType());
119 else
120 CurTy.setPointer(nullptr);
121 }
122#else
123 else if ( CompositeType * CT = dyn_cast<CompositeType>(CurTy.getPointer()) )
124 {
125 CurTy.setPointer(CT->getTypeAtIndex(getOperand()));
126 }
127#endif
128 else
129 {
130 CurTy.setPointer(nullptr);
131 }
132 ++OpIt;
133 return *this;
134 }
135
136
138 {
140 ++*this;
141 return tmp;
142 }
143
144};
145
146
148
150{
151 auto *GEPOp = llvm::cast<GEPOperator>(GEP);
152 return bridge_gep_iterator::begin(GEPOp->getSourceElementType(),
153 llvm::cast<PointerType>(GEPOp->getPointerOperandType()->getScalarType())->getAddressSpace(),
154 GEP->op_begin() + 1);
155}
156
157inline bridge_gep_iterator bridge_gep_end(const User* GEP)
158{
159 return bridge_gep_iterator::end(GEP->op_end());
160}
161
163{
164 auto &GEPOp = llvm::cast<GEPOperator>(GEP);
165 return bridge_gep_iterator::begin( GEPOp.getSourceElementType(),
166 llvm::cast<PointerType>(GEPOp.getPointerOperandType()->getScalarType())->getAddressSpace(),
167 GEP.op_begin() + 1);
168}
169
170inline bridge_gep_iterator bridge_gep_end(const User &GEP)
171{
172 return bridge_gep_iterator::end(GEP.op_end());
173}
174
175template<typename T>
176inline generic_bridge_gep_type_iterator<const T*> bridge_gep_end( Type* /*Op0*/, ArrayRef<T> A )
177{
179}
180
181} // End namespace llvm
182
183#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)
std::iterator< std::forward_iterator_tag, Type *, ptrdiff_t > super
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