aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/ADT
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r--include/llvm/ADT/APFloat.h5
-rw-r--r--include/llvm/ADT/APInt.h9
-rw-r--r--include/llvm/ADT/Any.h4
-rw-r--r--include/llvm/ADT/ArrayRef.h6
-rw-r--r--include/llvm/ADT/DenseMap.h57
-rw-r--r--include/llvm/ADT/DenseMapInfo.h13
-rw-r--r--include/llvm/ADT/DirectedGraph.h270
-rw-r--r--include/llvm/ADT/Hashing.h1
-rw-r--r--include/llvm/ADT/IntervalMap.h4
-rw-r--r--include/llvm/ADT/PointerIntPair.h11
-rw-r--r--include/llvm/ADT/PointerUnion.h30
-rw-r--r--include/llvm/ADT/STLExtras.h168
-rw-r--r--include/llvm/ADT/SmallBitVector.h2
-rw-r--r--include/llvm/ADT/Statistic.h102
-rw-r--r--include/llvm/ADT/StringExtras.h2
-rw-r--r--include/llvm/ADT/StringMap.h59
-rw-r--r--include/llvm/ADT/StringRef.h18
-rw-r--r--include/llvm/ADT/StringSet.h8
-rw-r--r--include/llvm/ADT/TinyPtrVector.h38
-rw-r--r--include/llvm/ADT/VariadicFunction.h330
-rw-r--r--include/llvm/ADT/iterator_range.h1
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.