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 instructions. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H 16 #define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H 17 18 #include "llvm/IR/DerivedTypes.h" 19 #include "llvm/IR/User.h" 20 21 namespace llvm { 22 template<typename ItTy = User::const_op_iterator> 23 class generic_gep_type_iterator 24 : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> { 25 typedef std::iterator<std::forward_iterator_tag, 26 Type *, ptrdiff_t> super; 27 28 ItTy OpIt; 29 Type *CurTy; 30 generic_gep_type_iterator() {} 31 public: 32 33 static generic_gep_type_iterator begin(Type *Ty, ItTy It) { 34 generic_gep_type_iterator I; 35 I.CurTy = Ty; 36 I.OpIt = It; 37 return I; 38 } 39 static generic_gep_type_iterator end(ItTy It) { 40 generic_gep_type_iterator I; 41 I.CurTy = nullptr; 42 I.OpIt = It; 43 return I; 44 } 45 46 bool operator==(const generic_gep_type_iterator& x) const { 47 return OpIt == x.OpIt; 48 } 49 bool operator!=(const generic_gep_type_iterator& x) const { 50 return !operator==(x); 51 } 52 53 Type *operator*() const { 54 return CurTy; 55 } 56 57 Type *getIndexedType() const { 58 CompositeType *CT = cast<CompositeType>(CurTy); 59 return CT->getTypeAtIndex(getOperand()); 60 } 61 62 // This is a non-standard operator->. It allows you to call methods on the 63 // current type directly. 64 Type *operator->() const { return operator*(); } 65 66 Value *getOperand() const { return *OpIt; } 67 68 generic_gep_type_iterator& operator++() { // Preincrement 69 if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) { 70 CurTy = CT->getTypeAtIndex(getOperand()); 71 } else { 72 CurTy = nullptr; 73 } 74 ++OpIt; 75 return *this; 76 } 77 78 generic_gep_type_iterator operator++(int) { // Postincrement 79 generic_gep_type_iterator tmp = *this; ++*this; return tmp; 80 } 81 }; 82 83 typedef generic_gep_type_iterator<> gep_type_iterator; 84 85 inline gep_type_iterator gep_type_begin(const User *GEP) { 86 return gep_type_iterator::begin 87 (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1); 88 } 89 inline gep_type_iterator gep_type_end(const User *GEP) { 90 return gep_type_iterator::end(GEP->op_end()); 91 } 92 inline gep_type_iterator gep_type_begin(const User &GEP) { 93 return gep_type_iterator::begin 94 (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1); 95 } 96 inline gep_type_iterator gep_type_end(const User &GEP) { 97 return gep_type_iterator::end(GEP.op_end()); 98 } 99 100 template<typename T> 101 inline generic_gep_type_iterator<const T *> 102 gep_type_begin(Type *Op0, ArrayRef<T> A) { 103 return generic_gep_type_iterator<const T *>::begin(Op0, A.begin()); 104 } 105 106 template<typename T> 107 inline generic_gep_type_iterator<const T *> 108 gep_type_end(Type * /*Op0*/, ArrayRef<T> A) { 109 return generic_gep_type_iterator<const T *>::end(A.end()); 110 } 111 } // end namespace llvm 112 113 #endif 114