Static Value-Flow Analysis
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 
13 namespace llvm
14 {
15 
16 template<typename ItTy = User::const_op_iterator>
17 class 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;
25 public:
26 
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);
41  I.AddrSpace = AddrSpace;
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 
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 
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 
171 {
172  return bridge_gep_iterator::end(GEP.op_end());
173 }
174 
175 template<typename T>
177 {
179 }
180 
181 } // End namespace llvm
182 
183 #endif
bool operator==(const generic_bridge_gep_type_iterator &x) const
generic_bridge_gep_type_iterator & operator++()
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)
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
llvm::Type Type
Definition: BasicTypes.h:83
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82
llvm::User User
Definition: BasicTypes.h:142
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