diff options
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r-- | include/llvm/ADT/APFloat.h | 5 | ||||
-rw-r--r-- | include/llvm/ADT/APInt.h | 9 | ||||
-rw-r--r-- | include/llvm/ADT/Any.h | 4 | ||||
-rw-r--r-- | include/llvm/ADT/ArrayRef.h | 6 | ||||
-rw-r--r-- | include/llvm/ADT/DenseMap.h | 57 | ||||
-rw-r--r-- | include/llvm/ADT/DenseMapInfo.h | 13 | ||||
-rw-r--r-- | include/llvm/ADT/DirectedGraph.h | 270 | ||||
-rw-r--r-- | include/llvm/ADT/Hashing.h | 1 | ||||
-rw-r--r-- | include/llvm/ADT/IntervalMap.h | 4 | ||||
-rw-r--r-- | include/llvm/ADT/PointerIntPair.h | 11 | ||||
-rw-r--r-- | include/llvm/ADT/PointerUnion.h | 30 | ||||
-rw-r--r-- | include/llvm/ADT/STLExtras.h | 168 | ||||
-rw-r--r-- | include/llvm/ADT/SmallBitVector.h | 2 | ||||
-rw-r--r-- | include/llvm/ADT/Statistic.h | 102 | ||||
-rw-r--r-- | include/llvm/ADT/StringExtras.h | 2 | ||||
-rw-r--r-- | include/llvm/ADT/StringMap.h | 59 | ||||
-rw-r--r-- | include/llvm/ADT/StringRef.h | 18 | ||||
-rw-r--r-- | include/llvm/ADT/StringSet.h | 8 | ||||
-rw-r--r-- | include/llvm/ADT/TinyPtrVector.h | 38 | ||||
-rw-r--r-- | include/llvm/ADT/VariadicFunction.h | 330 | ||||
-rw-r--r-- | include/llvm/ADT/iterator_range.h | 1 |
21 files changed, 531 insertions, 607 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index a9648d35cf5d..1c4969733791 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -192,6 +192,11 @@ struct APFloatBase { /// IEEE-754R 7: Default exception handling. /// /// opUnderflow or opOverflow are always returned or-ed with opInexact. + /// + /// APFloat models this behavior specified by IEEE-754: + /// "For operations producing results in floating-point format, the default + /// result of an operation that signals the invalid operation exception + /// shall be a quiet NaN." enum opStatus { opOK = 0x00, opInvalidOp = 0x01, diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 2381b75e08b1..8dce5a621bb3 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -1467,6 +1467,13 @@ public: U.pVal[whichWord(BitPosition)] &= Mask; } + /// Set bottom loBits bits to 0. + void clearLowBits(unsigned loBits) { + assert(loBits <= BitWidth && "More bits than bitwidth"); + APInt Keep = getHighBitsSet(BitWidth, BitWidth - loBits); + *this &= Keep; + } + /// Set the sign bit to 0. void clearSignBit() { clearBit(BitWidth - 1); @@ -1496,9 +1503,11 @@ public: /// Insert the bits from a smaller APInt starting at bitPosition. void insertBits(const APInt &SubBits, unsigned bitPosition); + void insertBits(uint64_t SubBits, unsigned bitPosition, unsigned numBits); /// Return an APInt with the extracted bits [bitPosition,bitPosition+numBits). APInt extractBits(unsigned numBits, unsigned bitPosition) const; + uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const; /// @} /// \name Value Characterization Functions diff --git a/include/llvm/ADT/Any.h b/include/llvm/ADT/Any.h index 5dcd6e73c54f..49657e02a991 100644 --- a/include/llvm/ADT/Any.h +++ b/include/llvm/ADT/Any.h @@ -38,7 +38,7 @@ class Any { explicit StorageImpl(T &&Value) : Value(std::move(Value)) {} std::unique_ptr<StorageBase> clone() const override { - return llvm::make_unique<StorageImpl<T>>(Value); + return std::make_unique<StorageImpl<T>>(Value); } const void *id() const override { return &TypeId<T>::Id; } @@ -78,7 +78,7 @@ public: int>::type = 0> Any(T &&Value) { using U = typename std::decay<T>::type; - Storage = llvm::make_unique<StorageImpl<U>>(std::forward<T>(Value)); + Storage = std::make_unique<StorageImpl<U>>(std::forward<T>(Value)); } Any(Any &&Other) : Storage(std::move(Other.Storage)) {} diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 773c88f7c9f9..f6455d3fa412 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -481,6 +481,12 @@ namespace llvm { return Vec; } + /// Construct an ArrayRef from a std::array. + template <typename T, std::size_t N> + ArrayRef<T> makeArrayRef(const std::array<T, N> &Arr) { + return Arr; + } + /// Construct an ArrayRef from an ArrayRef (no-op) (const) template <typename T> ArrayRef<T> makeArrayRef(const ArrayRef<T> &Vec) { return Vec; diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index a05cf8130d3c..948a6e6bfb38 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -38,33 +38,7 @@ namespace detail { // implementation without requiring two members. template <typename KeyT, typename ValueT> struct DenseMapPair : public std::pair<KeyT, ValueT> { - - // FIXME: Switch to inheriting constructors when we drop support for older - // clang versions. - // NOTE: This default constructor is declared with '{}' rather than - // '= default' to work around a separate bug in clang-3.8. This can - // also go when we switch to inheriting constructors. - DenseMapPair() {} - - DenseMapPair(const KeyT &Key, const ValueT &Value) - : std::pair<KeyT, ValueT>(Key, Value) {} - - DenseMapPair(KeyT &&Key, ValueT &&Value) - : std::pair<KeyT, ValueT>(std::move(Key), std::move(Value)) {} - - template <typename AltKeyT, typename AltValueT> - DenseMapPair(AltKeyT &&AltKey, AltValueT &&AltValue, - typename std::enable_if< - std::is_convertible<AltKeyT, KeyT>::value && - std::is_convertible<AltValueT, ValueT>::value>::type * = 0) - : std::pair<KeyT, ValueT>(std::forward<AltKeyT>(AltKey), - std::forward<AltValueT>(AltValue)) {} - - template <typename AltPairT> - DenseMapPair(AltPairT &&AltPair, - typename std::enable_if<std::is_convertible< - AltPairT, std::pair<KeyT, ValueT>>::value>::type * = nullptr) - : std::pair<KeyT, ValueT>(std::forward<AltPairT>(AltPair)) {} + using std::pair<KeyT, ValueT>::pair; KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; } const KeyT &getFirst() const { return std::pair<KeyT, ValueT>::first; } @@ -748,7 +722,7 @@ public: ~DenseMap() { this->destroyAll(); - operator delete(Buckets); + deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT)); } void swap(DenseMap& RHS) { @@ -768,7 +742,7 @@ public: DenseMap& operator=(DenseMap &&other) { this->destroyAll(); - operator delete(Buckets); + deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT)); init(0); swap(other); return *this; @@ -776,7 +750,7 @@ public: void copyFrom(const DenseMap& other) { this->destroyAll(); - operator delete(Buckets); + deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT)); if (allocateBuckets(other.NumBuckets)) { this->BaseT::copyFrom(other); } else { @@ -809,10 +783,12 @@ public: this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets); // Free the old table. - operator delete(OldBuckets); + deallocate_buffer(OldBuckets, sizeof(BucketT) * OldNumBuckets, + alignof(BucketT)); } void shrink_and_clear() { + unsigned OldNumBuckets = NumBuckets; unsigned OldNumEntries = NumEntries; this->destroyAll(); @@ -825,7 +801,8 @@ public: return; } - operator delete(Buckets); + deallocate_buffer(Buckets, sizeof(BucketT) * OldNumBuckets, + alignof(BucketT)); init(NewNumBuckets); } @@ -861,7 +838,8 @@ private: return false; } - Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets)); + Buckets = static_cast<BucketT *>( + allocate_buffer(sizeof(BucketT) * NumBuckets, alignof(BucketT))); return true; } }; @@ -1076,7 +1054,8 @@ public: this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets); // Free the old table. - operator delete(OldRep.Buckets); + deallocate_buffer(OldRep.Buckets, sizeof(BucketT) * OldRep.NumBuckets, + alignof(BucketT)); } void shrink_and_clear() { @@ -1160,15 +1139,17 @@ private: if (Small) return; - operator delete(getLargeRep()->Buckets); + deallocate_buffer(getLargeRep()->Buckets, + sizeof(BucketT) * getLargeRep()->NumBuckets, + alignof(BucketT)); getLargeRep()->~LargeRep(); } LargeRep allocateBuckets(unsigned Num) { assert(Num > InlineBuckets && "Must allocate more buckets than are inline"); - LargeRep Rep = { - static_cast<BucketT*>(operator new(sizeof(BucketT) * Num)), Num - }; + LargeRep Rep = {static_cast<BucketT *>(allocate_buffer( + sizeof(BucketT) * Num, alignof(BucketT))), + Num}; return Rep; } }; diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h index 5ef6f3ad1b04..bd4c60c8f13e 100644 --- a/include/llvm/ADT/DenseMapInfo.h +++ b/include/llvm/ADT/DenseMapInfo.h @@ -17,7 +17,7 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/PointerLikeTypeTraits.h" -#include "llvm/Support/ScalableSize.h" +#include "llvm/Support/TypeSize.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -67,6 +67,17 @@ template<> struct DenseMapInfo<char> { } }; +// Provide DenseMapInfo for unsigned chars. +template <> struct DenseMapInfo<unsigned char> { + static inline unsigned char getEmptyKey() { return ~0; } + static inline unsigned char getTombstoneKey() { return ~0 - 1; } + static unsigned getHashValue(const unsigned char &Val) { return Val * 37U; } + + static bool isEqual(const unsigned char &LHS, const unsigned char &RHS) { + return LHS == RHS; + } +}; + // Provide DenseMapInfo for unsigned shorts. template <> struct DenseMapInfo<unsigned short> { static inline unsigned short getEmptyKey() { return 0xFFFF; } diff --git a/include/llvm/ADT/DirectedGraph.h b/include/llvm/ADT/DirectedGraph.h new file mode 100644 index 000000000000..f6a358d99cd2 --- /dev/null +++ b/include/llvm/ADT/DirectedGraph.h @@ -0,0 +1,270 @@ +//===- llvm/ADT/DirectedGraph.h - Directed Graph ----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface and a base class implementation for a +// directed graph. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ADT_DIRECTEDGRAPH_H +#define LLVM_ADT_DIRECTEDGRAPH_H + +#include "llvm/ADT/GraphTraits.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +/// Represent an edge in the directed graph. +/// The edge contains the target node it connects to. +template <class NodeType, class EdgeType> class DGEdge { +public: + DGEdge() = delete; + /// Create an edge pointing to the given node \p N. + explicit DGEdge(NodeType &N) : TargetNode(N) {} + explicit DGEdge(const DGEdge<NodeType, EdgeType> &E) + : TargetNode(E.TargetNode) {} + DGEdge<NodeType, EdgeType> &operator=(const DGEdge<NodeType, EdgeType> &E) { + TargetNode = E.TargetNode; + return *this; + } + + /// Static polymorphism: delegate implementation (via isEqualTo) to the + /// derived class. + bool operator==(const EdgeType &E) const { return getDerived().isEqualTo(E); } + bool operator!=(const EdgeType &E) const { return !operator==(E); } + + /// Retrieve the target node this edge connects to. + const NodeType &getTargetNode() const { return TargetNode; } + NodeType &getTargetNode() { + return const_cast<NodeType &>( + static_cast<const DGEdge<NodeType, EdgeType> &>(*this).getTargetNode()); + } + +protected: + // As the default implementation use address comparison for equality. + bool isEqualTo(const EdgeType &E) const { return this == &E; } + + // Cast the 'this' pointer to the derived type and return a reference. + EdgeType &getDerived() { return *static_cast<EdgeType *>(this); } + const EdgeType &getDerived() const { + return *static_cast<const EdgeType *>(this); + } + + // The target node this edge connects to. + NodeType &TargetNode; +}; + +/// Represent a node in the directed graph. +/// The node has a (possibly empty) list of outgoing edges. +template <class NodeType, class EdgeType> class DGNode { +public: + using EdgeListTy = SetVector<EdgeType *>; + using iterator = typename EdgeListTy::iterator; + using const_iterator = typename EdgeListTy::const_iterator; + + /// Create a node with a single outgoing edge \p E. + explicit DGNode(EdgeType &E) : Edges() { Edges.insert(&E); } + DGNode() = default; + + explicit DGNode(const DGNode<NodeType, EdgeType> &N) : Edges(N.Edges) {} + DGNode(DGNode<NodeType, EdgeType> &&N) : Edges(std::move(N.Edges)) {} + + DGNode<NodeType, EdgeType> &operator=(const DGNode<NodeType, EdgeType> &N) { + Edges = N.Edges; + return *this; + } + DGNode<NodeType, EdgeType> &operator=(const DGNode<NodeType, EdgeType> &&N) { + Edges = std::move(N.Edges); + return *this; + } + + /// Static polymorphism: delegate implementation (via isEqualTo) to the + /// derived class. + bool operator==(const NodeType &N) const { return getDerived().isEqualTo(N); } + bool operator!=(const NodeType &N) const { return !operator==(N); } + + const_iterator begin() const { return Edges.begin(); } + const_iterator end() const { return Edges.end(); } + iterator begin() { return Edges.begin(); } + iterator end() { return Edges.end(); } + const EdgeType &front() const { return *Edges.front(); } + EdgeType &front() { return *Edges.front(); } + const EdgeType &back() const { return *Edges.back(); } + EdgeType &back() { return *Edges.back(); } + + /// Collect in \p EL, all the edges from this node to \p N. + /// Return true if at least one edge was found, and false otherwise. + /// Note that this implementation allows more than one edge to connect + /// a given pair of nodes. + bool findEdgesTo(const NodeType &N, SmallVectorImpl<EdgeType *> &EL) const { + assert(EL.empty() && "Expected the list of edges to be empty."); + for (auto *E : Edges) + if (E->getTargetNode() == N) + EL.push_back(E); + return !EL.empty(); + } + + /// Add the given edge \p E to this node, if it doesn't exist already. Returns + /// true if the edge is added and false otherwise. + bool addEdge(EdgeType &E) { return Edges.insert(&E); } + + /// Remove the given edge \p E from this node, if it exists. + void removeEdge(EdgeType &E) { Edges.remove(&E); } + + /// Test whether there is an edge that goes from this node to \p N. + bool hasEdgeTo(const NodeType &N) const { + return (findEdgeTo(N) != Edges.end()); + } + + /// Retrieve the outgoing edges for the node. + const EdgeListTy &getEdges() const { return Edges; } + EdgeListTy &getEdges() { + return const_cast<EdgeListTy &>( + static_cast<const DGNode<NodeType, EdgeType> &>(*this).Edges); + } + + /// Clear the outgoing edges. + void clear() { Edges.clear(); } + +protected: + // As the default implementation use address comparison for equality. + bool isEqualTo(const NodeType &N) const { return this == &N; } + + // Cast the 'this' pointer to the derived type and return a reference. + NodeType &getDerived() { return *static_cast<NodeType *>(this); } + const NodeType &getDerived() const { + return *static_cast<const NodeType *>(this); + } + + /// Find an edge to \p N. If more than one edge exists, this will return + /// the first one in the list of edges. + const_iterator findEdgeTo(const NodeType &N) const { + return llvm::find_if( + Edges, [&N](const EdgeType *E) { return E->getTargetNode() == N; }); + } + + // The list of outgoing edges. + EdgeListTy Edges; +}; + +/// Directed graph +/// +/// The graph is represented by a table of nodes. +/// Each node contains a (possibly empty) list of outgoing edges. +/// Each edge contains the target node it connects to. +template <class NodeType, class EdgeType> class DirectedGraph { +protected: + using NodeListTy = SmallVector<NodeType *, 10>; + using EdgeListTy = SmallVector<EdgeType *, 10>; +public: + using iterator = typename NodeListTy::iterator; + using const_iterator = typename NodeListTy::const_iterator; + using DGraphType = DirectedGraph<NodeType, EdgeType>; + + DirectedGraph() = default; + explicit DirectedGraph(NodeType &N) : Nodes() { addNode(N); } + DirectedGraph(const DGraphType &G) : Nodes(G.Nodes) {} + DirectedGraph(DGraphType &&RHS) : Nodes(std::move(RHS.Nodes)) {} + DGraphType &operator=(const DGraphType &G) { + Nodes = G.Nodes; + return *this; + } + DGraphType &operator=(const DGraphType &&G) { + Nodes = std::move(G.Nodes); + return *this; + } + + const_iterator begin() const { return Nodes.begin(); } + const_iterator end() const { return Nodes.end(); } + iterator begin() { return Nodes.begin(); } + iterator end() { return Nodes.end(); } + const NodeType &front() const { return *Nodes.front(); } + NodeType &front() { return *Nodes.front(); } + const NodeType &back() const { return *Nodes.back(); } + NodeType &back() { return *Nodes.back(); } + + size_t size() const { return Nodes.size(); } + + /// Find the given node \p N in the table. + const_iterator findNode(const NodeType &N) const { + return llvm::find_if(Nodes, + [&N](const NodeType *Node) { return *Node == N; }); + } + iterator findNode(const NodeType &N) { + return const_cast<iterator>( + static_cast<const DGraphType &>(*this).findNode(N)); + } + + /// Add the given node \p N to the graph if it is not already present. + bool addNode(NodeType &N) { + if (findNode(N) != Nodes.end()) + return false; + Nodes.push_back(&N); + return true; + } + + /// Collect in \p EL all edges that are coming into node \p N. Return true + /// if at least one edge was found, and false otherwise. + bool findIncomingEdgesToNode(const NodeType &N, SmallVectorImpl<EdgeType*> &EL) const { + assert(EL.empty() && "Expected the list of edges to be empty."); + EdgeListTy TempList; + for (auto *Node : Nodes) { + if (*Node == N) + continue; + Node->findEdgesTo(N, TempList); + EL.insert(EL.end(), TempList.begin(), TempList.end()); + TempList.clear(); + } + return !EL.empty(); + } + + /// Remove the given node \p N from the graph. If the node has incoming or + /// outgoing edges, they are also removed. Return true if the node was found + /// and then removed, and false if the node was not found in the graph to + /// begin with. + bool removeNode(NodeType &N) { + iterator IT = findNode(N); + if (IT == Nodes.end()) + return false; + // Remove incoming edges. + EdgeListTy EL; + for (auto *Node : Nodes) { + if (*Node == N) + continue; + Node->findEdgesTo(N, EL); + for (auto *E : EL) + Node->removeEdge(*E); + EL.clear(); + } + N.clear(); + Nodes.erase(IT); + return true; + } + + /// Assuming nodes \p Src and \p Dst are already in the graph, connect node \p + /// Src to node \p Dst using the provided edge \p E. Return true if \p Src is + /// not already connected to \p Dst via \p E, and false otherwise. + bool connect(NodeType &Src, NodeType &Dst, EdgeType &E) { + assert(findNode(Src) != Nodes.end() && "Src node should be present."); + assert(findNode(Dst) != Nodes.end() && "Dst node should be present."); + assert((E.getTargetNode() == Dst) && + "Target of the given edge does not match Dst."); + return Src.addEdge(E); + } + +protected: + // The list of nodes in the graph. + NodeListTy Nodes; +}; + +} // namespace llvm + +#endif // LLVM_ADT_DIRECTEDGRAPH_H diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h index 008188bfa210..b22606bdb518 100644 --- a/include/llvm/ADT/Hashing.h +++ b/include/llvm/ADT/Hashing.h @@ -45,7 +45,6 @@ #define LLVM_ADT_HASHING_H #include "llvm/Support/DataTypes.h" -#include "llvm/Support/Host.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/type_traits.h" #include <algorithm> diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h index 12828c4cfdab..a02876ee77f3 100644 --- a/include/llvm/ADT/IntervalMap.h +++ b/include/llvm/ADT/IntervalMap.h @@ -963,8 +963,8 @@ public: private: // The root data is either a RootLeaf or a RootBranchData instance. - LLVM_ALIGNAS(RootLeaf) LLVM_ALIGNAS(RootBranchData) - AlignedCharArrayUnion<RootLeaf, RootBranchData> data; + alignas(RootLeaf) alignas(RootBranchData) + AlignedCharArrayUnion<RootLeaf, RootBranchData> data; // Tree height. // 0: Leaves in root. diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 24a2bb67a36e..fa6bf1504469 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -13,6 +13,7 @@ #ifndef LLVM_ADT_POINTERINTPAIR_H #define LLVM_ADT_POINTERINTPAIR_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/type_traits.h" #include <cassert> @@ -59,19 +60,19 @@ public: IntType getInt() const { return (IntType)Info::getInt(Value); } - void setPointer(PointerTy PtrVal) { + void setPointer(PointerTy PtrVal) LLVM_LVALUE_FUNCTION { Value = Info::updatePointer(Value, PtrVal); } - void setInt(IntType IntVal) { + void setInt(IntType IntVal) LLVM_LVALUE_FUNCTION { Value = Info::updateInt(Value, static_cast<intptr_t>(IntVal)); } - void initWithPointer(PointerTy PtrVal) { + void initWithPointer(PointerTy PtrVal) LLVM_LVALUE_FUNCTION { Value = Info::updatePointer(0, PtrVal); } - void setPointerAndInt(PointerTy PtrVal, IntType IntVal) { + void setPointerAndInt(PointerTy PtrVal, IntType IntVal) LLVM_LVALUE_FUNCTION { Value = Info::updateInt(Info::updatePointer(0, PtrVal), static_cast<intptr_t>(IntVal)); } @@ -89,7 +90,7 @@ public: void *getOpaqueValue() const { return reinterpret_cast<void *>(Value); } - void setFromOpaqueValue(void *Val) { + void setFromOpaqueValue(void *Val) LLVM_LVALUE_FUNCTION { Value = reinterpret_cast<intptr_t>(Val); } diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index 2bcdf546c6e4..98c905775a77 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -54,21 +54,14 @@ struct PointerUnionTypeSelectorReturn< }; namespace pointer_union_detail { - constexpr int constexprMin(int a, int b) { return a < b ? a : b; } /// Determine the number of bits required to store integers with values < n. /// This is ceil(log2(n)). constexpr int bitsRequired(unsigned n) { return n > 1 ? 1 + bitsRequired((n + 1) / 2) : 0; } - // FIXME: In C++14, replace this with - // std::min({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...}) - template <typename T> constexpr int lowBitsAvailable() { - return PointerLikeTypeTraits<T>::NumLowBitsAvailable; - } - template <typename T1, typename T2, typename... Ts> - constexpr int lowBitsAvailable() { - return constexprMin(lowBitsAvailable<T1>(), lowBitsAvailable<T2, Ts...>()); + template <typename... Ts> constexpr int lowBitsAvailable() { + return std::min<int>({PointerLikeTypeTraits<Ts>::NumLowBitsAvailable...}); } /// Find the index of a type in a list of types. TypeIndex<T, Us...>::Index @@ -167,10 +160,11 @@ class PointerUnion void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int, pointer_union_detail::PointerUnionUIntTraits<PTs...>>, 0, PTs...> { - // The first type is special in some ways, but we don't want PointerUnion to - // be a 'template <typename First, typename ...Rest>' because it's much more - // convenient to have a name for the whole pack. So split off the first type - // here. + // The first type is special because we want to directly cast a pointer to a + // default-initialized union to a pointer to the first type. But we don't + // want PointerUnion to be a 'template <typename First, typename ...Rest>' + // because it's much more convenient to have a name for the whole pack. So + // split off the first type here. using First = typename pointer_union_detail::GetFirstType<PTs...>::type; using Base = typename PointerUnion::PointerUnionMembers; @@ -182,12 +176,7 @@ public: /// Test if the pointer held in the union is null, regardless of /// which type it is. - bool isNull() const { - // Convert from the void* to one of the pointer types, to make sure that - // we recursively strip off low bits if we have a nested PointerUnion. - return !PointerLikeTypeTraits<First>::getFromVoidPointer( - this->Val.getPointer()); - } + bool isNull() const { return !this->Val.getPointer(); } explicit operator bool() const { return !isNull(); } @@ -226,7 +215,8 @@ public: First *getAddrOfPtr1() { assert(is<First>() && "Val is not the first pointer"); assert( - get<First>() == this->Val.getPointer() && + PointerLikeTypeTraits<First>::getAsVoidPointer(get<First>()) == + this->Val.getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"); return const_cast<First *>( reinterpret_cast<const First *>(this->Val.getAddrOfPointer())); diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 81dce0168c79..274933bc5204 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -95,18 +95,6 @@ template <class Ty> struct identity { } }; -template <class Ty> struct less_ptr { - bool operator()(const Ty* left, const Ty* right) const { - return *left < *right; - } -}; - -template <class Ty> struct greater_ptr { - bool operator()(const Ty* left, const Ty* right) const { - return *right < *left; - } -}; - /// An efficient, type-erasing, non-owning reference to a callable. This is /// intended for use as the type of a function parameter that is not used /// after the function in question returns. @@ -530,10 +518,6 @@ bool all_of(R &&range, UnaryPredicate P); template <typename R, typename UnaryPredicate> bool any_of(R &&range, UnaryPredicate P); -template <size_t... I> struct index_sequence; - -template <class... Ts> struct index_sequence_for; - namespace detail { using std::declval; @@ -568,38 +552,38 @@ struct zip_common : public zip_traits<ZipType, Iters...> { std::tuple<Iters...> iterators; protected: - template <size_t... Ns> value_type deref(index_sequence<Ns...>) const { + template <size_t... Ns> value_type deref(std::index_sequence<Ns...>) const { return value_type(*std::get<Ns>(iterators)...); } template <size_t... Ns> - decltype(iterators) tup_inc(index_sequence<Ns...>) const { + decltype(iterators) tup_inc(std::index_sequence<Ns...>) const { return std::tuple<Iters...>(std::next(std::get<Ns>(iterators))...); } template <size_t... Ns> - decltype(iterators) tup_dec(index_sequence<Ns...>) const { + decltype(iterators) tup_dec(std::index_sequence<Ns...>) const { return std::tuple<Iters...>(std::prev(std::get<Ns>(iterators))...); } public: zip_common(Iters &&... ts) : iterators(std::forward<Iters>(ts)...) {} - value_type operator*() { return deref(index_sequence_for<Iters...>{}); } + value_type operator*() { return deref(std::index_sequence_for<Iters...>{}); } const value_type operator*() const { - return deref(index_sequence_for<Iters...>{}); + return deref(std::index_sequence_for<Iters...>{}); } ZipType &operator++() { - iterators = tup_inc(index_sequence_for<Iters...>{}); + iterators = tup_inc(std::index_sequence_for<Iters...>{}); return *reinterpret_cast<ZipType *>(this); } ZipType &operator--() { static_assert(Base::IsBidirectional, "All inner iterators must be at least bidirectional."); - iterators = tup_dec(index_sequence_for<Iters...>{}); + iterators = tup_dec(std::index_sequence_for<Iters...>{}); return *reinterpret_cast<ZipType *>(this); } }; @@ -618,7 +602,8 @@ struct zip_first : public zip_common<zip_first<Iters...>, Iters...> { template <typename... Iters> class zip_shortest : public zip_common<zip_shortest<Iters...>, Iters...> { template <size_t... Ns> - bool test(const zip_shortest<Iters...> &other, index_sequence<Ns...>) const { + bool test(const zip_shortest<Iters...> &other, + std::index_sequence<Ns...>) const { return all_of(std::initializer_list<bool>{std::get<Ns>(this->iterators) != std::get<Ns>(other.iterators)...}, identity<bool>{}); @@ -630,7 +615,7 @@ public: zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {} bool operator==(const zip_shortest<Iters...> &other) const { - return !test(other, index_sequence_for<Iters...>{}); + return !test(other, std::index_sequence_for<Iters...>{}); } }; @@ -646,18 +631,21 @@ public: private: std::tuple<Args...> ts; - template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const { + template <size_t... Ns> + iterator begin_impl(std::index_sequence<Ns...>) const { return iterator(std::begin(std::get<Ns>(ts))...); } - template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const { + template <size_t... Ns> iterator end_impl(std::index_sequence<Ns...>) const { return iterator(std::end(std::get<Ns>(ts))...); } public: zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {} - iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); } - iterator end() const { return end_impl(index_sequence_for<Args...>{}); } + iterator begin() const { + return begin_impl(std::index_sequence_for<Args...>{}); + } + iterator end() const { return end_impl(std::index_sequence_for<Args...>{}); } }; } // end namespace detail @@ -727,20 +715,20 @@ private: template <size_t... Ns> bool test(const zip_longest_iterator<Iters...> &other, - index_sequence<Ns...>) const { + std::index_sequence<Ns...>) const { return llvm::any_of( std::initializer_list<bool>{std::get<Ns>(this->iterators) != std::get<Ns>(other.iterators)...}, identity<bool>{}); } - template <size_t... Ns> value_type deref(index_sequence<Ns...>) const { + template <size_t... Ns> value_type deref(std::index_sequence<Ns...>) const { return value_type( deref_or_none(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...); } template <size_t... Ns> - decltype(iterators) tup_inc(index_sequence<Ns...>) const { + decltype(iterators) tup_inc(std::index_sequence<Ns...>) const { return std::tuple<Iters...>( next_or_end(std::get<Ns>(iterators), std::get<Ns>(end_iterators))...); } @@ -750,17 +738,19 @@ public: : iterators(std::forward<Iters>(ts.first)...), end_iterators(std::forward<Iters>(ts.second)...) {} - value_type operator*() { return deref(index_sequence_for<Iters...>{}); } + value_type operator*() { return deref(std::index_sequence_for<Iters...>{}); } - value_type operator*() const { return deref(index_sequence_for<Iters...>{}); } + value_type operator*() const { + return deref(std::index_sequence_for<Iters...>{}); + } zip_longest_iterator<Iters...> &operator++() { - iterators = tup_inc(index_sequence_for<Iters...>{}); + iterators = tup_inc(std::index_sequence_for<Iters...>{}); return *this; } bool operator==(const zip_longest_iterator<Iters...> &other) const { - return !test(other, index_sequence_for<Iters...>{}); + return !test(other, std::index_sequence_for<Iters...>{}); } }; @@ -777,12 +767,13 @@ public: private: std::tuple<Args...> ts; - template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) const { + template <size_t... Ns> + iterator begin_impl(std::index_sequence<Ns...>) const { return iterator(std::make_pair(adl_begin(std::get<Ns>(ts)), adl_end(std::get<Ns>(ts)))...); } - template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) const { + template <size_t... Ns> iterator end_impl(std::index_sequence<Ns...>) const { return iterator(std::make_pair(adl_end(std::get<Ns>(ts)), adl_end(std::get<Ns>(ts)))...); } @@ -790,8 +781,10 @@ private: public: zip_longest_range(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {} - iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); } - iterator end() const { return end_impl(index_sequence_for<Args...>{}); } + iterator begin() const { + return begin_impl(std::index_sequence_for<Args...>{}); + } + iterator end() const { return end_impl(std::index_sequence_for<Args...>{}); } }; } // namespace detail @@ -847,7 +840,7 @@ class concat_iterator /// Increments the first non-end iterator. /// /// It is an error to call this with all iterators at the end. - template <size_t... Ns> void increment(index_sequence<Ns...>) { + template <size_t... Ns> void increment(std::index_sequence<Ns...>) { // Build a sequence of functions to increment each iterator if possible. bool (concat_iterator::*IncrementHelperFns[])() = { &concat_iterator::incrementHelper<Ns>...}; @@ -876,7 +869,7 @@ class concat_iterator /// reference. /// /// It is an error to call this with all iterators at the end. - template <size_t... Ns> ValueT &get(index_sequence<Ns...>) const { + template <size_t... Ns> ValueT &get(std::index_sequence<Ns...>) const { // Build a sequence of functions to get from iterator if possible. ValueT *(concat_iterator::*GetHelperFns[])() const = { &concat_iterator::getHelper<Ns>...}; @@ -901,11 +894,13 @@ public: using BaseT::operator++; concat_iterator &operator++() { - increment(index_sequence_for<IterTs...>()); + increment(std::index_sequence_for<IterTs...>()); return *this; } - ValueT &operator*() const { return get(index_sequence_for<IterTs...>()); } + ValueT &operator*() const { + return get(std::index_sequence_for<IterTs...>()); + } bool operator==(const concat_iterator &RHS) const { return Begins == RHS.Begins && Ends == RHS.Ends; @@ -928,10 +923,10 @@ public: private: std::tuple<RangeTs...> Ranges; - template <size_t... Ns> iterator begin_impl(index_sequence<Ns...>) { + template <size_t... Ns> iterator begin_impl(std::index_sequence<Ns...>) { return iterator(std::get<Ns>(Ranges)...); } - template <size_t... Ns> iterator end_impl(index_sequence<Ns...>) { + template <size_t... Ns> iterator end_impl(std::index_sequence<Ns...>) { return iterator(make_range(std::end(std::get<Ns>(Ranges)), std::end(std::get<Ns>(Ranges)))...); } @@ -940,8 +935,8 @@ public: concat_range(RangeTs &&... Ranges) : Ranges(std::forward<RangeTs>(Ranges)...) {} - iterator begin() { return begin_impl(index_sequence_for<RangeTs...>{}); } - iterator end() { return end_impl(index_sequence_for<RangeTs...>{}); } + iterator begin() { return begin_impl(std::index_sequence_for<RangeTs...>{}); } + iterator end() { return end_impl(std::index_sequence_for<RangeTs...>{}); } }; } // end namespace detail @@ -990,28 +985,6 @@ struct on_first { } }; -// A subset of N3658. More stuff can be added as-needed. - -/// Represents a compile-time sequence of integers. -template <class T, T... I> struct integer_sequence { - using value_type = T; - - static constexpr size_t size() { return sizeof...(I); } -}; - -/// Alias for the common case of a sequence of size_ts. -template <size_t... I> -struct index_sequence : integer_sequence<std::size_t, I...> {}; - -template <std::size_t N, std::size_t... I> -struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {}; -template <std::size_t... I> -struct build_index_impl<0, I...> : index_sequence<I...> {}; - -/// Creates a compile-time integer sequence for a parameter pack. -template <class... Ts> -struct index_sequence_for : build_index_impl<sizeof...(Ts)> {}; - /// Utility type to build an inheritance chain that makes it easy to rank /// overload candidates. template <int N> struct rank : rank<N - 1> {}; @@ -1391,41 +1364,6 @@ void replace(Container &Cont, typename Container::iterator ContIt, // Extra additions to <memory> //===----------------------------------------------------------------------===// -// Implement make_unique according to N3656. - -/// Constructs a `new T()` with the given args and returns a -/// `unique_ptr<T>` which owns the object. -/// -/// Example: -/// -/// auto p = make_unique<int>(); -/// auto p = make_unique<std::tuple<int, int>>(0, 1); -template <class T, class... Args> -typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type -make_unique(Args &&... args) { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); -} - -/// Constructs a `new T[n]` with the given args and returns a -/// `unique_ptr<T[]>` which owns the object. -/// -/// \param n size of the new array. -/// -/// Example: -/// -/// auto p = make_unique<int[]>(2); // value-initializes the array with 0's. -template <class T> -typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0, - std::unique_ptr<T>>::type -make_unique(size_t n) { - return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]()); -} - -/// This function isn't used and is only here to provide better compile errors. -template <class T, class... Args> -typename std::enable_if<std::extent<T>::value != 0>::type -make_unique(Args &&...) = delete; - struct FreeDeleter { void operator()(void* v) { ::free(v); @@ -1439,20 +1377,6 @@ struct pair_hash { } }; -/// A functor like C++14's std::less<void> in its absence. -struct less { - template <typename A, typename B> bool operator()(A &&a, B &&b) const { - return std::forward<A>(a) < std::forward<B>(b); - } -}; - -/// A functor like C++14's std::equal<void> in its absence. -struct equal { - template <typename A, typename B> bool operator()(A &&a, B &&b) const { - return std::forward<A>(a) == std::forward<B>(b); - } -}; - /// Binary functor that adapts to any other binary functor after dereferencing /// operands. template <typename T> struct deref { @@ -1580,7 +1504,7 @@ template <typename R> detail::enumerator<R> enumerate(R &&TheRange) { namespace detail { template <typename F, typename Tuple, std::size_t... I> -auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence<I...>) +auto apply_tuple_impl(F &&f, Tuple &&t, std::index_sequence<I...>) -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...)) { return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...); } @@ -1593,9 +1517,9 @@ auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence<I...>) template <typename F, typename Tuple> auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl( std::forward<F>(f), std::forward<Tuple>(t), - build_index_impl< + std::make_index_sequence< std::tuple_size<typename std::decay<Tuple>::type>::value>{})) { - using Indices = build_index_impl< + using Indices = std::make_index_sequence< std::tuple_size<typename std::decay<Tuple>::type>::value>; return detail::apply_tuple_impl(std::forward<F>(f), std::forward<Tuple>(t), diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 742450e6a951..61375c008022 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -290,7 +290,7 @@ public: ++Prev; uintptr_t Bits = getSmallBits(); // Mask in previous bits. - uintptr_t Mask = (1 << Prev) - 1; + uintptr_t Mask = (uintptr_t(1) << Prev) - 1; Bits |= Mask; if (Bits == ~uintptr_t(0) || Prev + 1 >= getSmallSize()) diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h index 2ac59da596ef..b7387ddcf1c7 100644 --- a/include/llvm/ADT/Statistic.h +++ b/include/llvm/ADT/Statistic.h @@ -44,38 +44,39 @@ class raw_ostream; class raw_fd_ostream; class StringRef; -class Statistic { +class StatisticBase { public: const char *DebugType; const char *Name; const char *Desc; - std::atomic<unsigned> Value; - std::atomic<bool> Initialized; - unsigned getValue() const { return Value.load(std::memory_order_relaxed); } + StatisticBase(const char *DebugType, const char *Name, const char *Desc) + : DebugType(DebugType), Name(Name), Desc(Desc) {} + const char *getDebugType() const { return DebugType; } const char *getName() const { return Name; } const char *getDesc() const { return Desc; } +}; - /// construct - This should only be called for non-global statistics. - void construct(const char *debugtype, const char *name, const char *desc) { - DebugType = debugtype; - Name = name; - Desc = desc; - Value = 0; - Initialized = false; - } +class TrackingStatistic : public StatisticBase { +public: + std::atomic<unsigned> Value; + std::atomic<bool> Initialized; + + TrackingStatistic(const char *DebugType, const char *Name, const char *Desc) + : StatisticBase(DebugType, Name, Desc), Value(0), Initialized(false) {} + + unsigned getValue() const { return Value.load(std::memory_order_relaxed); } // Allow use of this class as the value itself. operator unsigned() const { return getValue(); } -#if LLVM_ENABLE_STATS - const Statistic &operator=(unsigned Val) { + const TrackingStatistic &operator=(unsigned Val) { Value.store(Val, std::memory_order_relaxed); return init(); } - const Statistic &operator++() { + const TrackingStatistic &operator++() { Value.fetch_add(1, std::memory_order_relaxed); return init(); } @@ -85,7 +86,7 @@ public: return Value.fetch_add(1, std::memory_order_relaxed); } - const Statistic &operator--() { + const TrackingStatistic &operator--() { Value.fetch_sub(1, std::memory_order_relaxed); return init(); } @@ -95,14 +96,14 @@ public: return Value.fetch_sub(1, std::memory_order_relaxed); } - const Statistic &operator+=(unsigned V) { + const TrackingStatistic &operator+=(unsigned V) { if (V == 0) return *this; Value.fetch_add(V, std::memory_order_relaxed); return init(); } - const Statistic &operator-=(unsigned V) { + const TrackingStatistic &operator-=(unsigned V) { if (V == 0) return *this; Value.fetch_sub(V, std::memory_order_relaxed); @@ -119,54 +120,57 @@ public: init(); } -#else // Statistics are disabled in release builds. - - const Statistic &operator=(unsigned Val) { +protected: + TrackingStatistic &init() { + if (!Initialized.load(std::memory_order_acquire)) + RegisterStatistic(); return *this; } - const Statistic &operator++() { - return *this; - } + void RegisterStatistic(); +}; - unsigned operator++(int) { - return 0; - } +class NoopStatistic : public StatisticBase { +public: + using StatisticBase::StatisticBase; - const Statistic &operator--() { - return *this; - } + unsigned getValue() const { return 0; } - unsigned operator--(int) { - return 0; - } + // Allow use of this class as the value itself. + operator unsigned() const { return 0; } - const Statistic &operator+=(const unsigned &V) { - return *this; - } + const NoopStatistic &operator=(unsigned Val) { return *this; } - const Statistic &operator-=(const unsigned &V) { - return *this; - } + const NoopStatistic &operator++() { return *this; } - void updateMax(unsigned V) {} + unsigned operator++(int) { return 0; } -#endif // LLVM_ENABLE_STATS + const NoopStatistic &operator--() { return *this; } -protected: - Statistic &init() { - if (!Initialized.load(std::memory_order_acquire)) - RegisterStatistic(); - return *this; - } + unsigned operator--(int) { return 0; } - void RegisterStatistic(); + const NoopStatistic &operator+=(const unsigned &V) { return *this; } + + const NoopStatistic &operator-=(const unsigned &V) { return *this; } + + void updateMax(unsigned V) {} }; +#if LLVM_ENABLE_STATS +using Statistic = TrackingStatistic; +#else +using Statistic = NoopStatistic; +#endif + // STATISTIC - A macro to make definition of statistics really simple. This // automatically passes the DEBUG_TYPE of the file into the statistic. #define STATISTIC(VARNAME, DESC) \ - static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, {false}} + static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC} + +// ALWAYS_ENABLED_STATISTIC - A macro to define a statistic like STATISTIC but +// it is enabled even if LLVM_ENABLE_STATS is off. +#define ALWAYS_ENABLED_STATISTIC(VARNAME, DESC) \ + static llvm::TrackingStatistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC} /// Enable the collection and printing of statistics. void EnableStatistics(bool PrintOnExit = true); diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index 16ac90bd6c89..ef1a11e0619b 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -345,7 +345,7 @@ inline void join_items_impl(std::string &Result, Sep Separator, const Arg1 &A1, join_items_impl(Result, Separator, std::forward<Args>(Items)...); } -inline size_t join_one_item_size(char C) { return 1; } +inline size_t join_one_item_size(char) { return 1; } inline size_t join_one_item_size(const char *S) { return S ? ::strlen(S) : 0; } template <typename T> inline size_t join_one_item_size(const T &Str) { diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index 8a586fc26709..108185bd07b9 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -118,36 +118,59 @@ public: } }; -/// StringMapEntry - This is used to represent one value that is inserted into -/// a StringMap. It contains the Value itself and the key: the string length -/// and data. +/// StringMapEntryStorage - Holds the value in a StringMapEntry. +/// +/// Factored out into a separate base class to make it easier to specialize. +/// This is primarily intended to support StringSet, which doesn't need a value +/// stored at all. template<typename ValueTy> -class StringMapEntry : public StringMapEntryBase { +class StringMapEntryStorage : public StringMapEntryBase { public: ValueTy second; - explicit StringMapEntry(size_t strLen) + explicit StringMapEntryStorage(size_t strLen) : StringMapEntryBase(strLen), second() {} template <typename... InitTy> - StringMapEntry(size_t strLen, InitTy &&... InitVals) + StringMapEntryStorage(size_t strLen, InitTy &&... InitVals) : StringMapEntryBase(strLen), second(std::forward<InitTy>(InitVals)...) {} - StringMapEntry(StringMapEntry &E) = delete; - - StringRef getKey() const { - return StringRef(getKeyData(), getKeyLength()); - } + StringMapEntryStorage(StringMapEntryStorage &E) = delete; const ValueTy &getValue() const { return second; } ValueTy &getValue() { return second; } void setValue(const ValueTy &V) { second = V; } +}; + +template<> +class StringMapEntryStorage<NoneType> : public StringMapEntryBase { +public: + explicit StringMapEntryStorage(size_t strLen, NoneType none = None) + : StringMapEntryBase(strLen) {} + StringMapEntryStorage(StringMapEntryStorage &E) = delete; + + NoneType getValue() const { return None; } +}; + +/// StringMapEntry - This is used to represent one value that is inserted into +/// a StringMap. It contains the Value itself and the key: the string length +/// and data. +template<typename ValueTy> +class StringMapEntry final : public StringMapEntryStorage<ValueTy> { +public: + using StringMapEntryStorage<ValueTy>::StringMapEntryStorage; + + StringRef getKey() const { + return StringRef(getKeyData(), this->getKeyLength()); + } /// getKeyData - Return the start of the string data that is the key for this /// value. The string data is always stored immediately after the /// StringMapEntry object. const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);} - StringRef first() const { return StringRef(getKeyData(), getKeyLength()); } + StringRef first() const { + return StringRef(getKeyData(), this->getKeyLength()); + } /// Create a StringMapEntry for the specified key construct the value using /// \p InitiVals. @@ -199,7 +222,7 @@ public: template<typename AllocatorTy> void Destroy(AllocatorTy &Allocator) { // Free memory referenced by the item. - size_t AllocSize = sizeof(StringMapEntry) + getKeyLength() + 1; + size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1; this->~StringMapEntry(); Allocator.Deallocate(static_cast<void *>(this), AllocSize); } @@ -391,6 +414,16 @@ public: return try_emplace(KV.first, std::move(KV.second)); } + /// Inserts an element or assigns to the current element if the key already + /// exists. The return type is the same as try_emplace. + template <typename V> + std::pair<iterator, bool> insert_or_assign(StringRef Key, V &&Val) { + auto Ret = try_emplace(Key, std::forward<V>(Val)); + if (!Ret.second) + Ret.first->second = std::forward<V>(Val); + return Ret; + } + /// Emplace a new element for the specified key into the map if the key isn't /// already in the map. The bool component of the returned pair is true /// if and only if the insertion takes place, and the iterator component of diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 4661b1e68b2f..52baab17bede 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -67,6 +67,20 @@ namespace llvm { return ::memcmp(Lhs,Rhs,Length); } + // Constexpr version of std::strlen. + static constexpr size_t strLen(const char *Str) { +#if __cplusplus > 201402L + return std::char_traits<char>::length(Str); +#elif __has_builtin(__builtin_strlen) || defined(__GNUC__) + return __builtin_strlen(Str); +#else + const char *Begin = Str; + while (*Str != '\0') + ++Str; + return Str - Begin; +#endif + } + public: /// @name Constructors /// @{ @@ -79,8 +93,8 @@ namespace llvm { StringRef(std::nullptr_t) = delete; /// Construct a string ref from a cstring. - /*implicit*/ StringRef(const char *Str) - : Data(Str), Length(Str ? ::strlen(Str) : 0) {} + /*implicit*/ constexpr StringRef(const char *Str) + : Data(Str), Length(Str ? strLen(Str) : 0) {} /// Construct a string ref from a pointer and length. /*implicit*/ constexpr StringRef(const char *data, size_t length) diff --git a/include/llvm/ADT/StringSet.h b/include/llvm/ADT/StringSet.h index af3a44a7b32c..60be09d3c326 100644 --- a/include/llvm/ADT/StringSet.h +++ b/include/llvm/ADT/StringSet.h @@ -24,8 +24,8 @@ namespace llvm { /// StringSet - A wrapper for StringMap that provides set-like functionality. template <class AllocatorTy = MallocAllocator> - class StringSet : public StringMap<char, AllocatorTy> { - using base = StringMap<char, AllocatorTy>; + class StringSet : public StringMap<NoneType, AllocatorTy> { + using base = StringMap<NoneType, AllocatorTy>; public: StringSet() = default; @@ -37,13 +37,13 @@ namespace llvm { std::pair<typename base::iterator, bool> insert(StringRef Key) { assert(!Key.empty()); - return base::insert(std::make_pair(Key, '\0')); + return base::insert(std::make_pair(Key, None)); } template <typename InputIt> void insert(const InputIt &Begin, const InputIt &End) { for (auto It = Begin; It != End; ++It) - base::insert(std::make_pair(*It, '\0')); + base::insert(std::make_pair(*It, None)); } template <typename ValueTy> diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h index ac82451a9b21..6b76d35d4e92 100644 --- a/include/llvm/ADT/TinyPtrVector.h +++ b/include/llvm/ADT/TinyPtrVector.h @@ -31,6 +31,10 @@ class TinyPtrVector { public: using VecTy = SmallVector<EltTy, 4>; using value_type = typename VecTy::value_type; + // EltTy must be the first pointer type so that is<EltTy> is true for the + // default-constructed PtrUnion. This allows an empty TinyPtrVector to + // naturally vend a begin/end iterator of type EltTy* without an additional + // check for the empty state. using PtrUnion = PointerUnion<EltTy, VecTy *>; private: @@ -96,14 +100,14 @@ public: if (RHS.Val.template is<EltTy>()) { V->clear(); V->push_back(RHS.front()); - RHS.Val = (EltTy)nullptr; + RHS.Val = EltTy(); return *this; } delete V; } Val = RHS.Val; - RHS.Val = (EltTy)nullptr; + RHS.Val = EltTy(); return *this; } @@ -213,9 +217,9 @@ public: EltTy operator[](unsigned i) const { assert(!Val.isNull() && "can't index into an empty vector"); - if (EltTy V = Val.template dyn_cast<EltTy>()) { + if (Val.template is<EltTy>()) { assert(i == 0 && "tinyvector index out of range"); - return V; + return Val.template get<EltTy>(); } assert(i < Val.template get<VecTy*>()->size() && @@ -225,29 +229,29 @@ public: EltTy front() const { assert(!empty() && "vector empty"); - if (EltTy V = Val.template dyn_cast<EltTy>()) - return V; + if (Val.template is<EltTy>()) + return Val.template get<EltTy>(); return Val.template get<VecTy*>()->front(); } EltTy back() const { assert(!empty() && "vector empty"); - if (EltTy V = Val.template dyn_cast<EltTy>()) - return V; + if (Val.template is<EltTy>()) + return Val.template get<EltTy>(); return Val.template get<VecTy*>()->back(); } void push_back(EltTy NewVal) { - assert(NewVal && "Can't add a null value"); - // If we have nothing, add something. if (Val.isNull()) { Val = NewVal; + assert(!Val.isNull() && "Can't add a null value"); return; } // If we have a single value, convert to a vector. - if (EltTy V = Val.template dyn_cast<EltTy>()) { + if (Val.template is<EltTy>()) { + EltTy V = Val.template get<EltTy>(); Val = new VecTy(); Val.template get<VecTy*>()->push_back(V); } @@ -267,7 +271,7 @@ public: void clear() { // If we have a single value, convert to empty. if (Val.template is<EltTy>()) { - Val = (EltTy)nullptr; + Val = EltTy(); } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { // If we have a vector form, just clear it. Vec->clear(); @@ -282,7 +286,7 @@ public: // If we have a single value, convert to empty. if (Val.template is<EltTy>()) { if (I == begin()) - Val = (EltTy)nullptr; + Val = EltTy(); } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { // multiple items in a vector; just do the erase, there is no // benefit to collapsing back to a pointer @@ -298,7 +302,7 @@ public: if (Val.template is<EltTy>()) { if (S == begin() && S != E) - Val = (EltTy)nullptr; + Val = EltTy(); } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { return Vec->erase(S, E); } @@ -313,7 +317,8 @@ public: return std::prev(end()); } assert(!Val.isNull() && "Null value with non-end insert iterator."); - if (EltTy V = Val.template dyn_cast<EltTy>()) { + if (Val.template is<EltTy>()) { + EltTy V = Val.template get<EltTy>(); assert(I == begin()); Val = Elt; push_back(V); @@ -339,7 +344,8 @@ public: } Val = new VecTy(); - } else if (EltTy V = Val.template dyn_cast<EltTy>()) { + } else if (Val.template is<EltTy>()) { + EltTy V = Val.template get<EltTy>(); Val = new VecTy(); Val.template get<VecTy*>()->push_back(V); } diff --git a/include/llvm/ADT/VariadicFunction.h b/include/llvm/ADT/VariadicFunction.h deleted file mode 100644 index 5aefb05ecdda..000000000000 --- a/include/llvm/ADT/VariadicFunction.h +++ /dev/null @@ -1,330 +0,0 @@ -//===- VariadicFunction.h - Variadic Functions ------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements compile-time type-safe variadic functions. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ADT_VARIADICFUNCTION_H -#define LLVM_ADT_VARIADICFUNCTION_H - -#include "llvm/ADT/ArrayRef.h" - -namespace llvm { - -// Define macros to aid in expanding a comma separated series with the index of -// the series pasted onto the last token. -#define LLVM_COMMA_JOIN1(x) x ## 0 -#define LLVM_COMMA_JOIN2(x) LLVM_COMMA_JOIN1(x), x ## 1 -#define LLVM_COMMA_JOIN3(x) LLVM_COMMA_JOIN2(x), x ## 2 -#define LLVM_COMMA_JOIN4(x) LLVM_COMMA_JOIN3(x), x ## 3 -#define LLVM_COMMA_JOIN5(x) LLVM_COMMA_JOIN4(x), x ## 4 -#define LLVM_COMMA_JOIN6(x) LLVM_COMMA_JOIN5(x), x ## 5 -#define LLVM_COMMA_JOIN7(x) LLVM_COMMA_JOIN6(x), x ## 6 -#define LLVM_COMMA_JOIN8(x) LLVM_COMMA_JOIN7(x), x ## 7 -#define LLVM_COMMA_JOIN9(x) LLVM_COMMA_JOIN8(x), x ## 8 -#define LLVM_COMMA_JOIN10(x) LLVM_COMMA_JOIN9(x), x ## 9 -#define LLVM_COMMA_JOIN11(x) LLVM_COMMA_JOIN10(x), x ## 10 -#define LLVM_COMMA_JOIN12(x) LLVM_COMMA_JOIN11(x), x ## 11 -#define LLVM_COMMA_JOIN13(x) LLVM_COMMA_JOIN12(x), x ## 12 -#define LLVM_COMMA_JOIN14(x) LLVM_COMMA_JOIN13(x), x ## 13 -#define LLVM_COMMA_JOIN15(x) LLVM_COMMA_JOIN14(x), x ## 14 -#define LLVM_COMMA_JOIN16(x) LLVM_COMMA_JOIN15(x), x ## 15 -#define LLVM_COMMA_JOIN17(x) LLVM_COMMA_JOIN16(x), x ## 16 -#define LLVM_COMMA_JOIN18(x) LLVM_COMMA_JOIN17(x), x ## 17 -#define LLVM_COMMA_JOIN19(x) LLVM_COMMA_JOIN18(x), x ## 18 -#define LLVM_COMMA_JOIN20(x) LLVM_COMMA_JOIN19(x), x ## 19 -#define LLVM_COMMA_JOIN21(x) LLVM_COMMA_JOIN20(x), x ## 20 -#define LLVM_COMMA_JOIN22(x) LLVM_COMMA_JOIN21(x), x ## 21 -#define LLVM_COMMA_JOIN23(x) LLVM_COMMA_JOIN22(x), x ## 22 -#define LLVM_COMMA_JOIN24(x) LLVM_COMMA_JOIN23(x), x ## 23 -#define LLVM_COMMA_JOIN25(x) LLVM_COMMA_JOIN24(x), x ## 24 -#define LLVM_COMMA_JOIN26(x) LLVM_COMMA_JOIN25(x), x ## 25 -#define LLVM_COMMA_JOIN27(x) LLVM_COMMA_JOIN26(x), x ## 26 -#define LLVM_COMMA_JOIN28(x) LLVM_COMMA_JOIN27(x), x ## 27 -#define LLVM_COMMA_JOIN29(x) LLVM_COMMA_JOIN28(x), x ## 28 -#define LLVM_COMMA_JOIN30(x) LLVM_COMMA_JOIN29(x), x ## 29 -#define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30 -#define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31 - -/// Class which can simulate a type-safe variadic function. -/// -/// The VariadicFunction class template makes it easy to define -/// type-safe variadic functions where all arguments have the same -/// type. -/// -/// Suppose we need a variadic function like this: -/// -/// ResultT Foo(const ArgT &A_0, const ArgT &A_1, ..., const ArgT &A_N); -/// -/// Instead of many overloads of Foo(), we only need to define a helper -/// function that takes an array of arguments: -/// -/// ResultT FooImpl(ArrayRef<const ArgT *> Args) { -/// // 'Args[i]' is a pointer to the i-th argument passed to Foo(). -/// ... -/// } -/// -/// and then define Foo() like this: -/// -/// const VariadicFunction<ResultT, ArgT, FooImpl> Foo; -/// -/// VariadicFunction takes care of defining the overloads of Foo(). -/// -/// Actually, Foo is a function object (i.e. functor) instead of a plain -/// function. This object is stateless and its constructor/destructor -/// does nothing, so it's safe to create global objects and call Foo(...) at -/// any time. -/// -/// Sometimes we need a variadic function to have some fixed leading -/// arguments whose types may be different from that of the optional -/// arguments. For example: -/// -/// bool FullMatch(const StringRef &S, const RE &Regex, -/// const ArgT &A_0, ..., const ArgT &A_N); -/// -/// VariadicFunctionN is for such cases, where N is the number of fixed -/// arguments. It is like VariadicFunction, except that it takes N more -/// template arguments for the types of the fixed arguments: -/// -/// bool FullMatchImpl(const StringRef &S, const RE &Regex, -/// ArrayRef<const ArgT *> Args) { ... } -/// const VariadicFunction2<bool, const StringRef&, -/// const RE&, ArgT, FullMatchImpl> -/// FullMatch; -/// -/// Currently VariadicFunction and friends support up-to 3 -/// fixed leading arguments and up-to 32 optional arguments. -template <typename ResultT, typename ArgT, - ResultT (*Func)(ArrayRef<const ArgT *>)> -struct VariadicFunction { - ResultT operator()() const { - return Func(None); - } - -#define LLVM_DEFINE_OVERLOAD(N) \ - ResultT operator()(LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \ - const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \ - return Func(makeArrayRef(Args)); \ - } - LLVM_DEFINE_OVERLOAD(1) - LLVM_DEFINE_OVERLOAD(2) - LLVM_DEFINE_OVERLOAD(3) - LLVM_DEFINE_OVERLOAD(4) - LLVM_DEFINE_OVERLOAD(5) - LLVM_DEFINE_OVERLOAD(6) - LLVM_DEFINE_OVERLOAD(7) - LLVM_DEFINE_OVERLOAD(8) - LLVM_DEFINE_OVERLOAD(9) - LLVM_DEFINE_OVERLOAD(10) - LLVM_DEFINE_OVERLOAD(11) - LLVM_DEFINE_OVERLOAD(12) - LLVM_DEFINE_OVERLOAD(13) - LLVM_DEFINE_OVERLOAD(14) - LLVM_DEFINE_OVERLOAD(15) - LLVM_DEFINE_OVERLOAD(16) - LLVM_DEFINE_OVERLOAD(17) - LLVM_DEFINE_OVERLOAD(18) - LLVM_DEFINE_OVERLOAD(19) - LLVM_DEFINE_OVERLOAD(20) - LLVM_DEFINE_OVERLOAD(21) - LLVM_DEFINE_OVERLOAD(22) - LLVM_DEFINE_OVERLOAD(23) - LLVM_DEFINE_OVERLOAD(24) - LLVM_DEFINE_OVERLOAD(25) - LLVM_DEFINE_OVERLOAD(26) - LLVM_DEFINE_OVERLOAD(27) - LLVM_DEFINE_OVERLOAD(28) - LLVM_DEFINE_OVERLOAD(29) - LLVM_DEFINE_OVERLOAD(30) - LLVM_DEFINE_OVERLOAD(31) - LLVM_DEFINE_OVERLOAD(32) -#undef LLVM_DEFINE_OVERLOAD -}; - -template <typename ResultT, typename Param0T, typename ArgT, - ResultT (*Func)(Param0T, ArrayRef<const ArgT *>)> -struct VariadicFunction1 { - ResultT operator()(Param0T P0) const { - return Func(P0, None); - } - -#define LLVM_DEFINE_OVERLOAD(N) \ - ResultT operator()(Param0T P0, LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \ - const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \ - return Func(P0, makeArrayRef(Args)); \ - } - LLVM_DEFINE_OVERLOAD(1) - LLVM_DEFINE_OVERLOAD(2) - LLVM_DEFINE_OVERLOAD(3) - LLVM_DEFINE_OVERLOAD(4) - LLVM_DEFINE_OVERLOAD(5) - LLVM_DEFINE_OVERLOAD(6) - LLVM_DEFINE_OVERLOAD(7) - LLVM_DEFINE_OVERLOAD(8) - LLVM_DEFINE_OVERLOAD(9) - LLVM_DEFINE_OVERLOAD(10) - LLVM_DEFINE_OVERLOAD(11) - LLVM_DEFINE_OVERLOAD(12) - LLVM_DEFINE_OVERLOAD(13) - LLVM_DEFINE_OVERLOAD(14) - LLVM_DEFINE_OVERLOAD(15) - LLVM_DEFINE_OVERLOAD(16) - LLVM_DEFINE_OVERLOAD(17) - LLVM_DEFINE_OVERLOAD(18) - LLVM_DEFINE_OVERLOAD(19) - LLVM_DEFINE_OVERLOAD(20) - LLVM_DEFINE_OVERLOAD(21) - LLVM_DEFINE_OVERLOAD(22) - LLVM_DEFINE_OVERLOAD(23) - LLVM_DEFINE_OVERLOAD(24) - LLVM_DEFINE_OVERLOAD(25) - LLVM_DEFINE_OVERLOAD(26) - LLVM_DEFINE_OVERLOAD(27) - LLVM_DEFINE_OVERLOAD(28) - LLVM_DEFINE_OVERLOAD(29) - LLVM_DEFINE_OVERLOAD(30) - LLVM_DEFINE_OVERLOAD(31) - LLVM_DEFINE_OVERLOAD(32) -#undef LLVM_DEFINE_OVERLOAD -}; - -template <typename ResultT, typename Param0T, typename Param1T, typename ArgT, - ResultT (*Func)(Param0T, Param1T, ArrayRef<const ArgT *>)> -struct VariadicFunction2 { - ResultT operator()(Param0T P0, Param1T P1) const { - return Func(P0, P1, None); - } - -#define LLVM_DEFINE_OVERLOAD(N) \ - ResultT operator()(Param0T P0, Param1T P1, \ - LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \ - const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \ - return Func(P0, P1, makeArrayRef(Args)); \ - } - LLVM_DEFINE_OVERLOAD(1) - LLVM_DEFINE_OVERLOAD(2) - LLVM_DEFINE_OVERLOAD(3) - LLVM_DEFINE_OVERLOAD(4) - LLVM_DEFINE_OVERLOAD(5) - LLVM_DEFINE_OVERLOAD(6) - LLVM_DEFINE_OVERLOAD(7) - LLVM_DEFINE_OVERLOAD(8) - LLVM_DEFINE_OVERLOAD(9) - LLVM_DEFINE_OVERLOAD(10) - LLVM_DEFINE_OVERLOAD(11) - LLVM_DEFINE_OVERLOAD(12) - LLVM_DEFINE_OVERLOAD(13) - LLVM_DEFINE_OVERLOAD(14) - LLVM_DEFINE_OVERLOAD(15) - LLVM_DEFINE_OVERLOAD(16) - LLVM_DEFINE_OVERLOAD(17) - LLVM_DEFINE_OVERLOAD(18) - LLVM_DEFINE_OVERLOAD(19) - LLVM_DEFINE_OVERLOAD(20) - LLVM_DEFINE_OVERLOAD(21) - LLVM_DEFINE_OVERLOAD(22) - LLVM_DEFINE_OVERLOAD(23) - LLVM_DEFINE_OVERLOAD(24) - LLVM_DEFINE_OVERLOAD(25) - LLVM_DEFINE_OVERLOAD(26) - LLVM_DEFINE_OVERLOAD(27) - LLVM_DEFINE_OVERLOAD(28) - LLVM_DEFINE_OVERLOAD(29) - LLVM_DEFINE_OVERLOAD(30) - LLVM_DEFINE_OVERLOAD(31) - LLVM_DEFINE_OVERLOAD(32) -#undef LLVM_DEFINE_OVERLOAD -}; - -template <typename ResultT, typename Param0T, typename Param1T, - typename Param2T, typename ArgT, - ResultT (*Func)(Param0T, Param1T, Param2T, ArrayRef<const ArgT *>)> -struct VariadicFunction3 { - ResultT operator()(Param0T P0, Param1T P1, Param2T P2) const { - return Func(P0, P1, P2, None); - } - -#define LLVM_DEFINE_OVERLOAD(N) \ - ResultT operator()(Param0T P0, Param1T P1, Param2T P2, \ - LLVM_COMMA_JOIN ## N(const ArgT &A)) const { \ - const ArgT *const Args[] = { LLVM_COMMA_JOIN ## N(&A) }; \ - return Func(P0, P1, P2, makeArrayRef(Args)); \ - } - LLVM_DEFINE_OVERLOAD(1) - LLVM_DEFINE_OVERLOAD(2) - LLVM_DEFINE_OVERLOAD(3) - LLVM_DEFINE_OVERLOAD(4) - LLVM_DEFINE_OVERLOAD(5) - LLVM_DEFINE_OVERLOAD(6) - LLVM_DEFINE_OVERLOAD(7) - LLVM_DEFINE_OVERLOAD(8) - LLVM_DEFINE_OVERLOAD(9) - LLVM_DEFINE_OVERLOAD(10) - LLVM_DEFINE_OVERLOAD(11) - LLVM_DEFINE_OVERLOAD(12) - LLVM_DEFINE_OVERLOAD(13) - LLVM_DEFINE_OVERLOAD(14) - LLVM_DEFINE_OVERLOAD(15) - LLVM_DEFINE_OVERLOAD(16) - LLVM_DEFINE_OVERLOAD(17) - LLVM_DEFINE_OVERLOAD(18) - LLVM_DEFINE_OVERLOAD(19) - LLVM_DEFINE_OVERLOAD(20) - LLVM_DEFINE_OVERLOAD(21) - LLVM_DEFINE_OVERLOAD(22) - LLVM_DEFINE_OVERLOAD(23) - LLVM_DEFINE_OVERLOAD(24) - LLVM_DEFINE_OVERLOAD(25) - LLVM_DEFINE_OVERLOAD(26) - LLVM_DEFINE_OVERLOAD(27) - LLVM_DEFINE_OVERLOAD(28) - LLVM_DEFINE_OVERLOAD(29) - LLVM_DEFINE_OVERLOAD(30) - LLVM_DEFINE_OVERLOAD(31) - LLVM_DEFINE_OVERLOAD(32) -#undef LLVM_DEFINE_OVERLOAD -}; - -// Cleanup the macro namespace. -#undef LLVM_COMMA_JOIN1 -#undef LLVM_COMMA_JOIN2 -#undef LLVM_COMMA_JOIN3 -#undef LLVM_COMMA_JOIN4 -#undef LLVM_COMMA_JOIN5 -#undef LLVM_COMMA_JOIN6 -#undef LLVM_COMMA_JOIN7 -#undef LLVM_COMMA_JOIN8 -#undef LLVM_COMMA_JOIN9 -#undef LLVM_COMMA_JOIN10 -#undef LLVM_COMMA_JOIN11 -#undef LLVM_COMMA_JOIN12 -#undef LLVM_COMMA_JOIN13 -#undef LLVM_COMMA_JOIN14 -#undef LLVM_COMMA_JOIN15 -#undef LLVM_COMMA_JOIN16 -#undef LLVM_COMMA_JOIN17 -#undef LLVM_COMMA_JOIN18 -#undef LLVM_COMMA_JOIN19 -#undef LLVM_COMMA_JOIN20 -#undef LLVM_COMMA_JOIN21 -#undef LLVM_COMMA_JOIN22 -#undef LLVM_COMMA_JOIN23 -#undef LLVM_COMMA_JOIN24 -#undef LLVM_COMMA_JOIN25 -#undef LLVM_COMMA_JOIN26 -#undef LLVM_COMMA_JOIN27 -#undef LLVM_COMMA_JOIN28 -#undef LLVM_COMMA_JOIN29 -#undef LLVM_COMMA_JOIN30 -#undef LLVM_COMMA_JOIN31 -#undef LLVM_COMMA_JOIN32 - -} // end namespace llvm - -#endif // LLVM_ADT_VARIADICFUNCTION_H diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h index 774c7c4e3366..aa8830943cab 100644 --- a/include/llvm/ADT/iterator_range.h +++ b/include/llvm/ADT/iterator_range.h @@ -44,6 +44,7 @@ public: IteratorT begin() const { return begin_iterator; } IteratorT end() const { return end_iterator; } + bool empty() const { return begin_iterator == end_iterator; } }; /// Convenience function for iterating over sub-ranges. |