klee
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GetElementPtrTypeIterator.h
Go to the documentation of this file.
1 //===- klee/util/GetElementPtrTypeIterator.h --------------------*- C++ -*-===//
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, insertvalue and extractvalue instructions.
12 //
13 // It is an enhanced version of llvm::gep_type_iterator which only handles
14 // getelementptr.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef KLEE_UTIL_GETELEMENTPTRTYPE_H
19 #define KLEE_UTIL_GETELEMENTPTRTYPE_H
20 
21 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
22 #include "llvm/IR/User.h"
23 #include "llvm/IR/DerivedTypes.h"
24 #include "llvm/IR/Instructions.h"
25 #include "llvm/IR/Constants.h"
26 #else
27 #include "llvm/User.h"
28 #include "llvm/DerivedTypes.h"
29 #include "llvm/Instructions.h"
30 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 0)
31 #include "llvm/Constants.h"
32 #endif
33 #endif
34 
35 #include "klee/Config/Version.h"
36 
37 namespace klee {
38  template<typename ItTy = llvm::User::const_op_iterator>
40  : public std::iterator<std::forward_iterator_tag,
41  LLVM_TYPE_Q llvm::Type *, ptrdiff_t> {
42  typedef std::iterator<std::forward_iterator_tag,
43  LLVM_TYPE_Q llvm::Type *, ptrdiff_t> super;
44 
45  ItTy OpIt;
46  LLVM_TYPE_Q llvm::Type *CurTy;
48 
49  llvm::Value *asValue(llvm::Value *V) const { return V; }
50  llvm::Value *asValue(unsigned U) const {
51  return llvm::ConstantInt::get(CurTy->getContext(), llvm::APInt(32, U));
52  }
53 
54  public:
55 
57  ItTy It) {
59  I.CurTy = Ty;
60  I.OpIt = It;
61  return I;
62  }
63  static generic_gep_type_iterator end(ItTy It) {
65  I.CurTy = 0;
66  I.OpIt = It;
67  return I;
68  }
69 
70  bool operator==(const generic_gep_type_iterator& x) const {
71  return OpIt == x.OpIt;
72  }
73  bool operator!=(const generic_gep_type_iterator& x) const {
74  return !operator==(x);
75  }
76 
77  LLVM_TYPE_Q llvm::Type *operator*() const {
78  return CurTy;
79  }
80 
81  LLVM_TYPE_Q llvm::Type *getIndexedType() const {
82  LLVM_TYPE_Q llvm::CompositeType *CT = cast<llvm::CompositeType>(CurTy);
83  return CT->getTypeAtIndex(getOperand());
84  }
85 
86  // This is a non-standard operator->. It allows you to call methods on the
87  // current type directly.
88  LLVM_TYPE_Q llvm::Type *operator->() const { return operator*(); }
89 
90  llvm::Value *getOperand() const { return asValue(*OpIt); }
91 
93  if (LLVM_TYPE_Q llvm::CompositeType *CT =
94  dyn_cast<llvm::CompositeType>(CurTy)) {
95  CurTy = CT->getTypeAtIndex(getOperand());
96  } else {
97  CurTy = 0;
98  }
99  ++OpIt;
100  return *this;
101  }
102 
103  generic_gep_type_iterator operator++(int) { // Postincrement
104  generic_gep_type_iterator tmp = *this; ++*this; return tmp;
105  }
106  };
107 
112 
113  inline gep_type_iterator gep_type_begin(const llvm::User *GEP) {
114  return gep_type_iterator::begin(GEP->getOperand(0)->getType(),
115  GEP->op_begin()+1);
116  }
117  inline gep_type_iterator gep_type_end(const llvm::User *GEP) {
118  return gep_type_iterator::end(GEP->op_end());
119  }
120  inline gep_type_iterator gep_type_begin(const llvm::User &GEP) {
121  return gep_type_iterator::begin(GEP.getOperand(0)->getType(),
122  GEP.op_begin()+1);
123  }
124  inline gep_type_iterator gep_type_end(const llvm::User &GEP) {
125  return gep_type_iterator::end(GEP.op_end());
126  }
127 
128  inline ev_type_iterator ev_type_begin(const llvm::ExtractValueInst *EV) {
129  return ev_type_iterator::begin(EV->getOperand(0)->getType(),
130  EV->idx_begin());
131  }
132  inline ev_type_iterator ev_type_end(const llvm::ExtractValueInst *EV) {
133  return ev_type_iterator::end(EV->idx_end());
134  }
135 
136  inline iv_type_iterator iv_type_begin(const llvm::InsertValueInst *IV) {
137  return iv_type_iterator::begin(IV->getType(),
138  IV->idx_begin());
139  }
140  inline iv_type_iterator iv_type_end(const llvm::InsertValueInst *IV) {
141  return iv_type_iterator::end(IV->idx_end());
142  }
143 
144  inline vce_type_iterator vce_type_begin(const llvm::ConstantExpr *CE) {
145  return vce_type_iterator::begin(CE->getOperand(0)->getType(),
146  CE->getIndices().begin());
147  }
148  inline vce_type_iterator vce_type_end(const llvm::ConstantExpr *CE) {
149  return vce_type_iterator::end(CE->getIndices().end());
150  }
151 
152  template<typename ItTy>
153  inline generic_gep_type_iterator<ItTy>
154  gep_type_begin(LLVM_TYPE_Q llvm::Type *Op0, ItTy I, ItTy E) {
156  }
157 
158  template<typename ItTy>
159  inline generic_gep_type_iterator<ItTy>
160  gep_type_end(LLVM_TYPE_Q llvm::Type *Op0, ItTy I, ItTy E) {
162  }
163 } // end namespace klee
164 
165 #endif
LLVM_TYPE_Q llvm::Type * operator*() const
generic_gep_type_iterator & operator++()
LLVM_TYPE_Q llvm::Type * getIndexedType() const
iv_type_iterator iv_type_begin(const llvm::InsertValueInst *IV)
bool operator==(const generic_gep_type_iterator &x) const
bool operator!=(const generic_gep_type_iterator &x) const
generic_gep_type_iterator< llvm::ExtractValueInst::idx_iterator > ev_type_iterator
iv_type_iterator iv_type_end(const llvm::InsertValueInst *IV)
ev_type_iterator ev_type_end(const llvm::ExtractValueInst *EV)
gep_type_iterator gep_type_end(const llvm::User *GEP)
LLVM_TYPE_Q llvm::Type * operator->() const
static generic_gep_type_iterator begin(LLVM_TYPE_Q llvm::Type *Ty, ItTy It)
std::iterator< std::forward_iterator_tag, LLVM_TYPE_Q llvm::Type *, ptrdiff_t > super
vce_type_iterator vce_type_begin(const llvm::ConstantExpr *CE)
llvm::Value * asValue(llvm::Value *V) const
ev_type_iterator ev_type_begin(const llvm::ExtractValueInst *EV)
llvm::Value * asValue(unsigned U) const
#define LLVM_TYPE_Q
Definition: Version.h:21
gep_type_iterator gep_type_begin(const llvm::User *GEP)
generic_gep_type_iterator operator++(int)
generic_gep_type_iterator< llvm::InsertValueInst::idx_iterator > iv_type_iterator
generic_gep_type_iterator< llvm::SmallVector< unsigned, 4 >::const_iterator > vce_type_iterator
vce_type_iterator vce_type_end(const llvm::ConstantExpr *CE)
generic_gep_type_iterator gep_type_iterator
static generic_gep_type_iterator end(ItTy It)