klee
GetElementPtrTypeIterator.h
Go to the documentation of this file.
1//===-- 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_GETELEMENTPTRTYPEITERATOR_H
19#define KLEE_GETELEMENTPTRTYPEITERATOR_H
20
21#include "llvm/IR/User.h"
22#include "llvm/IR/DerivedTypes.h"
23#include "llvm/IR/Instructions.h"
24#include "llvm/IR/Constants.h"
25
26#include "klee/Config/Version.h"
27
28namespace klee {
29template <typename ItTy = llvm::User::const_op_iterator>
31 : public std::iterator<std::forward_iterator_tag, llvm::Type *, ptrdiff_t> {
32 typedef std::iterator<std::forward_iterator_tag, llvm::Type *, ptrdiff_t>
34
35 ItTy OpIt;
36 llvm::Type *CurTy;
38
39 llvm::Value *asValue(llvm::Value *V) const { return V; }
40 llvm::Value *asValue(unsigned U) const {
41 return llvm::ConstantInt::get(CurTy->getContext(), llvm::APInt(32, U));
42 }
43
44 public:
45 static generic_gep_type_iterator begin(llvm::Type *Ty, ItTy It) {
47 I.CurTy = Ty;
48 I.OpIt = It;
49 return I;
50 }
53 I.CurTy = 0;
54 I.OpIt = It;
55 return I;
56 }
57
59 return OpIt == x.OpIt;
60 }
62 return !operator==(x);
63 }
64
65 llvm::Type *operator*() const { return CurTy; }
66
67 llvm::Type *getIndexedType() const {
68#if LLVM_VERSION_CODE >= LLVM_VERSION(11, 0)
69 return llvm::GetElementPtrInst::getTypeAtIndex(CurTy, getOperand());
70#else
71 llvm::CompositeType *CT = cast<llvm::CompositeType>(CurTy);
72 return CT->getTypeAtIndex(getOperand());
73#endif
74 }
75
76 // This is a non-standard operator->. It allows you to call methods on the
77 // current type directly.
78 llvm::Type *operator->() const { return operator*(); }
79
80 llvm::Value *getOperand() const { return asValue(*OpIt); }
81
83#if LLVM_VERSION_CODE >= LLVM_VERSION(11, 0)
84 if (isa<llvm::StructType>(CurTy) || isa<llvm::ArrayType>(CurTy) ||
85 isa<llvm::VectorType>(CurTy)) {
86 CurTy = llvm::GetElementPtrInst::getTypeAtIndex(CurTy, getOperand());
87#else
88 if (llvm::CompositeType *CT = dyn_cast<llvm::CompositeType>(CurTy)) {
89 CurTy = CT->getTypeAtIndex(getOperand());
90#endif
91 } else if (auto ptr = dyn_cast<llvm::PointerType>(CurTy)) {
92 CurTy = ptr->getElementType();
93 } else {
94 CurTy = 0;
95 }
96 ++OpIt;
97 return *this;
98 }
99
100 generic_gep_type_iterator operator++(int) { // Postincrement
101 generic_gep_type_iterator tmp = *this; ++*this; return tmp;
102 }
103 };
104
109
110 inline gep_type_iterator gep_type_begin(const llvm::User *GEP) {
111 return gep_type_iterator::begin(GEP->getOperand(0)->getType(),
112 GEP->op_begin()+1);
113 }
114 inline gep_type_iterator gep_type_end(const llvm::User *GEP) {
115 return gep_type_iterator::end(GEP->op_end());
116 }
117 inline gep_type_iterator gep_type_begin(const llvm::User &GEP) {
118 return gep_type_iterator::begin(GEP.getOperand(0)->getType(),
119 GEP.op_begin()+1);
120 }
121 inline gep_type_iterator gep_type_end(const llvm::User &GEP) {
122 return gep_type_iterator::end(GEP.op_end());
123 }
124
125 inline ev_type_iterator ev_type_begin(const llvm::ExtractValueInst *EV) {
126 return ev_type_iterator::begin(EV->getOperand(0)->getType(),
127 EV->idx_begin());
128 }
129 inline ev_type_iterator ev_type_end(const llvm::ExtractValueInst *EV) {
130 return ev_type_iterator::end(EV->idx_end());
131 }
132
133 inline iv_type_iterator iv_type_begin(const llvm::InsertValueInst *IV) {
134 return iv_type_iterator::begin(IV->getType(),
135 IV->idx_begin());
136 }
137 inline iv_type_iterator iv_type_end(const llvm::InsertValueInst *IV) {
138 return iv_type_iterator::end(IV->idx_end());
139 }
140
141 inline vce_type_iterator vce_type_begin(const llvm::ConstantExpr *CE) {
142 return vce_type_iterator::begin(CE->getOperand(0)->getType(),
143 CE->getIndices().begin());
144 }
145 inline vce_type_iterator vce_type_end(const llvm::ConstantExpr *CE) {
146 return vce_type_iterator::end(CE->getIndices().end());
147 }
148
149 template <typename ItTy>
150 inline generic_gep_type_iterator<ItTy> gep_type_begin(llvm::Type *Op0, ItTy I,
151 ItTy E) {
153 }
154
155 template <typename ItTy>
156 inline generic_gep_type_iterator<ItTy> gep_type_end(llvm::Type *Op0, ItTy I,
157 ItTy E) {
159 }
160} // end namespace klee
161
162#endif /* KLEE_GETELEMENTPTRTYPEITERATOR_H */
llvm::Value * asValue(unsigned U) const
llvm::Value * asValue(llvm::Value *V) const
bool operator==(const generic_gep_type_iterator &x) const
generic_gep_type_iterator & operator++()
bool operator!=(const generic_gep_type_iterator &x) const
generic_gep_type_iterator operator++(int)
static generic_gep_type_iterator begin(llvm::Type *Ty, ItTy It)
static generic_gep_type_iterator end(ItTy It)
std::iterator< std::forward_iterator_tag, llvm::Type *, ptrdiff_t > super
Definition: main.cpp:291
gep_type_iterator gep_type_begin(const llvm::User *GEP)
generic_gep_type_iterator< llvm::SmallVector< unsigned, 4 >::const_iterator > vce_type_iterator
vce_type_iterator vce_type_end(const llvm::ConstantExpr *CE)
iv_type_iterator iv_type_end(const llvm::InsertValueInst *IV)
generic_gep_type_iterator< llvm::ExtractValueInst::idx_iterator > ev_type_iterator
ev_type_iterator ev_type_begin(const llvm::ExtractValueInst *EV)
ev_type_iterator ev_type_end(const llvm::ExtractValueInst *EV)
generic_gep_type_iterator gep_type_iterator
vce_type_iterator vce_type_begin(const llvm::ConstantExpr *CE)
generic_gep_type_iterator< llvm::InsertValueInst::idx_iterator > iv_type_iterator
gep_type_iterator gep_type_end(const llvm::User *GEP)
iv_type_iterator iv_type_begin(const llvm::InsertValueInst *IV)