#define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Operator.h"
#include "llvm/IR/User.h"
+#include "llvm/ADT/PointerIntPair.h"
namespace llvm {
template<typename ItTy = User::const_op_iterator>
Type *, ptrdiff_t> super;
ItTy OpIt;
- Type *CurTy;
+ PointerIntPair<Type *, 1> CurTy;
+ unsigned AddrSpace;
generic_gep_type_iterator() {}
public:
static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
generic_gep_type_iterator I;
- I.CurTy = Ty;
+ I.CurTy.setPointer(Ty);
+ I.OpIt = It;
+ return I;
+ }
+ static generic_gep_type_iterator begin(Type *Ty, unsigned AddrSpace,
+ ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy.setPointer(Ty);
+ I.CurTy.setInt(true);
+ I.AddrSpace = AddrSpace;
I.OpIt = It;
return I;
}
static generic_gep_type_iterator end(ItTy It) {
generic_gep_type_iterator I;
- I.CurTy = 0;
I.OpIt = It;
return I;
}
}
Type *operator*() const {
- return CurTy;
+ if (CurTy.getInt())
+ return CurTy.getPointer()->getPointerTo(AddrSpace);
+ return CurTy.getPointer();
}
Type *getIndexedType() const {
- CompositeType *CT = cast<CompositeType>(CurTy);
+ if (CurTy.getInt())
+ return CurTy.getPointer();
+ CompositeType *CT = cast<CompositeType>(CurTy.getPointer());
return CT->getTypeAtIndex(getOperand());
}
// current type directly.
Type *operator->() const { return operator*(); }
- Value *getOperand() const { return *OpIt; }
+ Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
generic_gep_type_iterator& operator++() { // Preincrement
- if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
- CurTy = CT->getTypeAtIndex(getOperand());
+ if (CurTy.getInt()) {
+ CurTy.setInt(false);
+ } else if (CompositeType *CT =
+ dyn_cast<CompositeType>(CurTy.getPointer())) {
+ CurTy.setPointer(CT->getTypeAtIndex(getOperand()));
} else {
- CurTy = 0;
+ CurTy.setPointer(nullptr);
}
++OpIt;
return *this;
typedef generic_gep_type_iterator<> gep_type_iterator;
inline gep_type_iterator gep_type_begin(const User *GEP) {
- return gep_type_iterator::begin
- (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1);
+ auto *GEPOp = cast<GEPOperator>(GEP);
+ return gep_type_iterator::begin(
+ GEPOp->getSourceElementType(),
+ cast<PointerType>(GEPOp->getPointerOperandType()->getScalarType())
+ ->getAddressSpace(),
+ 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);
+ auto &GEPOp = cast<GEPOperator>(GEP);
+ return gep_type_iterator::begin(
+ GEPOp.getSourceElementType(),
+ cast<PointerType>(GEPOp.getPointerOperandType()->getScalarType())
+ ->getAddressSpace(),
+ GEP.op_begin() + 1);
}
inline gep_type_iterator gep_type_end(const User &GEP) {
return gep_type_iterator::end(GEP.op_end());