//===- llvm/Support/GetElementPtrTypeIterator.h -----------------*- C++ -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
//===----------------------------------------------------------------------===//
//
// This file implements an iterator for walking through the types indexed by
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H
-#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
+#define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
-#include "Support/iterator"
-#include "llvm/iMemory.h"
-#include "llvm/DerivedTypes.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/User.h"
namespace llvm {
- class gep_type_iterator
- : public forward_iterator<const Type *, ptrdiff_t> {
- typedef forward_iterator<const Type*, ptrdiff_t> super;
-
- User *TheGEP; // Either GetElementPtrInst or ConstantExpr
- const Type *CurTy;
- unsigned Operand;
-
- gep_type_iterator() {}
+ template<typename ItTy = User::const_op_iterator>
+ class generic_gep_type_iterator
+ : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
+ typedef std::iterator<std::forward_iterator_tag,
+ Type *, ptrdiff_t> super;
+
+ ItTy OpIt;
+ Type *CurTy;
+ generic_gep_type_iterator() {}
public:
- static gep_type_iterator begin(User *gep) {
- gep_type_iterator I;
- I.TheGEP = gep;
- I.CurTy = gep->getOperand(0)->getType();
- I.Operand = 1;
+ static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = Ty;
+ I.OpIt = It;
return I;
}
- static gep_type_iterator end(User *gep) {
- gep_type_iterator I;
- I.TheGEP = gep;
+ static generic_gep_type_iterator end(ItTy It) {
+ generic_gep_type_iterator I;
I.CurTy = 0;
- I.Operand = gep->getNumOperands();
+ I.OpIt = It;
return I;
}
- bool operator==(const gep_type_iterator& x) const {
- return Operand == x.Operand;
+ bool operator==(const generic_gep_type_iterator& x) const {
+ return OpIt == x.OpIt;
}
- bool operator!=(const gep_type_iterator& x) const {
+ bool operator!=(const generic_gep_type_iterator& x) const {
return !operator==(x);
}
- const Type *operator*() const {
+ Type *operator*() const {
return CurTy;
}
+ Type *getIndexedType() const {
+ CompositeType *CT = cast<CompositeType>(CurTy);
+ return CT->getTypeAtIndex(getOperand());
+ }
+
// This is a non-standard operator->. It allows you to call methods on the
// current type directly.
- const Type *operator->() const { return operator*(); }
-
- unsigned getOperandNum() const { return Operand; }
+ Type *operator->() const { return operator*(); }
- Value *getOperand() const { return TheGEP->getOperand(Operand); }
+ Value *getOperand() const { return *OpIt; }
- gep_type_iterator& operator++() { // Preincrement
- if (const CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
+ generic_gep_type_iterator& operator++() { // Preincrement
+ if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
CurTy = CT->getTypeAtIndex(getOperand());
} else {
CurTy = 0;
}
- ++Operand;
- return *this;
+ ++OpIt;
+ return *this;
}
- gep_type_iterator operator++(int) { // Postincrement
- gep_type_iterator tmp = *this; ++*this; return tmp;
+ generic_gep_type_iterator operator++(int) { // Postincrement
+ generic_gep_type_iterator tmp = *this; ++*this; return tmp;
}
};
- inline gep_type_iterator gep_type_begin(User *GEP) {
- return gep_type_iterator::begin(GEP);
- }
+ typedef generic_gep_type_iterator<> gep_type_iterator;
- inline gep_type_iterator gep_type_end(User *GEP) {
- return gep_type_iterator::end(GEP);
+ inline gep_type_iterator gep_type_begin(const User *GEP) {
+ return gep_type_iterator::begin
+ (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1);
+ }
+ inline gep_type_iterator gep_type_end(const User *GEP) {
+ return gep_type_iterator::end(GEP->op_end());
+ }
+ inline gep_type_iterator gep_type_begin(const User &GEP) {
+ return gep_type_iterator::begin
+ (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1);
}
- inline gep_type_iterator gep_type_begin(User &GEP) {
- return gep_type_iterator::begin(&GEP);
+ inline gep_type_iterator gep_type_end(const User &GEP) {
+ return gep_type_iterator::end(GEP.op_end());
+ }
+
+ template<typename T>
+ inline generic_gep_type_iterator<const T *>
+ gep_type_begin(Type *Op0, ArrayRef<T> A) {
+ return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
}
- inline gep_type_iterator gep_type_end(User &GEP) {
- return gep_type_iterator::end(&GEP);
+ template<typename T>
+ inline generic_gep_type_iterator<const T *>
+ gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
+ return generic_gep_type_iterator<const T *>::end(A.end());
}
} // end namespace llvm