LLVM API Documentation
00001 //===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements an iterator for walking through the types indexed by 00011 // getelementptr instructions. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H 00016 #define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H 00017 00018 #include "llvm/IR/DerivedTypes.h" 00019 #include "llvm/IR/User.h" 00020 00021 namespace llvm { 00022 template<typename ItTy = User::const_op_iterator> 00023 class generic_gep_type_iterator 00024 : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> { 00025 typedef std::iterator<std::forward_iterator_tag, 00026 Type *, ptrdiff_t> super; 00027 00028 ItTy OpIt; 00029 Type *CurTy; 00030 generic_gep_type_iterator() {} 00031 public: 00032 00033 static generic_gep_type_iterator begin(Type *Ty, ItTy It) { 00034 generic_gep_type_iterator I; 00035 I.CurTy = Ty; 00036 I.OpIt = It; 00037 return I; 00038 } 00039 static generic_gep_type_iterator end(ItTy It) { 00040 generic_gep_type_iterator I; 00041 I.CurTy = nullptr; 00042 I.OpIt = It; 00043 return I; 00044 } 00045 00046 bool operator==(const generic_gep_type_iterator& x) const { 00047 return OpIt == x.OpIt; 00048 } 00049 bool operator!=(const generic_gep_type_iterator& x) const { 00050 return !operator==(x); 00051 } 00052 00053 Type *operator*() const { 00054 return CurTy; 00055 } 00056 00057 Type *getIndexedType() const { 00058 CompositeType *CT = cast<CompositeType>(CurTy); 00059 return CT->getTypeAtIndex(getOperand()); 00060 } 00061 00062 // This is a non-standard operator->. It allows you to call methods on the 00063 // current type directly. 00064 Type *operator->() const { return operator*(); } 00065 00066 Value *getOperand() const { return *OpIt; } 00067 00068 generic_gep_type_iterator& operator++() { // Preincrement 00069 if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) { 00070 CurTy = CT->getTypeAtIndex(getOperand()); 00071 } else { 00072 CurTy = nullptr; 00073 } 00074 ++OpIt; 00075 return *this; 00076 } 00077 00078 generic_gep_type_iterator operator++(int) { // Postincrement 00079 generic_gep_type_iterator tmp = *this; ++*this; return tmp; 00080 } 00081 }; 00082 00083 typedef generic_gep_type_iterator<> gep_type_iterator; 00084 00085 inline gep_type_iterator gep_type_begin(const User *GEP) { 00086 return gep_type_iterator::begin 00087 (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1); 00088 } 00089 inline gep_type_iterator gep_type_end(const User *GEP) { 00090 return gep_type_iterator::end(GEP->op_end()); 00091 } 00092 inline gep_type_iterator gep_type_begin(const User &GEP) { 00093 return gep_type_iterator::begin 00094 (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1); 00095 } 00096 inline gep_type_iterator gep_type_end(const User &GEP) { 00097 return gep_type_iterator::end(GEP.op_end()); 00098 } 00099 00100 template<typename T> 00101 inline generic_gep_type_iterator<const T *> 00102 gep_type_begin(Type *Op0, ArrayRef<T> A) { 00103 return generic_gep_type_iterator<const T *>::begin(Op0, A.begin()); 00104 } 00105 00106 template<typename T> 00107 inline generic_gep_type_iterator<const T *> 00108 gep_type_end(Type * /*Op0*/, ArrayRef<T> A) { 00109 return generic_gep_type_iterator<const T *>::end(A.end()); 00110 } 00111 } // end namespace llvm 00112 00113 #endif