1 //===- llvm/Support/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_SUPPORT_GETELEMENTPTRTYPE_H 16 #define LLVM_SUPPORT_GETELEMENTPTRTYPE_H 17 18 #include "llvm/User.h" 19 #include "llvm/DerivedTypes.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; generic_gep_type_iterator()30 generic_gep_type_iterator() {} 31 public: 32 begin(Type * Ty,ItTy It)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 } end(ItTy It)39 static generic_gep_type_iterator end(ItTy It) { 40 generic_gep_type_iterator I; 41 I.CurTy = 0; 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 getIndexedType()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 getOperand()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 = 0; 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 gep_type_begin(const User * GEP)85 inline gep_type_iterator gep_type_begin(const User *GEP) { 86 return gep_type_iterator::begin(GEP->getOperand(0)->getType(), 87 GEP->op_begin()+1); 88 } gep_type_end(const User * GEP)89 inline gep_type_iterator gep_type_end(const User *GEP) { 90 return gep_type_iterator::end(GEP->op_end()); 91 } gep_type_begin(const User & GEP)92 inline gep_type_iterator gep_type_begin(const User &GEP) { 93 return gep_type_iterator::begin(GEP.getOperand(0)->getType(), 94 GEP.op_begin()+1); 95 } gep_type_end(const User & GEP)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 *> gep_type_begin(Type * Op0,ArrayRef<T> A)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 *> gep_type_end(Type * Op0,ArrayRef<T> A)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