File indexing completed on 2026-05-10 08:44:00
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
0015 #define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
0016
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/PointerUnion.h"
0019 #include "llvm/IR/DataLayout.h"
0020 #include "llvm/IR/DerivedTypes.h"
0021 #include "llvm/IR/Operator.h"
0022 #include "llvm/IR/User.h"
0023 #include "llvm/Support/Casting.h"
0024 #include <cstddef>
0025 #include <cstdint>
0026 #include <iterator>
0027
0028 namespace llvm {
0029
0030 template <typename ItTy = User::const_op_iterator>
0031 class generic_gep_type_iterator {
0032
0033 ItTy OpIt;
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 PointerUnion<StructType *, VectorType *, Type *> CurTy;
0067
0068 generic_gep_type_iterator() = default;
0069
0070 public:
0071 using iterator_category = std::forward_iterator_tag;
0072 using value_type = Type *;
0073 using difference_type = std::ptrdiff_t;
0074 using pointer = value_type *;
0075 using reference = value_type &;
0076
0077 static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
0078 generic_gep_type_iterator I;
0079 I.CurTy = Ty;
0080 I.OpIt = It;
0081 return I;
0082 }
0083
0084 static generic_gep_type_iterator end(ItTy It) {
0085 generic_gep_type_iterator I;
0086 I.OpIt = It;
0087 return I;
0088 }
0089
0090 bool operator==(const generic_gep_type_iterator &x) const {
0091 return OpIt == x.OpIt;
0092 }
0093
0094 bool operator!=(const generic_gep_type_iterator &x) const {
0095 return !operator==(x);
0096 }
0097
0098
0099
0100
0101
0102 Type *getIndexedType() const {
0103 if (auto *T = dyn_cast_if_present<Type *>(CurTy))
0104 return T;
0105 if (auto *VT = dyn_cast_if_present<VectorType *>(CurTy))
0106 return VT->getElementType();
0107 return cast<StructType *>(CurTy)->getTypeAtIndex(getOperand());
0108 }
0109
0110 Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
0111
0112 generic_gep_type_iterator &operator++() {
0113 Type *Ty = getIndexedType();
0114 if (auto *ATy = dyn_cast<ArrayType>(Ty))
0115 CurTy = ATy->getElementType();
0116 else if (auto *VTy = dyn_cast<VectorType>(Ty))
0117 CurTy = VTy;
0118 else
0119 CurTy = dyn_cast<StructType>(Ty);
0120 ++OpIt;
0121 return *this;
0122 }
0123
0124 generic_gep_type_iterator operator++(int) {
0125 generic_gep_type_iterator tmp = *this;
0126 ++*this;
0127 return tmp;
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 bool isStruct() const { return isa<StructType *>(CurTy); }
0146 bool isVector() const { return isa<VectorType *>(CurTy); }
0147 bool isSequential() const { return !isStruct(); }
0148
0149
0150
0151
0152
0153
0154 TypeSize getSequentialElementStride(const DataLayout &DL) const {
0155 assert(isSequential());
0156 Type *ElemTy = getIndexedType();
0157 if (isVector()) {
0158 assert(DL.typeSizeEqualsStoreSize(ElemTy) && "Not byte-addressable");
0159 return DL.getTypeStoreSize(ElemTy);
0160 }
0161 return DL.getTypeAllocSize(ElemTy);
0162 }
0163
0164 StructType *getStructType() const { return cast<StructType *>(CurTy); }
0165
0166 StructType *getStructTypeOrNull() const {
0167 return dyn_cast_if_present<StructType *>(CurTy);
0168 }
0169 };
0170
0171 using gep_type_iterator = generic_gep_type_iterator<>;
0172
0173 inline gep_type_iterator gep_type_begin(const User *GEP) {
0174 auto *GEPOp = cast<GEPOperator>(GEP);
0175 return gep_type_iterator::begin(
0176 GEPOp->getSourceElementType(),
0177 GEP->op_begin() + 1);
0178 }
0179
0180 inline gep_type_iterator gep_type_end(const User *GEP) {
0181 return gep_type_iterator::end(GEP->op_end());
0182 }
0183
0184 inline gep_type_iterator gep_type_begin(const User &GEP) {
0185 auto &GEPOp = cast<GEPOperator>(GEP);
0186 return gep_type_iterator::begin(
0187 GEPOp.getSourceElementType(),
0188 GEP.op_begin() + 1);
0189 }
0190
0191 inline gep_type_iterator gep_type_end(const User &GEP) {
0192 return gep_type_iterator::end(GEP.op_end());
0193 }
0194
0195 template<typename T>
0196 inline generic_gep_type_iterator<const T *>
0197 gep_type_begin(Type *Op0, ArrayRef<T> A) {
0198 return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
0199 }
0200
0201 template<typename T>
0202 inline generic_gep_type_iterator<const T *>
0203 gep_type_end(Type * , ArrayRef<T> A) {
0204 return generic_gep_type_iterator<const T *>::end(A.end());
0205 }
0206
0207 }
0208
0209 #endif