aboutsummaryrefslogtreecommitdiff
path: root/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include/llvm/IR/GetElementPtrTypeIterator.h')
-rw-r--r--llvm/include/llvm/IR/GetElementPtrTypeIterator.h206
1 files changed, 106 insertions, 100 deletions
diff --git a/llvm/include/llvm/IR/GetElementPtrTypeIterator.h b/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
index 6293305a2639..ed854e458da2 100644
--- a/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
+++ b/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
@@ -27,106 +27,112 @@
namespace llvm {
- template<typename ItTy = User::const_op_iterator>
- class generic_gep_type_iterator
- : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
- using super = std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t>;
-
- ItTy OpIt;
- PointerUnion<StructType *, Type *> CurTy;
- enum : uint64_t { Unbounded = -1ull };
- uint64_t NumElements = Unbounded;
-
- generic_gep_type_iterator() = default;
-
- public:
- static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
- generic_gep_type_iterator I;
- I.CurTy = Ty;
- I.OpIt = It;
- return I;
- }
-
- static generic_gep_type_iterator end(ItTy It) {
- generic_gep_type_iterator I;
- I.OpIt = It;
- return I;
- }
-
- bool operator==(const generic_gep_type_iterator& x) const {
- return OpIt == x.OpIt;
- }
-
- bool operator!=(const generic_gep_type_iterator& x) const {
- return !operator==(x);
- }
-
- // FIXME: Make this the iterator's operator*() after the 4.0 release.
- // operator*() had a different meaning in earlier releases, so we're
- // temporarily not giving this iterator an operator*() to avoid a subtle
- // semantics break.
- Type *getIndexedType() const {
- if (auto *T = CurTy.dyn_cast<Type *>())
- return T;
- return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
- }
-
- Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
-
- generic_gep_type_iterator& operator++() { // Preincrement
- Type *Ty = getIndexedType();
- if (auto *ATy = dyn_cast<ArrayType>(Ty)) {
- CurTy = ATy->getElementType();
- NumElements = ATy->getNumElements();
- } else if (auto *VTy = dyn_cast<VectorType>(Ty)) {
- CurTy = VTy->getElementType();
- if (isa<ScalableVectorType>(VTy))
- NumElements = Unbounded;
- else
- NumElements = cast<FixedVectorType>(VTy)->getNumElements();
- } else
- CurTy = dyn_cast<StructType>(Ty);
- ++OpIt;
- return *this;
- }
-
- generic_gep_type_iterator operator++(int) { // Postincrement
- generic_gep_type_iterator tmp = *this; ++*this; return tmp;
- }
-
- // All of the below API is for querying properties of the "outer type", i.e.
- // the type that contains the indexed type. Most of the time this is just
- // the type that was visited immediately prior to the indexed type, but for
- // the first element this is an unbounded array of the GEP's source element
- // type, for which there is no clearly corresponding IR type (we've
- // historically used a pointer type as the outer type in this case, but
- // pointers will soon lose their element type).
- //
- // FIXME: Most current users of this class are just interested in byte
- // offsets (a few need to know whether the outer type is a struct because
- // they are trying to replace a constant with a variable, which is only
- // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
- // we should provide a more minimal API here that exposes not much more than
- // that.
-
- bool isStruct() const { return CurTy.is<StructType *>(); }
- bool isSequential() const { return CurTy.is<Type *>(); }
-
- StructType *getStructType() const { return CurTy.get<StructType *>(); }
-
- StructType *getStructTypeOrNull() const {
- return CurTy.dyn_cast<StructType *>();
- }
-
- bool isBoundedSequential() const {
- return isSequential() && NumElements != Unbounded;
- }
-
- uint64_t getSequentialNumElements() const {
- assert(isBoundedSequential());
- return NumElements;
- }
- };
+template <typename ItTy = User::const_op_iterator>
+class generic_gep_type_iterator {
+
+ ItTy OpIt;
+ PointerUnion<StructType *, Type *> CurTy;
+ enum : uint64_t { Unbounded = -1ull };
+ uint64_t NumElements = Unbounded;
+
+ generic_gep_type_iterator() = default;
+
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = Type *;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+ static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = Ty;
+ I.OpIt = It;
+ return I;
+ }
+
+ static generic_gep_type_iterator end(ItTy It) {
+ generic_gep_type_iterator I;
+ I.OpIt = It;
+ return I;
+ }
+
+ bool operator==(const generic_gep_type_iterator &x) const {
+ return OpIt == x.OpIt;
+ }
+
+ bool operator!=(const generic_gep_type_iterator &x) const {
+ return !operator==(x);
+ }
+
+ // FIXME: Make this the iterator's operator*() after the 4.0 release.
+ // operator*() had a different meaning in earlier releases, so we're
+ // temporarily not giving this iterator an operator*() to avoid a subtle
+ // semantics break.
+ Type *getIndexedType() const {
+ if (auto *T = CurTy.dyn_cast<Type *>())
+ return T;
+ return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
+ }
+
+ Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
+
+ generic_gep_type_iterator &operator++() { // Preincrement
+ Type *Ty = getIndexedType();
+ if (auto *ATy = dyn_cast<ArrayType>(Ty)) {
+ CurTy = ATy->getElementType();
+ NumElements = ATy->getNumElements();
+ } else if (auto *VTy = dyn_cast<VectorType>(Ty)) {
+ CurTy = VTy->getElementType();
+ if (isa<ScalableVectorType>(VTy))
+ NumElements = Unbounded;
+ else
+ NumElements = cast<FixedVectorType>(VTy)->getNumElements();
+ } else
+ CurTy = dyn_cast<StructType>(Ty);
+ ++OpIt;
+ return *this;
+ }
+
+ generic_gep_type_iterator operator++(int) { // Postincrement
+ generic_gep_type_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // All of the below API is for querying properties of the "outer type", i.e.
+ // the type that contains the indexed type. Most of the time this is just
+ // the type that was visited immediately prior to the indexed type, but for
+ // the first element this is an unbounded array of the GEP's source element
+ // type, for which there is no clearly corresponding IR type (we've
+ // historically used a pointer type as the outer type in this case, but
+ // pointers will soon lose their element type).
+ //
+ // FIXME: Most current users of this class are just interested in byte
+ // offsets (a few need to know whether the outer type is a struct because
+ // they are trying to replace a constant with a variable, which is only
+ // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
+ // we should provide a more minimal API here that exposes not much more than
+ // that.
+
+ bool isStruct() const { return CurTy.is<StructType *>(); }
+ bool isSequential() const { return CurTy.is<Type *>(); }
+
+ StructType *getStructType() const { return CurTy.get<StructType *>(); }
+
+ StructType *getStructTypeOrNull() const {
+ return CurTy.dyn_cast<StructType *>();
+ }
+
+ bool isBoundedSequential() const {
+ return isSequential() && NumElements != Unbounded;
+ }
+
+ uint64_t getSequentialNumElements() const {
+ assert(isBoundedSequential());
+ return NumElements;
+ }
+};
using gep_type_iterator = generic_gep_type_iterator<>;