diff --git a/clang/include/clang/AST/StmtIterator.h b/clang/include/clang/AST/StmtIterator.h --- a/clang/include/clang/AST/StmtIterator.h +++ b/clang/include/clang/AST/StmtIterator.h @@ -74,14 +74,17 @@ }; template -class StmtIteratorImpl : public StmtIteratorBase, - public std::iterator { +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) {} diff --git a/clang/include/clang/Rewrite/Core/RewriteRope.h b/clang/include/clang/Rewrite/Core/RewriteRope.h --- a/clang/include/clang/Rewrite/Core/RewriteRope.h +++ b/clang/include/clang/Rewrite/Core/RewriteRope.h @@ -83,8 +83,7 @@ /// 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 { + class RopePieceBTreeIterator { /// CurNode - The current B+Tree node that we are inspecting. const void /*RopePieceBTreeLeaf*/ *CurNode = nullptr; @@ -96,6 +95,12 @@ 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); diff --git a/llvm/include/llvm/ADT/BreadthFirstIterator.h b/llvm/include/llvm/ADT/BreadthFirstIterator.h --- a/llvm/include/llvm/ADT/BreadthFirstIterator.h +++ b/llvm/include/llvm/ADT/BreadthFirstIterator.h @@ -44,11 +44,15 @@ class SetType = bf_iterator_default_set::NodeRef>, class GT = GraphTraits> -class bf_iterator - : public std::iterator, - public bf_iterator_storage { - using super = std::iterator; +class bf_iterator : public bf_iterator_storage { +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; @@ -62,7 +66,6 @@ // Current level. unsigned Level; -private: inline bf_iterator(NodeRef Node) { this->Visited.insert(Node); Level = 0; @@ -107,8 +110,6 @@ } 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)); diff --git a/llvm/include/llvm/ADT/CoalescingBitVector.h b/llvm/include/llvm/ADT/CoalescingBitVector.h --- a/llvm/include/llvm/ADT/CoalescingBitVector.h +++ b/llvm/include/llvm/ADT/CoalescingBitVector.h @@ -231,10 +231,17 @@ bool operator!=(const ThisT &RHS) const { return !operator==(RHS); } - class const_iterator - : public std::iterator { + 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; diff --git a/llvm/include/llvm/ADT/DepthFirstIterator.h b/llvm/include/llvm/ADT/DepthFirstIterator.h --- a/llvm/include/llvm/ADT/DepthFirstIterator.h +++ b/llvm/include/llvm/ADT/DepthFirstIterator.h @@ -82,10 +82,15 @@ class SetType = df_iterator_default_set::NodeRef>, bool ExtStorage = false, class GT = GraphTraits> -class df_iterator - : public std::iterator, - public df_iterator_storage { - using super = std::iterator; +class df_iterator : public df_iterator_storage { +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; @@ -97,7 +102,6 @@ // VisitStack - Used to maintain the ordering. Top = current block std::vector VisitStack; -private: inline df_iterator(NodeRef Node) { this->Visited.insert(Node); VisitStack.push_back(StackElement(Node, None)); @@ -144,8 +148,6 @@ } 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)); diff --git a/llvm/include/llvm/ADT/EquivalenceClasses.h b/llvm/include/llvm/ADT/EquivalenceClasses.h --- a/llvm/include/llvm/ADT/EquivalenceClasses.h +++ b/llvm/include/llvm/ADT/EquivalenceClasses.h @@ -248,19 +248,18 @@ return It != member_end() && It == findLeader(V2); } - class member_iterator : public std::iterator { + class member_iterator { friend class EquivalenceClasses; - using super = std::iterator; - 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) {} diff --git a/llvm/include/llvm/ADT/ImmutableSet.h b/llvm/include/llvm/ADT/ImmutableSet.h --- a/llvm/include/llvm/ADT/ImmutableSet.h +++ b/llvm/include/llvm/ADT/ImmutableSet.h @@ -651,13 +651,16 @@ // Immutable AVL-Tree Iterators. //===----------------------------------------------------------------------===// -template -class ImutAVLTreeGenericIterator - : public std::iterator> { +template class ImutAVLTreeGenericIterator { SmallVector stack; public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = ImutAVLTree; + using difference_type = std::ptrdiff_t; + using pointer = value_type *; + using reference = value_type &; + enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3, Flags=0x3 }; @@ -762,15 +765,18 @@ } }; -template -class ImutAVLTreeInOrderIterator - : public std::iterator> { +template class ImutAVLTreeInOrderIterator { using InternalIteratorTy = ImutAVLTreeGenericIterator; InternalIteratorTy InternalItr; public: + using iterator_category = std::bidirectional_iterator_tag; + using value_type = ImutAVLTree; + using difference_type = std::ptrdiff_t; + using pointer = value_type *; + using reference = value_type &; + using TreeTy = ImutAVLTree; ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) { diff --git a/llvm/include/llvm/ADT/IntervalMap.h b/llvm/include/llvm/ADT/IntervalMap.h --- a/llvm/include/llvm/ADT/IntervalMap.h +++ b/llvm/include/llvm/ADT/IntervalMap.h @@ -63,9 +63,14 @@ // }; // // template -// class IntervalMap::const_iterator : -// public std::iterator { +// 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; @@ -1289,12 +1294,17 @@ //===----------------------------------------------------------------------===// template -class IntervalMap::const_iterator : - public std::iterator { - -protected: +class IntervalMap::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; diff --git a/llvm/include/llvm/ADT/PostOrderIterator.h b/llvm/include/llvm/ADT/PostOrderIterator.h --- a/llvm/include/llvm/ADT/PostOrderIterator.h +++ b/llvm/include/llvm/ADT/PostOrderIterator.h @@ -90,13 +90,17 @@ }; template ::NodeRef, 8>, + class SetType = SmallPtrSet::NodeRef, 8>, bool ExtStorage = false, class GT = GraphTraits> -class po_iterator - : public std::iterator, - public po_iterator_storage { - using super = std::iterator; +class po_iterator : public po_iterator_storage { +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; @@ -135,8 +139,6 @@ } public: - using pointer = typename super::pointer; - // Provide static "constructors"... static po_iterator begin(GraphT G) { return po_iterator(GT::getEntryNode(G)); diff --git a/llvm/include/llvm/ADT/SparseMultiSet.h b/llvm/include/llvm/ADT/SparseMultiSet.h --- a/llvm/include/llvm/ADT/SparseMultiSet.h +++ b/llvm/include/llvm/ADT/SparseMultiSet.h @@ -216,11 +216,17 @@ /// Our iterators are iterators over the collection of objects that share a /// key. - template - class iterator_base : public std::iterator { + template 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; @@ -247,12 +253,6 @@ void setNext(unsigned N) { SMS->Dense[Idx].Next = N; } public: - using super = std::iterator; - 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"); @@ -411,7 +411,7 @@ 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 diff --git a/llvm/include/llvm/ADT/iterator.h b/llvm/include/llvm/ADT/iterator.h --- a/llvm/include/llvm/ADT/iterator.h +++ b/llvm/include/llvm/ADT/iterator.h @@ -64,9 +64,14 @@ template -class iterator_facade_base - : public std::iterator { +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 { + 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 { diff --git a/llvm/include/llvm/Analysis/MemorySSA.h b/llvm/include/llvm/Analysis/MemorySSA.h --- a/llvm/include/llvm/Analysis/MemorySSA.h +++ b/llvm/include/llvm/Analysis/MemorySSA.h @@ -1100,7 +1100,7 @@ return MP->getIncomingBlock(ArgNo); } - typename BaseT::iterator::pointer operator*() const { + typename std::iterator_traits::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. @@ -1196,7 +1196,7 @@ return DefIterator == Other.DefIterator; } - BaseT::iterator::reference operator*() const { + typename std::iterator_traits::reference operator*() const { assert(DefIterator != OriginalAccess->defs_end() && "Tried to access past the end of our iterator"); return CurrentPair; diff --git a/llvm/include/llvm/Analysis/RegionIterator.h b/llvm/include/llvm/Analysis/RegionIterator.h --- a/llvm/include/llvm/Analysis/RegionIterator.h +++ b/llvm/include/llvm/Analysis/RegionIterator.h @@ -35,10 +35,15 @@ /// /// For a subregion RegionNode there is just one successor. The RegionNode /// representing the exit of the subregion. -template -class RNSuccIterator - : public std::iterator { - using super = std::iterator; +template 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; using SuccIterTy = typename BlockTraits::ChildIteratorType; @@ -99,7 +104,6 @@ public: using Self = RNSuccIterator; - using value_type = typename super::value_type; /// Create begin iterator of a RegionNode. inline RNSuccIterator(NodeRef node) @@ -163,9 +167,7 @@ /// are contained in the Region and its subregions. This is close to a virtual /// control flow graph of the Region. template -class RNSuccIterator, BlockT, RegionT> - : public std::iterator { - using super = std::iterator; +class RNSuccIterator, BlockT, RegionT> { using BlockTraits = GraphTraits; using SuccIterTy = typename BlockTraits::ChildIteratorType; @@ -173,8 +175,13 @@ 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, BlockT, RegionT>; - using value_type = typename super::value_type; /// Create the iterator from a RegionNode. /// diff --git a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h --- a/llvm/include/llvm/CodeGen/MachineRegisterInfo.h +++ b/llvm/include/llvm/CodeGen/MachineRegisterInfo.h @@ -970,10 +970,17 @@ /// when incrementing. template - class defusechain_iterator : public std::iterator { + 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) { @@ -1008,11 +1015,6 @@ } public: - using reference = std::iterator::reference; - using pointer = std::iterator::pointer; - defusechain_iterator() = default; bool operator==(const defusechain_iterator &x) const { @@ -1074,12 +1076,19 @@ /// 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 - class defusechain_instr_iterator - : public std::iterator { + template + 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) { @@ -1114,11 +1123,6 @@ } public: - using reference = std::iterator::reference; - using pointer = std::iterator::pointer; - defusechain_instr_iterator() = default; bool operator==(const defusechain_instr_iterator &x) const { diff --git a/llvm/include/llvm/CodeGen/ScheduleDAG.h b/llvm/include/llvm/CodeGen/ScheduleDAG.h --- a/llvm/include/llvm/CodeGen/ScheduleDAG.h +++ b/llvm/include/llvm/CodeGen/ScheduleDAG.h @@ -614,14 +614,19 @@ const MCInstrDesc *getNodeDesc(const SDNode *Node) const; }; - class SUnitIterator : public std::iterator { + 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; } diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -716,8 +716,7 @@ /// This class provides iterator support for SDUse /// operands that use a specific SDNode. - class use_iterator - : public std::iterator { + class use_iterator { friend class SDNode; SDUse *Op = nullptr; @@ -725,10 +724,11 @@ explicit use_iterator(SDUse *op) : Op(op) {} public: - using reference = std::iterator::reference; - using pointer = std::iterator::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) {} @@ -2592,14 +2592,19 @@ } }; -class SDNodeIterator : public std::iterator { +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; } diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -140,7 +140,7 @@ friend class ValueIterator; }; - class ValueIterator : public std::iterator { + class ValueIterator { const AppleAcceleratorTable *AccelTable = nullptr; Entry Current; ///< The current entry. uint64_t DataOffset = 0; ///< Offset into the section. @@ -149,7 +149,14 @@ /// 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. @@ -466,8 +473,15 @@ friend class DWARFDebugNames; }; - class ValueIterator : public std::iterator { + 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. diff --git a/llvm/include/llvm/IR/CFG.h b/llvm/include/llvm/IR/CFG.h --- a/llvm/include/llvm/IR/CFG.h +++ b/llvm/include/llvm/IR/CFG.h @@ -40,10 +40,15 @@ //===----------------------------------------------------------------------===// template // Predecessor Iterator -class PredIterator : public std::iterator { - using super = - std::iterator; +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; USE_iterator It; @@ -59,9 +64,6 @@ } public: - using pointer = typename super::pointer; - using reference = typename super::reference; - PredIterator() = default; explicit inline PredIterator(Ptr *bb) : It(bb->user_begin()) { advancePastNonTerminators(); diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -80,11 +80,16 @@ return cast_or_null(N->getOperand(I)); } - class iterator : std::iterator { + 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) {} @@ -2639,11 +2644,16 @@ }; /// An iterator for expression operands. - class expr_op_iterator - : public std::iterator { + 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) {} diff --git a/llvm/include/llvm/IR/GetElementPtrTypeIterator.h b/llvm/include/llvm/IR/GetElementPtrTypeIterator.h --- a/llvm/include/llvm/IR/GetElementPtrTypeIterator.h +++ b/llvm/include/llvm/IR/GetElementPtrTypeIterator.h @@ -27,106 +27,112 @@ namespace llvm { - template - class generic_gep_type_iterator - : public std::iterator { - using super = std::iterator; - - ItTy OpIt; - PointerUnion 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()) - return T; - return CurTy.get()->getTypeAtIndex(getOperand()); - } - - Value *getOperand() const { return const_cast(&**OpIt); } - - generic_gep_type_iterator& operator++() { // Preincrement - Type *Ty = getIndexedType(); - if (auto *ATy = dyn_cast(Ty)) { - CurTy = ATy->getElementType(); - NumElements = ATy->getNumElements(); - } else if (auto *VTy = dyn_cast(Ty)) { - CurTy = VTy->getElementType(); - if (isa(VTy)) - NumElements = Unbounded; - else - NumElements = cast(VTy)->getNumElements(); - } else - CurTy = dyn_cast(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(); } - bool isSequential() const { return CurTy.is(); } - - StructType *getStructType() const { return CurTy.get(); } - - StructType *getStructTypeOrNull() const { - return CurTy.dyn_cast(); - } - - bool isBoundedSequential() const { - return isSequential() && NumElements != Unbounded; - } - - uint64_t getSequentialNumElements() const { - assert(isBoundedSequential()); - return NumElements; - } - }; +template +class generic_gep_type_iterator { + + ItTy OpIt; + PointerUnion 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()) + return T; + return CurTy.get()->getTypeAtIndex(getOperand()); + } + + Value *getOperand() const { return const_cast(&**OpIt); } + + generic_gep_type_iterator &operator++() { // Preincrement + Type *Ty = getIndexedType(); + if (auto *ATy = dyn_cast(Ty)) { + CurTy = ATy->getElementType(); + NumElements = ATy->getNumElements(); + } else if (auto *VTy = dyn_cast(Ty)) { + CurTy = VTy->getElementType(); + if (isa(VTy)) + NumElements = Unbounded; + else + NumElements = cast(VTy)->getNumElements(); + } else + CurTy = dyn_cast(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(); } + bool isSequential() const { return CurTy.is(); } + + StructType *getStructType() const { return CurTy.get(); } + + StructType *getStructTypeOrNull() const { + return CurTy.dyn_cast(); + } + + bool isBoundedSequential() const { + return isSequential() && NumElements != Unbounded; + } + + uint64_t getSequentialNumElements() const { + assert(isBoundedSequential()); + return NumElements; + } +}; using gep_type_iterator = generic_gep_type_iterator<>; diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -1247,13 +1247,16 @@ /// /// An iterator that transforms an \a MDNode::iterator into an iterator over a /// particular Metadata subclass. -template -class TypedMDOperandIterator - : public std::iterator { +template 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) {} @@ -1392,9 +1395,7 @@ explicit NamedMDNode(const Twine &N); - template - class op_iterator_impl : - public std::iterator { + template class op_iterator_impl { friend class NamedMDNode; const NamedMDNode *Node = nullptr; @@ -1403,6 +1404,12 @@ 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; } diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -718,14 +718,19 @@ } /// An iterator for DICompileUnits that skips those marked NoDebug. - class debug_compile_units_iterator - : public std::iterator { + 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(); diff --git a/llvm/include/llvm/IR/Value.h b/llvm/include/llvm/IR/Value.h --- a/llvm/include/llvm/IR/Value.h +++ b/llvm/include/llvm/IR/Value.h @@ -123,8 +123,7 @@ private: template // UseT == 'Use' or 'const Use' - class use_iterator_impl - : public std::iterator { + class use_iterator_impl { friend class Value; UseT *U; @@ -132,6 +131,12 @@ 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; } @@ -162,13 +167,18 @@ }; template // UserTy == 'User' or 'const User' - class user_iterator_impl - : public std::iterator { + class user_iterator_impl { use_iterator_impl 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; } diff --git a/llvm/include/llvm/IR/ValueMap.h b/llvm/include/llvm/IR/ValueMap.h --- a/llvm/include/llvm/IR/ValueMap.h +++ b/llvm/include/llvm/IR/ValueMap.h @@ -323,17 +323,19 @@ } }; -template -class ValueMapIterator : - public std::iterator, - ptrdiff_t> { +template 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; + using difference_type = std::ptrdiff_t; + using pointer = value_type *; + using reference = value_type &; + ValueMapIterator() : I() {} ValueMapIterator(BaseT I) : I(I) {} @@ -375,17 +377,19 @@ } }; -template -class ValueMapConstIterator : - public std::iterator, - ptrdiff_t> { +template 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; + using difference_type = std::ptrdiff_t; + using pointer = value_type *; + using reference = value_type &; + ValueMapConstIterator() : I() {} ValueMapConstIterator(BaseT I) : I(I) {} ValueMapConstIterator(ValueMapIterator Other) diff --git a/llvm/include/llvm/Object/ELFTypes.h b/llvm/include/llvm/Object/ELFTypes.h --- a/llvm/include/llvm/Object/ELFTypes.h +++ b/llvm/include/llvm/Object/ELFTypes.h @@ -655,9 +655,15 @@ Elf_Word getType() const { return Nhdr.n_type; } }; -template -class Elf_Note_Iterator_Impl - : std::iterator> { +template class Elf_Note_Iterator_Impl { +public: + using iterator_category = std::forward_iterator_tag; + using value_type = Elf_Note_Impl; + 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 *Nhdr = nullptr; size_t RemainingSize = 0u; diff --git a/llvm/include/llvm/Object/SymbolicFile.h b/llvm/include/llvm/Object/SymbolicFile.h --- a/llvm/include/llvm/Object/SymbolicFile.h +++ b/llvm/include/llvm/Object/SymbolicFile.h @@ -64,12 +64,16 @@ return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0; } -template -class content_iterator - : public std::iterator { +template 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; } diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -41,8 +41,7 @@ }; /// A file format agnostic iterator over coverage mapping data. -class CoverageMappingIterator - : public std::iterator { +class CoverageMappingIterator { CoverageMappingReader *Reader; CoverageMappingRecord Record; coveragemap_error ReadErr; @@ -50,6 +49,12 @@ 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) {} diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h --- a/llvm/include/llvm/ProfileData/InstrProfReader.h +++ b/llvm/include/llvm/ProfileData/InstrProfReader.h @@ -38,8 +38,15 @@ class InstrProfReader; /// A file format agnostic iterator over profiling data. -class InstrProfIterator : public std::iterator { +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; diff --git a/llvm/include/llvm/Support/LineIterator.h b/llvm/include/llvm/Support/LineIterator.h --- a/llvm/include/llvm/Support/LineIterator.h +++ b/llvm/include/llvm/Support/LineIterator.h @@ -30,8 +30,7 @@ /// character. /// /// Note that this iterator requires the buffer to be nul terminated. -class line_iterator - : public std::iterator { +class line_iterator { Optional Buffer; char CommentMarker = '\0'; bool SkipBlanks = true; @@ -40,6 +39,12 @@ 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; diff --git a/llvm/include/llvm/Support/TargetRegistry.h b/llvm/include/llvm/Support/TargetRegistry.h --- a/llvm/include/llvm/Support/TargetRegistry.h +++ b/llvm/include/llvm/Support/TargetRegistry.h @@ -603,8 +603,7 @@ // function). TargetRegistry() = delete; - class iterator - : public std::iterator { + class iterator { friend struct TargetRegistry; const Target *Current = nullptr; @@ -612,6 +611,12 @@ 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; } diff --git a/llvm/include/llvm/Support/YAMLParser.h b/llvm/include/llvm/Support/YAMLParser.h --- a/llvm/include/llvm/Support/YAMLParser.h +++ b/llvm/include/llvm/Support/YAMLParser.h @@ -325,10 +325,14 @@ /// /// 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 basic_collection_iterator - : public std::iterator { +template 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) {} diff --git a/llvm/include/llvm/TextAPI/ArchitectureSet.h b/llvm/include/llvm/TextAPI/ArchitectureSet.h --- a/llvm/include/llvm/TextAPI/ArchitectureSet.h +++ b/llvm/include/llvm/TextAPI/ArchitectureSet.h @@ -66,9 +66,14 @@ return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h); } - template - class arch_iterator - : public std::iterator { + template 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; diff --git a/llvm/include/llvm/Transforms/Scalar/GVNExpression.h b/llvm/include/llvm/Transforms/Scalar/GVNExpression.h --- a/llvm/include/llvm/Transforms/Scalar/GVNExpression.h +++ b/llvm/include/llvm/Transforms/Scalar/GVNExpression.h @@ -240,14 +240,19 @@ } }; -class op_inserter - : public std::iterator { +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) {} @@ -472,14 +477,19 @@ } }; -class int_op_inserter - : public std::iterator { +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) {} diff --git a/llvm/lib/Analysis/CFGPrinter.cpp b/llvm/lib/Analysis/CFGPrinter.cpp --- a/llvm/lib/Analysis/CFGPrinter.cpp +++ b/llvm/lib/Analysis/CFGPrinter.cpp @@ -286,8 +286,7 @@ }; /// 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::isNodeHidden(const BasicBlock *Node, diff --git a/llvm/tools/llvm-objdump/MachODump.cpp b/llvm/tools/llvm-objdump/MachODump.cpp --- a/llvm/tools/llvm-objdump/MachODump.cpp +++ b/llvm/tools/llvm-objdump/MachODump.cpp @@ -466,7 +466,7 @@ 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(); @@ -478,7 +478,7 @@ 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 << " (?,?)"; diff --git a/polly/include/polly/Support/VirtualInstruction.h b/polly/include/polly/Support/VirtualInstruction.h --- a/polly/include/polly/Support/VirtualInstruction.h +++ b/polly/include/polly/Support/VirtualInstruction.h @@ -167,12 +167,10 @@ }; /// An iterator for virtual operands. -class VirtualOperandIterator - : public std::iterator { +class VirtualOperandIterator { friend class VirtualInstruction; friend class VirtualUse; - using super = std::iterator; using Self = VirtualOperandIterator; ScopStmt *User; @@ -182,8 +180,11 @@ : 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);