136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===//
263b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
319ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner//                     The LLVM Compiler Infrastructure
419ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner//
57ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// This file is distributed under the University of Illinois Open Source
67ed47a13356daed2a34cd2209a31f92552e3bdd8Chris Lattner// License. See LICENSE.TXT for details.
763b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman//
819ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner//===----------------------------------------------------------------------===//
919ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner//
1019ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner// This file implements an iterator for walking through the types indexed by
1119ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner// getelementptr instructions.
1219ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner//
1319ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner//===----------------------------------------------------------------------===//
1419ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
1719ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/User.h"
2019ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
2119ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattnernamespace llvm {
2272e606e2bd76452ac6760ceed258b377cd8862a2Chris Lattner  template<typename ItTy = User::const_op_iterator>
2343cb041754df231f488fa7c203f13ec731ca389cChris Lattner  class generic_gep_type_iterator
24db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
257362ce08cb2c1f0b544b18dbc21630fb4baebcfcGabor Greif    typedef std::iterator<std::forward_iterator_tag,
26db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner                          Type *, ptrdiff_t> super;
2719ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
2843cb041754df231f488fa7c203f13ec731ca389cChris Lattner    ItTy OpIt;
29db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Type *CurTy;
3043cb041754df231f488fa7c203f13ec731ca389cChris Lattner    generic_gep_type_iterator() {}
3119ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner  public:
3219ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
33db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
3443cb041754df231f488fa7c203f13ec731ca389cChris Lattner      generic_gep_type_iterator I;
352425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner      I.CurTy = Ty;
362425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner      I.OpIt = It;
3719ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner      return I;
3819ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    }
3943cb041754df231f488fa7c203f13ec731ca389cChris Lattner    static generic_gep_type_iterator end(ItTy It) {
4043cb041754df231f488fa7c203f13ec731ca389cChris Lattner      generic_gep_type_iterator I;
41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      I.CurTy = nullptr;
422425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner      I.OpIt = It;
4319ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner      return I;
4419ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    }
4519ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
4663b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman    bool operator==(const generic_gep_type_iterator& x) const {
472425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner      return OpIt == x.OpIt;
4819ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    }
4943cb041754df231f488fa7c203f13ec731ca389cChris Lattner    bool operator!=(const generic_gep_type_iterator& x) const {
5019ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner      return !operator==(x);
5119ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    }
5219ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
53db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Type *operator*() const {
5419ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner      return CurTy;
5519ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    }
5619ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
57db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Type *getIndexedType() const {
58db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner      CompositeType *CT = cast<CompositeType>(CurTy);
5979bda7fbe23e6668e1ee53a80f91856f152600a6Chris Lattner      return CT->getTypeAtIndex(getOperand());
6079bda7fbe23e6668e1ee53a80f91856f152600a6Chris Lattner    }
6179bda7fbe23e6668e1ee53a80f91856f152600a6Chris Lattner
6219ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    // This is a non-standard operator->.  It allows you to call methods on the
6319ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    // current type directly.
64db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Type *operator->() const { return operator*(); }
6563b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman
662425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner    Value *getOperand() const { return *OpIt; }
6719ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
6843cb041754df231f488fa7c203f13ec731ca389cChris Lattner    generic_gep_type_iterator& operator++() {   // Preincrement
69db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner      if (CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
7019ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner        CurTy = CT->getTypeAtIndex(getOperand());
7119ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner      } else {
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        CurTy = nullptr;
7319ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner      }
742425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner      ++OpIt;
7563b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman      return *this;
7619ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    }
7719ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
7843cb041754df231f488fa7c203f13ec731ca389cChris Lattner    generic_gep_type_iterator operator++(int) { // Postincrement
7963b3afa98460ce38a1c48d3c44ef6edfdaf37b77Misha Brukman      generic_gep_type_iterator tmp = *this; ++*this; return tmp;
8019ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner    }
8119ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner  };
8219ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
8343cb041754df231f488fa7c203f13ec731ca389cChris Lattner  typedef generic_gep_type_iterator<> gep_type_iterator;
8443cb041754df231f488fa7c203f13ec731ca389cChris Lattner
8572e606e2bd76452ac6760ceed258b377cd8862a2Chris Lattner  inline gep_type_iterator gep_type_begin(const User *GEP) {
86707276d415002fb37ac3fbc50c66905a4ffe1f75Duncan Sands    return gep_type_iterator::begin
87707276d415002fb37ac3fbc50c66905a4ffe1f75Duncan Sands      (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1);
8819ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner  }
8972e606e2bd76452ac6760ceed258b377cd8862a2Chris Lattner  inline gep_type_iterator gep_type_end(const User *GEP) {
902425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner    return gep_type_iterator::end(GEP->op_end());
9119ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner  }
9272e606e2bd76452ac6760ceed258b377cd8862a2Chris Lattner  inline gep_type_iterator gep_type_begin(const User &GEP) {
93707276d415002fb37ac3fbc50c66905a4ffe1f75Duncan Sands    return gep_type_iterator::begin
94707276d415002fb37ac3fbc50c66905a4ffe1f75Duncan Sands      (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1);
95c4c6b9e5bc062763578eb63a011f447de1eeddc6Chris Lattner  }
9672e606e2bd76452ac6760ceed258b377cd8862a2Chris Lattner  inline gep_type_iterator gep_type_end(const User &GEP) {
972425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner    return gep_type_iterator::end(GEP.op_end());
982425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner  }
9943cb041754df231f488fa7c203f13ec731ca389cChris Lattner
100ca12a2139e7ed8b5f30df9927494dd7aae929a7cJay Foad  template<typename T>
101ca12a2139e7ed8b5f30df9927494dd7aae929a7cJay Foad  inline generic_gep_type_iterator<const T *>
102ca12a2139e7ed8b5f30df9927494dd7aae929a7cJay Foad  gep_type_begin(Type *Op0, ArrayRef<T> A) {
103ca12a2139e7ed8b5f30df9927494dd7aae929a7cJay Foad    return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
1042425f8c62931f6ab127784adbf6f52bc8c684113Chris Lattner  }
10543cb041754df231f488fa7c203f13ec731ca389cChris Lattner
106ca12a2139e7ed8b5f30df9927494dd7aae929a7cJay Foad  template<typename T>
107ca12a2139e7ed8b5f30df9927494dd7aae929a7cJay Foad  inline generic_gep_type_iterator<const T *>
10848d5e750a8189c55087333d2bbc5dd0e1e07ddfaDuncan Sands  gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
109ca12a2139e7ed8b5f30df9927494dd7aae929a7cJay Foad    return generic_gep_type_iterator<const T *>::end(A.end());
110c4c6b9e5bc062763578eb63a011f447de1eeddc6Chris Lattner  }
11119ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner} // end namespace llvm
11219ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner
11319ed305339b13178c0dc05ee68fd9999ea17c469Chris Lattner#endif
114