This patch removes all uses of `std::iterator`, which was deprecated in C++17.
While this isn't currently an issue while compiling LLVM, it's useful for those using LLVM as a library.
For some reason there're a few places that were seemingly able to use `std` functions unqualified, which no longer works after this patch. I've updated those places, but I'm not really sure why it worked in the first place.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D67586
};
template <typename DERIVED, typename REFERENCE>
-class StmtIteratorImpl : public StmtIteratorBase,
- public std::iterator<std::forward_iterator_tag,
- REFERENCE, ptrdiff_t,
- REFERENCE, REFERENCE> {
+class StmtIteratorImpl : public StmtIteratorBase {
protected:
StmtIteratorImpl(const StmtIteratorBase& RHS) : StmtIteratorBase(RHS) {}
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = REFERENCE;
+ using difference_type = std::ptrdiff_t;
+ using pointer = REFERENCE;
+ using reference = REFERENCE;
+
StmtIteratorImpl() = default;
StmtIteratorImpl(Stmt **s) : StmtIteratorBase(s) {}
StmtIteratorImpl(Decl **dgi, Decl **dge) : StmtIteratorBase(dgi, dge) {}
/// over bytes that are in a RopePieceBTree. This first iterates over bytes
/// in a RopePiece, then iterates over RopePiece's in a RopePieceBTreeLeaf,
/// then iterates over RopePieceBTreeLeaf's in a RopePieceBTree.
- class RopePieceBTreeIterator :
- public std::iterator<std::forward_iterator_tag, const char, ptrdiff_t> {
+ class RopePieceBTreeIterator {
/// CurNode - The current B+Tree node that we are inspecting.
const void /*RopePieceBTreeLeaf*/ *CurNode = nullptr;
unsigned CurChar = 0;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = const char;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
RopePieceBTreeIterator() = default;
RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
class SetType =
bf_iterator_default_set<typename GraphTraits<GraphT>::NodeRef>,
class GT = GraphTraits<GraphT>>
-class bf_iterator
- : public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
- public bf_iterator_storage<SetType> {
- using super = std::iterator<std::forward_iterator_tag, typename GT::NodeRef>;
+class bf_iterator : public bf_iterator_storage<SetType> {
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = typename GT::NodeRef;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+private:
using NodeRef = typename GT::NodeRef;
using ChildItTy = typename GT::ChildIteratorType;
// Current level.
unsigned Level;
-private:
inline bf_iterator(NodeRef Node) {
this->Visited.insert(Node);
Level = 0;
}
public:
- using pointer = typename super::pointer;
-
// Provide static begin and end methods as our public "constructors"
static bf_iterator begin(const GraphT &G) {
return bf_iterator(GT::getEntryNode(G));
bool operator!=(const ThisT &RHS) const { return !operator==(RHS); }
- class const_iterator
- : public std::iterator<std::forward_iterator_tag, IndexT> {
+ class const_iterator {
friend class CoalescingBitVector;
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = IndexT;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+ private:
// For performance reasons, make the offset at the end different than the
// one used in \ref begin, to optimize the common `It == end()` pattern.
static constexpr unsigned kIteratorAtTheEndOffset = ~0u;
class SetType =
df_iterator_default_set<typename GraphTraits<GraphT>::NodeRef>,
bool ExtStorage = false, class GT = GraphTraits<GraphT>>
-class df_iterator
- : public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
- public df_iterator_storage<SetType, ExtStorage> {
- using super = std::iterator<std::forward_iterator_tag, typename GT::NodeRef>;
+class df_iterator : public df_iterator_storage<SetType, ExtStorage> {
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = typename GT::NodeRef;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+private:
using NodeRef = typename GT::NodeRef;
using ChildItTy = typename GT::ChildIteratorType;
// VisitStack - Used to maintain the ordering. Top = current block
std::vector<StackElement> VisitStack;
-private:
inline df_iterator(NodeRef Node) {
this->Visited.insert(Node);
VisitStack.push_back(StackElement(Node, None));
}
public:
- using pointer = typename super::pointer;
-
// Provide static begin and end methods as our public "constructors"
static df_iterator begin(const GraphT &G) {
return df_iterator(GT::getEntryNode(G));
return It != member_end() && It == findLeader(V2);
}
- class member_iterator : public std::iterator<std::forward_iterator_tag,
- const ElemTy, ptrdiff_t> {
+ class member_iterator {
friend class EquivalenceClasses;
- using super = std::iterator<std::forward_iterator_tag,
- const ElemTy, ptrdiff_t>;
-
const ECValue *Node;
public:
- using size_type = size_t;
- using pointer = typename super::pointer;
- using reference = typename super::reference;
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = const ElemTy;
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
explicit member_iterator() = default;
explicit member_iterator(const ECValue *N) : Node(N) {}
// Immutable AVL-Tree Iterators.
//===----------------------------------------------------------------------===//
-template <typename ImutInfo>
-class ImutAVLTreeGenericIterator
- : public std::iterator<std::bidirectional_iterator_tag,
- ImutAVLTree<ImutInfo>> {
+template <typename ImutInfo> class ImutAVLTreeGenericIterator {
SmallVector<uintptr_t,20> stack;
public:
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = ImutAVLTree<ImutInfo>;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
Flags=0x3 };
}
};
-template <typename ImutInfo>
-class ImutAVLTreeInOrderIterator
- : public std::iterator<std::bidirectional_iterator_tag,
- ImutAVLTree<ImutInfo>> {
+template <typename ImutInfo> class ImutAVLTreeInOrderIterator {
using InternalIteratorTy = ImutAVLTreeGenericIterator<ImutInfo>;
InternalIteratorTy InternalItr;
public:
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = ImutAVLTree<ImutInfo>;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
using TreeTy = ImutAVLTree<ImutInfo>;
ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
// };
//
// template <typename KeyT, typename ValT, unsigned N, typename Traits>
-// class IntervalMap::const_iterator :
-// public std::iterator<std::bidirectional_iterator_tag, ValT> {
+// class IntervalMap::const_iterator {
// public:
+// using iterator_category = std::bidirectional_iterator_tag;
+// using value_type = ValT;
+// using difference_type = std::ptrdiff_t;
+// using pointer = value_type *;
+// using reference = value_type &;
+//
// bool operator==(const const_iterator &) const;
// bool operator!=(const const_iterator &) const;
// bool valid() const;
//===----------------------------------------------------------------------===//
template <typename KeyT, typename ValT, unsigned N, typename Traits>
-class IntervalMap<KeyT, ValT, N, Traits>::const_iterator :
- public std::iterator<std::bidirectional_iterator_tag, ValT> {
-
-protected:
+class IntervalMap<KeyT, ValT, N, Traits>::const_iterator {
friend class IntervalMap;
+public:
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = ValT;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+protected:
// The map referred to.
IntervalMap *map = nullptr;
};
template <class GraphT,
- class SetType =
- SmallPtrSet<typename GraphTraits<GraphT>::NodeRef, 8>,
+ class SetType = SmallPtrSet<typename GraphTraits<GraphT>::NodeRef, 8>,
bool ExtStorage = false, class GT = GraphTraits<GraphT>>
-class po_iterator
- : public std::iterator<std::forward_iterator_tag, typename GT::NodeRef>,
- public po_iterator_storage<SetType, ExtStorage> {
- using super = std::iterator<std::forward_iterator_tag, typename GT::NodeRef>;
+class po_iterator : public po_iterator_storage<SetType, ExtStorage> {
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = typename GT::NodeRef;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+private:
using NodeRef = typename GT::NodeRef;
using ChildItTy = typename GT::ChildIteratorType;
}
public:
- using pointer = typename super::pointer;
-
// Provide static "constructors"...
static po_iterator begin(GraphT G) {
return po_iterator(GT::getEntryNode(G));
/// Our iterators are iterators over the collection of objects that share a
/// key.
- template<typename SMSPtrTy>
- class iterator_base : public std::iterator<std::bidirectional_iterator_tag,
- ValueT> {
+ template <typename SMSPtrTy> class iterator_base {
friend class SparseMultiSet;
+ public:
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = ValueT;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+ private:
SMSPtrTy SMS;
unsigned Idx;
unsigned SparseIdx;
void setNext(unsigned N) { SMS->Dense[Idx].Next = N; }
public:
- using super = std::iterator<std::bidirectional_iterator_tag, ValueT>;
- using value_type = typename super::value_type;
- using difference_type = typename super::difference_type;
- using pointer = typename super::pointer;
- using reference = typename super::reference;
-
reference operator*() const {
assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
"Dereferencing iterator of invalid key or index");
RangePair equal_range(const KeyT &K) {
iterator B = find(K);
iterator E = iterator(this, SMSNode::INVALID, B.SparseIdx);
- return make_pair(B, E);
+ return std::make_pair(B, E);
}
/// Insert a new element at the tail of the subset list. Returns an iterator
template <typename DerivedT, typename IteratorCategoryT, typename T,
typename DifferenceTypeT = std::ptrdiff_t, typename PointerT = T *,
typename ReferenceT = T &>
-class iterator_facade_base
- : public std::iterator<IteratorCategoryT, T, DifferenceTypeT, PointerT,
- ReferenceT> {
+class iterator_facade_base {
+public:
+ using iterator_category = IteratorCategoryT;
+ using value_type = T;
+ using difference_type = DifferenceTypeT;
+ using pointer = PointerT;
+ using reference = ReferenceT;
+
protected:
enum {
IsRandomAccess = std::is_base_of<std::random_access_iterator_tag,
void dump() const;
/// Define an iterator for alias sets... this is just a forward iterator.
- class iterator : public std::iterator<std::forward_iterator_tag,
- PointerRec, ptrdiff_t> {
+ class iterator {
PointerRec *CurNode;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = PointerRec;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
explicit iterator(PointerRec *CN = nullptr) : CurNode(CN) {}
bool operator==(const iterator& x) const {
return MP->getIncomingBlock(ArgNo);
}
- typename BaseT::iterator::pointer operator*() const {
+ typename std::iterator_traits<BaseT>::pointer operator*() const {
assert(Access && "Tried to access past the end of our iterator");
// Go to the first argument for phis, and the defining access for everything
// else.
return DefIterator == Other.DefIterator;
}
- BaseT::iterator::reference operator*() const {
+ typename std::iterator_traits<BaseT>::reference operator*() const {
assert(DefIterator != OriginalAccess->defs_end() &&
"Tried to access past the end of our iterator");
return CurrentPair;
///
/// For a subregion RegionNode there is just one successor. The RegionNode
/// representing the exit of the subregion.
-template <class NodeRef, class BlockT, class RegionT>
-class RNSuccIterator
- : public std::iterator<std::forward_iterator_tag, NodeRef> {
- using super = std::iterator<std::forward_iterator_tag, NodeRef>;
+template <class NodeRef, class BlockT, class RegionT> class RNSuccIterator {
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = NodeRef;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+private:
using BlockTraits = GraphTraits<BlockT *>;
using SuccIterTy = typename BlockTraits::ChildIteratorType;
public:
using Self = RNSuccIterator<NodeRef, BlockT, RegionT>;
- using value_type = typename super::value_type;
/// Create begin iterator of a RegionNode.
inline RNSuccIterator(NodeRef node)
/// are contained in the Region and its subregions. This is close to a virtual
/// control flow graph of the Region.
template <class NodeRef, class BlockT, class RegionT>
-class RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>
- : public std::iterator<std::forward_iterator_tag, NodeRef> {
- using super = std::iterator<std::forward_iterator_tag, NodeRef>;
+class RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT> {
using BlockTraits = GraphTraits<BlockT *>;
using SuccIterTy = typename BlockTraits::ChildIteratorType;
SuccIterTy Itor;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = NodeRef;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
using Self = RNSuccIterator<FlatIt<NodeRef>, BlockT, RegionT>;
- using value_type = typename super::value_type;
/// Create the iterator from a RegionNode.
///
/// when incrementing.
template <bool ReturnUses, bool ReturnDefs, bool SkipDebug, bool ByOperand,
bool ByInstr, bool ByBundle>
- class defusechain_iterator : public std::iterator<std::forward_iterator_tag,
- MachineOperand, ptrdiff_t> {
+ class defusechain_iterator {
friend class MachineRegisterInfo;
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = MachineOperand;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+ private:
MachineOperand *Op = nullptr;
explicit defusechain_iterator(MachineOperand *op) : Op(op) {
}
public:
- using reference = std::iterator<std::forward_iterator_tag, MachineOperand,
- ptrdiff_t>::reference;
- using pointer = std::iterator<std::forward_iterator_tag, MachineOperand,
- ptrdiff_t>::pointer;
-
defusechain_iterator() = default;
bool operator==(const defusechain_iterator &x) const {
/// returns defs. If neither are true then you are silly and it always
/// returns end(). If SkipDebug is true it skips uses marked Debug
/// when incrementing.
- template<bool ReturnUses, bool ReturnDefs, bool SkipDebug,
- bool ByOperand, bool ByInstr, bool ByBundle>
- class defusechain_instr_iterator
- : public std::iterator<std::forward_iterator_tag, MachineInstr, ptrdiff_t> {
+ template <bool ReturnUses, bool ReturnDefs, bool SkipDebug, bool ByOperand,
+ bool ByInstr, bool ByBundle>
+ class defusechain_instr_iterator {
friend class MachineRegisterInfo;
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = MachineInstr;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+ private:
MachineOperand *Op = nullptr;
explicit defusechain_instr_iterator(MachineOperand *op) : Op(op) {
}
public:
- using reference = std::iterator<std::forward_iterator_tag,
- MachineInstr, ptrdiff_t>::reference;
- using pointer = std::iterator<std::forward_iterator_tag,
- MachineInstr, ptrdiff_t>::pointer;
-
defusechain_instr_iterator() = default;
bool operator==(const defusechain_instr_iterator &x) const {
const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
};
- class SUnitIterator : public std::iterator<std::forward_iterator_tag,
- SUnit, ptrdiff_t> {
+ class SUnitIterator {
SUnit *Node;
unsigned Operand;
SUnitIterator(SUnit *N, unsigned Op) : Node(N), Operand(Op) {}
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = SUnit;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
bool operator==(const SUnitIterator& x) const {
return Operand == x.Operand;
}
/// This class provides iterator support for SDUse
/// operands that use a specific SDNode.
- class use_iterator
- : public std::iterator<std::forward_iterator_tag, SDUse, ptrdiff_t> {
+ class use_iterator {
friend class SDNode;
SDUse *Op = nullptr;
explicit use_iterator(SDUse *op) : Op(op) {}
public:
- using reference = std::iterator<std::forward_iterator_tag,
- SDUse, ptrdiff_t>::reference;
- using pointer = std::iterator<std::forward_iterator_tag,
- SDUse, ptrdiff_t>::pointer;
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = SDUse;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
use_iterator() = default;
use_iterator(const use_iterator &I) : Op(I.Op) {}
}
};
-class SDNodeIterator : public std::iterator<std::forward_iterator_tag,
- SDNode, ptrdiff_t> {
+class SDNodeIterator {
const SDNode *Node;
unsigned Operand;
SDNodeIterator(const SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = SDNode;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
bool operator==(const SDNodeIterator& x) const {
return Operand == x.Operand;
}
friend class ValueIterator;
};
- class ValueIterator : public std::iterator<std::input_iterator_tag, Entry> {
+ class ValueIterator {
const AppleAcceleratorTable *AccelTable = nullptr;
Entry Current; ///< The current entry.
uint64_t DataOffset = 0; ///< Offset into the section.
/// Advance the iterator.
void Next();
+
public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = Entry;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
/// Construct a new iterator for the entries at \p DataOffset.
ValueIterator(const AppleAcceleratorTable &AccelTable, uint64_t DataOffset);
/// End marker.
friend class DWARFDebugNames;
};
- class ValueIterator : public std::iterator<std::input_iterator_tag, Entry> {
+ class ValueIterator {
+ public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = Entry;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+ private:
/// The Name Index we are currently iterating through. The implementation
/// relies on the fact that this can also be used as an iterator into the
/// "NameIndices" vector in the Accelerator section.
//===----------------------------------------------------------------------===//
template <class Ptr, class USE_iterator> // Predecessor Iterator
-class PredIterator : public std::iterator<std::forward_iterator_tag,
- Ptr, ptrdiff_t, Ptr*, Ptr*> {
- using super =
- std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t, Ptr*, Ptr*>;
+class PredIterator {
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = Ptr;
+ using difference_type = std::ptrdiff_t;
+ using pointer = Ptr *;
+ using reference = Ptr *;
+
+private:
using Self = PredIterator<Ptr, USE_iterator>;
USE_iterator It;
}
public:
- using pointer = typename super::pointer;
- using reference = typename super::reference;
-
PredIterator() = default;
explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) {
advancePastNonTerminators();
return cast_or_null<DIType>(N->getOperand(I));
}
- class iterator : std::iterator<std::input_iterator_tag, DIType *,
- std::ptrdiff_t, void, DIType *> {
+ class iterator {
MDNode::op_iterator I = nullptr;
public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = DIType *;
+ using difference_type = std::ptrdiff_t;
+ using pointer = void;
+ using reference = DIType *;
+
iterator() = default;
explicit iterator(MDNode::op_iterator I) : I(I) {}
};
/// An iterator for expression operands.
- class expr_op_iterator
- : public std::iterator<std::input_iterator_tag, ExprOperand> {
+ class expr_op_iterator {
ExprOperand Op;
public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = ExprOperand;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
expr_op_iterator() = default;
explicit expr_op_iterator(element_iterator I) : Op(I) {}
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<>;
///
/// An iterator that transforms an \a MDNode::iterator into an iterator over a
/// particular Metadata subclass.
-template <class T>
-class TypedMDOperandIterator
- : public std::iterator<std::input_iterator_tag, T *, std::ptrdiff_t, void,
- T *> {
+template <class T> class TypedMDOperandIterator {
MDNode::op_iterator I = nullptr;
public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = T *;
+ using difference_type = std::ptrdiff_t;
+ using pointer = void;
+ using reference = T *;
+
TypedMDOperandIterator() = default;
explicit TypedMDOperandIterator(MDNode::op_iterator I) : I(I) {}
explicit NamedMDNode(const Twine &N);
- template<class T1, class T2>
- class op_iterator_impl :
- public std::iterator<std::bidirectional_iterator_tag, T2> {
+ template <class T1, class T2> class op_iterator_impl {
friend class NamedMDNode;
const NamedMDNode *Node = nullptr;
op_iterator_impl(const NamedMDNode *N, unsigned i) : Node(N), Idx(i) {}
public:
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = T2;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
op_iterator_impl() = default;
bool operator==(const op_iterator_impl &o) const { return Idx == o.Idx; }
}
/// An iterator for DICompileUnits that skips those marked NoDebug.
- class debug_compile_units_iterator
- : public std::iterator<std::input_iterator_tag, DICompileUnit *> {
+ class debug_compile_units_iterator {
NamedMDNode *CUs;
unsigned Idx;
void SkipNoDebugCUs();
public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = DICompileUnit *;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
explicit debug_compile_units_iterator(NamedMDNode *CUs, unsigned Idx)
: CUs(CUs), Idx(Idx) {
SkipNoDebugCUs();
private:
template <typename UseT> // UseT == 'Use' or 'const Use'
- class use_iterator_impl
- : public std::iterator<std::forward_iterator_tag, UseT *> {
+ class use_iterator_impl {
friend class Value;
UseT *U;
explicit use_iterator_impl(UseT *u) : U(u) {}
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = UseT *;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
use_iterator_impl() : U() {}
bool operator==(const use_iterator_impl &x) const { return U == x.U; }
};
template <typename UserTy> // UserTy == 'User' or 'const User'
- class user_iterator_impl
- : public std::iterator<std::forward_iterator_tag, UserTy *> {
+ class user_iterator_impl {
use_iterator_impl<Use> UI;
explicit user_iterator_impl(Use *U) : UI(U) {}
friend class Value;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = UserTy *;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
user_iterator_impl() = default;
bool operator==(const user_iterator_impl &x) const { return UI == x.UI; }
}
};
-template<typename DenseMapT, typename KeyT>
-class ValueMapIterator :
- public std::iterator<std::forward_iterator_tag,
- std::pair<KeyT, typename DenseMapT::mapped_type>,
- ptrdiff_t> {
+template <typename DenseMapT, typename KeyT> class ValueMapIterator {
using BaseT = typename DenseMapT::iterator;
using ValueT = typename DenseMapT::mapped_type;
BaseT I;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = std::pair<KeyT, typename DenseMapT::mapped_type>;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
ValueMapIterator() : I() {}
ValueMapIterator(BaseT I) : I(I) {}
}
};
-template<typename DenseMapT, typename KeyT>
-class ValueMapConstIterator :
- public std::iterator<std::forward_iterator_tag,
- std::pair<KeyT, typename DenseMapT::mapped_type>,
- ptrdiff_t> {
+template <typename DenseMapT, typename KeyT> class ValueMapConstIterator {
using BaseT = typename DenseMapT::const_iterator;
using ValueT = typename DenseMapT::mapped_type;
BaseT I;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = std::pair<KeyT, typename DenseMapT::mapped_type>;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
ValueMapConstIterator() : I() {}
ValueMapConstIterator(BaseT I) : I(I) {}
ValueMapConstIterator(ValueMapIterator<DenseMapT, KeyT> Other)
Elf_Word getType() const { return Nhdr.n_type; }
};
-template <class ELFT>
-class Elf_Note_Iterator_Impl
- : std::iterator<std::forward_iterator_tag, Elf_Note_Impl<ELFT>> {
+template <class ELFT> class Elf_Note_Iterator_Impl {
+public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = Elf_Note_Impl<ELFT>;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+private:
// Nhdr being a nullptr marks the end of iteration.
const Elf_Nhdr_Impl<ELFT> *Nhdr = nullptr;
size_t RemainingSize = 0u;
return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
}
-template <class content_type>
-class content_iterator
- : public std::iterator<std::forward_iterator_tag, content_type> {
+template <class content_type> class content_iterator {
content_type Current;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = content_type;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
content_iterator(content_type symb) : Current(std::move(symb)) {}
const content_type *operator->() const { return &Current; }
};
/// A file format agnostic iterator over coverage mapping data.
-class CoverageMappingIterator
- : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> {
+class CoverageMappingIterator {
CoverageMappingReader *Reader;
CoverageMappingRecord Record;
coveragemap_error ReadErr;
void increment();
public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = CoverageMappingRecord;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
CoverageMappingIterator()
: Reader(nullptr), Record(), ReadErr(coveragemap_error::success) {}
class InstrProfReader;
/// A file format agnostic iterator over profiling data.
-class InstrProfIterator : public std::iterator<std::input_iterator_tag,
- NamedInstrProfRecord> {
+class InstrProfIterator {
+public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = NamedInstrProfRecord;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
+private:
InstrProfReader *Reader = nullptr;
value_type Record;
/// character.
///
/// Note that this iterator requires the buffer to be nul terminated.
-class line_iterator
- : public std::iterator<std::forward_iterator_tag, StringRef> {
+class line_iterator {
Optional<MemoryBufferRef> Buffer;
char CommentMarker = '\0';
bool SkipBlanks = true;
StringRef CurrentLine;
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = StringRef;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
/// Default construct an "end" iterator.
line_iterator() = default;
// function).
TargetRegistry() = delete;
- class iterator
- : public std::iterator<std::forward_iterator_tag, Target, ptrdiff_t> {
+ class iterator {
friend struct TargetRegistry;
const Target *Current = nullptr;
explicit iterator(Target *T) : Current(T) {}
public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = Target;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
iterator() = default;
bool operator==(const iterator &x) const { return Current == x.Current; }
///
/// BaseT must have a ValueT* member named CurrentEntry and a member function
/// increment() which must set CurrentEntry to 0 to create an end iterator.
-template <class BaseT, class ValueT>
-class basic_collection_iterator
- : public std::iterator<std::input_iterator_tag, ValueT> {
+template <class BaseT, class ValueT> class basic_collection_iterator {
public:
+ using iterator_category = std::input_iterator_tag;
+ using value_type = ValueT;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
basic_collection_iterator() = default;
basic_collection_iterator(BaseT *B) : Base(B) {}
return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h);
}
- template <typename Ty>
- class arch_iterator
- : public std::iterator<std::forward_iterator_tag, Architecture, size_t> {
+ template <typename Ty> class arch_iterator {
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = Architecture;
+ using difference_type = std::size_t;
+ using pointer = value_type *;
+ using reference = value_type &;
+
private:
ArchSetType Index;
Ty *ArchSet;
}
};
-class op_inserter
- : public std::iterator<std::output_iterator_tag, void, void, void, void> {
+class op_inserter {
private:
using Container = BasicExpression;
Container *BE;
public:
+ using iterator_category = std::output_iterator_tag;
+ using value_type = void;
+ using difference_type = void;
+ using pointer = void;
+ using reference = void;
+
explicit op_inserter(BasicExpression &E) : BE(&E) {}
explicit op_inserter(BasicExpression *E) : BE(E) {}
}
};
-class int_op_inserter
- : public std::iterator<std::output_iterator_tag, void, void, void, void> {
+class int_op_inserter {
private:
using Container = AggregateValueExpression;
Container *AVE;
public:
+ using iterator_category = std::output_iterator_tag;
+ using value_type = void;
+ using difference_type = void;
+ using pointer = void;
+ using reference = void;
+
explicit int_op_inserter(AggregateValueExpression &E) : AVE(&E) {}
explicit int_op_inserter(AggregateValueExpression *E) : AVE(E) {}
};
/// The post order traversal iteration is done to know the status of
/// isHiddenBasicBlock for all the successors on the current BB.
- for_each(po_begin(&F->getEntryBlock()), po_end(&F->getEntryBlock()),
- evaluateBB);
+ llvm::for_each(post_order(&F->getEntryBlock()), evaluateBB);
}
bool DOTGraphTraits<DOTFuncInfo *>::isNodeHidden(const BasicBlock *Node,
if (isExtern) {
symbol_iterator SI = O->symbol_begin();
- advance(SI, Val);
+ std::advance(SI, Val);
S = unwrapOrError(SI->getName(), FileName);
} else {
section_iterator SI = O->section_begin();
uint32_t I = Val - 1;
while (I != 0 && SI != O->section_end()) {
--I;
- advance(SI, 1);
+ std::advance(SI, 1);
}
if (SI == O->section_end()) {
Fmt << Val << " (?,?)";
};
/// An iterator for virtual operands.
-class VirtualOperandIterator
- : public std::iterator<std::forward_iterator_tag, VirtualUse> {
+class VirtualOperandIterator {
friend class VirtualInstruction;
friend class VirtualUse;
- using super = std::iterator<std::forward_iterator_tag, VirtualUse>;
using Self = VirtualOperandIterator;
ScopStmt *User;
: User(User), U(U) {}
public:
- using pointer = typename super::pointer;
- using reference = typename super::reference;
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = VirtualUse;
+ using difference_type = std::ptrdiff_t;
+ using pointer = value_type *;
+ using reference = value_type &;
inline bool operator==(const Self &that) const {
assert(this->User == that.User);