aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/ADT
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2015-12-30 11:46:15 +0000
committerDimitry Andric <dim@FreeBSD.org>2015-12-30 11:46:15 +0000
commitdd58ef019b700900793a1eb48b52123db01b654e (patch)
treefcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /include/llvm/ADT
parent2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff)
Notes
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r--include/llvm/ADT/APFloat.h8
-rw-r--r--include/llvm/ADT/APInt.h7
-rw-r--r--include/llvm/ADT/APSInt.h6
-rw-r--r--include/llvm/ADT/ArrayRef.h21
-rw-r--r--include/llvm/ADT/BitVector.h10
-rw-r--r--include/llvm/ADT/DeltaAlgorithm.h2
-rw-r--r--include/llvm/ADT/DenseMap.h26
-rw-r--r--include/llvm/ADT/DenseMapInfo.h28
-rw-r--r--include/llvm/ADT/DenseSet.h5
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h22
-rw-r--r--include/llvm/ADT/FoldingSet.h37
-rw-r--r--include/llvm/ADT/ImmutableList.h12
-rw-r--r--include/llvm/ADT/ImmutableMap.h101
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h4
-rw-r--r--include/llvm/ADT/Optional.h19
-rw-r--r--include/llvm/ADT/PackedVector.h28
-rw-r--r--include/llvm/ADT/PointerIntPair.h178
-rw-r--r--include/llvm/ADT/PointerUnion.h818
-rw-r--r--include/llvm/ADT/PostOrderIterator.h8
-rw-r--r--include/llvm/ADT/STLExtras.h52
-rw-r--r--include/llvm/ADT/ScopedHashTable.h40
-rw-r--r--include/llvm/ADT/SetOperations.h2
-rw-r--r--include/llvm/ADT/SetVector.h30
-rw-r--r--include/llvm/ADT/SmallBitVector.h23
-rw-r--r--include/llvm/ADT/SmallPtrSet.h13
-rw-r--r--include/llvm/ADT/SmallSet.h4
-rw-r--r--include/llvm/ADT/SmallVector.h7
-rw-r--r--include/llvm/ADT/SparseBitVector.h48
-rw-r--r--include/llvm/ADT/Statistic.h5
-rw-r--r--include/llvm/ADT/StringMap.h22
-rw-r--r--include/llvm/ADT/StringRef.h37
-rw-r--r--include/llvm/ADT/StringSet.h5
-rw-r--r--include/llvm/ADT/StringSwitch.h50
-rw-r--r--include/llvm/ADT/TinyPtrVector.h3
-rw-r--r--include/llvm/ADT/Triple.h97
-rw-r--r--include/llvm/ADT/UniqueVector.h1
-rw-r--r--include/llvm/ADT/ilist.h152
-rw-r--r--include/llvm/ADT/ilist_node.h89
-rw-r--r--include/llvm/ADT/iterator_range.h12
39 files changed, 1243 insertions, 789 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 76615affb253..3fe04060fd59 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -142,6 +142,9 @@ public:
/// @}
static unsigned int semanticsPrecision(const fltSemantics &);
+ static ExponentType semanticsMinExponent(const fltSemantics &);
+ static ExponentType semanticsMaxExponent(const fltSemantics &);
+ static unsigned int semanticsSizeInBits(const fltSemantics &);
/// IEEE-754R 5.11: Floating Point Comparison Relations.
enum cmpResult {
@@ -296,7 +299,7 @@ public:
/// IEEE remainder.
opStatus remainder(const APFloat &);
/// C fmod, or llvm frem.
- opStatus mod(const APFloat &, roundingMode);
+ opStatus mod(const APFloat &);
opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
opStatus roundToIntegral(roundingMode);
/// IEEE-754R 5.3.1: nextUp/nextDown.
@@ -445,6 +448,9 @@ public:
/// Returns true if and only if the number has the largest possible finite
/// magnitude in the current semantics.
bool isLargest() const;
+
+ /// Returns true if and only if the number is an exact integer.
+ bool isInteger() const;
/// @}
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 5013f295f5c7..e2a0cb5e69dc 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -294,11 +294,12 @@ public:
delete[] pVal;
}
- /// \brief Default constructor that creates an uninitialized APInt.
+ /// \brief Default constructor that creates an uninteresting APInt
+ /// representing a 1-bit zero value.
///
/// This is useful for object deserialization (pair this with the static
/// method Read).
- explicit APInt() : BitWidth(1) {}
+ explicit APInt() : BitWidth(1), VAL(0) {}
/// \brief Returns whether this instance allocated memory.
bool needsCleanup() const { return !isSingleWord(); }
@@ -1528,7 +1529,7 @@ public:
/// \returns the nearest log base 2 of this APInt. Ties round up.
///
/// NOTE: When we have a BitWidth of 1, we define:
- ///
+ ///
/// log2(0) = UINT32_MAX
/// log2(1) = 0
///
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index a187515f8592..a6552d0a2f36 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -21,6 +21,7 @@ namespace llvm {
class APSInt : public APInt {
bool IsUnsigned;
+
public:
/// Default constructor that creates an uninitialized APInt.
explicit APSInt() : IsUnsigned(false) {}
@@ -246,8 +247,7 @@ public:
return this->operator|(RHS);
}
-
- APSInt operator^(const APSInt& RHS) const {
+ APSInt operator^(const APSInt &RHS) const {
assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned);
}
@@ -286,7 +286,7 @@ public:
}
/// \brief Determine if two APSInts have the same value, zero- or
- /// sign-extending as needed.
+ /// sign-extending as needed.
static bool isSameValue(const APSInt &I1, const APSInt &I2) {
return !compareValues(I1, I2);
}
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index c8795fd89e33..517ba39849e1 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -10,6 +10,7 @@
#ifndef LLVM_ADT_ARRAYREF_H
#define LLVM_ADT_ARRAYREF_H
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallVector.h"
#include <vector>
@@ -85,7 +86,7 @@ namespace llvm {
/// Construct an ArrayRef from a std::initializer_list.
/*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
- : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()),
+ : Data(Vec.begin() == Vec.end() ? (T*)nullptr : Vec.begin()),
Length(Vec.size()) {}
/// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to
@@ -148,7 +149,7 @@ namespace llvm {
// copy - Allocate copy in Allocator and return ArrayRef<T> to it.
template <typename Allocator> ArrayRef<T> copy(Allocator &A) {
T *Buff = A.template Allocate<T>(Length);
- std::copy(begin(), end(), Buff);
+ std::uninitialized_copy(begin(), end(), Buff);
return ArrayRef<T>(Buff, Length);
}
@@ -156,8 +157,6 @@ namespace llvm {
bool equals(ArrayRef RHS) const {
if (Length != RHS.Length)
return false;
- if (Length == 0)
- return true;
return std::equal(begin(), end(), RHS.begin());
}
@@ -339,6 +338,16 @@ namespace llvm {
return Vec;
}
+ /// Construct an ArrayRef from an ArrayRef (no-op) (const)
+ template <typename T> ArrayRef<T> makeArrayRef(const ArrayRef<T> &Vec) {
+ return Vec;
+ }
+
+ /// Construct an ArrayRef from an ArrayRef (no-op)
+ template <typename T> ArrayRef<T> &makeArrayRef(ArrayRef<T> &Vec) {
+ return Vec;
+ }
+
/// Construct an ArrayRef from a C array.
template<typename T, size_t N>
ArrayRef<T> makeArrayRef(const T (&Arr)[N]) {
@@ -366,6 +375,10 @@ namespace llvm {
template <typename T> struct isPodLike<ArrayRef<T> > {
static const bool value = true;
};
+
+ template <typename T> hash_code hash_value(ArrayRef<T> S) {
+ return hash_combine_range(S.begin(), S.end());
+ }
}
#endif
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index f58dd7356c7d..ad00d51f99e9 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -34,7 +34,7 @@ class BitVector {
BitWord *Bits; // Actual bits.
unsigned Size; // Size of bitvector in bits.
- unsigned Capacity; // Size of allocated memory in BitWord.
+ unsigned Capacity; // Number of BitWords allocated in the Bits array.
public:
typedef unsigned size_type;
@@ -566,8 +566,16 @@ private:
if (AddBits)
clear_unused_bits();
}
+
+public:
+ /// Return the size (in bytes) of the bit vector.
+ size_t getMemorySize() const { return Capacity * sizeof(BitWord); }
};
+static inline size_t capacity_in_bytes(const BitVector &X) {
+ return X.getMemorySize();
+}
+
} // End llvm namespace
namespace std {
diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h
index 21bc1e80c9d8..a26f37dfdc7d 100644
--- a/include/llvm/ADT/DeltaAlgorithm.h
+++ b/include/llvm/ADT/DeltaAlgorithm.h
@@ -68,7 +68,7 @@ private:
/// \return - True on success.
bool Search(const changeset_ty &Changes, const changesetlist_ty &Sets,
changeset_ty &Res);
-
+
protected:
/// UpdatedSearchState - Callback used when the search state changes.
virtual void UpdatedSearchState(const changeset_ty &Changes,
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 27f73157a29f..6ee1960b5c82 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -282,7 +282,7 @@ protected:
"# initial buckets must be a power of two!");
const KeyT EmptyKey = getEmptyKey();
for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
- new (&B->getFirst()) KeyT(EmptyKey);
+ ::new (&B->getFirst()) KeyT(EmptyKey);
}
void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) {
@@ -300,7 +300,7 @@ protected:
(void)FoundVal; // silence warning.
assert(!FoundVal && "Key already in new map?");
DestBucket->getFirst() = std::move(B->getFirst());
- new (&DestBucket->getSecond()) ValueT(std::move(B->getSecond()));
+ ::new (&DestBucket->getSecond()) ValueT(std::move(B->getSecond()));
incrementNumEntries();
// Free the value.
@@ -324,11 +324,11 @@ protected:
getNumBuckets() * sizeof(BucketT));
else
for (size_t i = 0; i < getNumBuckets(); ++i) {
- new (&getBuckets()[i].getFirst())
+ ::new (&getBuckets()[i].getFirst())
KeyT(other.getBuckets()[i].getFirst());
if (!KeyInfoT::isEqual(getBuckets()[i].getFirst(), getEmptyKey()) &&
!KeyInfoT::isEqual(getBuckets()[i].getFirst(), getTombstoneKey()))
- new (&getBuckets()[i].getSecond())
+ ::new (&getBuckets()[i].getSecond())
ValueT(other.getBuckets()[i].getSecond());
}
}
@@ -402,7 +402,7 @@ private:
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
TheBucket->getFirst() = Key;
- new (&TheBucket->getSecond()) ValueT(Value);
+ ::new (&TheBucket->getSecond()) ValueT(Value);
return TheBucket;
}
@@ -411,7 +411,7 @@ private:
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
TheBucket->getFirst() = Key;
- new (&TheBucket->getSecond()) ValueT(std::move(Value));
+ ::new (&TheBucket->getSecond()) ValueT(std::move(Value));
return TheBucket;
}
@@ -419,7 +419,7 @@ private:
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
TheBucket->getFirst() = std::move(Key);
- new (&TheBucket->getSecond()) ValueT(std::move(Value));
+ ::new (&TheBucket->getSecond()) ValueT(std::move(Value));
return TheBucket;
}
@@ -766,10 +766,10 @@ public:
// Swap separately and handle any assymetry.
std::swap(LHSB->getFirst(), RHSB->getFirst());
if (hasLHSValue) {
- new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
+ ::new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
LHSB->getSecond().~ValueT();
} else if (hasRHSValue) {
- new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond()));
+ ::new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond()));
RHSB->getSecond().~ValueT();
}
}
@@ -795,11 +795,11 @@ public:
for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
BucketT *NewB = &LargeSide.getInlineBuckets()[i],
*OldB = &SmallSide.getInlineBuckets()[i];
- new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst()));
+ ::new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst()));
OldB->getFirst().~KeyT();
if (!KeyInfoT::isEqual(NewB->getFirst(), EmptyKey) &&
!KeyInfoT::isEqual(NewB->getFirst(), TombstoneKey)) {
- new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond()));
+ ::new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond()));
OldB->getSecond().~ValueT();
}
}
@@ -866,8 +866,8 @@ public:
!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
"Too many inline buckets!");
- new (&TmpEnd->getFirst()) KeyT(std::move(P->getFirst()));
- new (&TmpEnd->getSecond()) ValueT(std::move(P->getSecond()));
+ ::new (&TmpEnd->getFirst()) KeyT(std::move(P->getFirst()));
+ ::new (&TmpEnd->getSecond()) ValueT(std::move(P->getSecond()));
++TmpEnd;
P->getSecond().~ValueT();
}
diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h
index b0a053072079..a844ebcccf5b 100644
--- a/include/llvm/ADT/DenseMapInfo.h
+++ b/include/llvm/ADT/DenseMapInfo.h
@@ -14,6 +14,7 @@
#ifndef LLVM_ADT_DENSEMAPINFO_H
#define LLVM_ADT_DENSEMAPINFO_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
@@ -58,7 +59,7 @@ template<> struct DenseMapInfo<char> {
return LHS == RHS;
}
};
-
+
// Provide DenseMapInfo for unsigned ints.
template<> struct DenseMapInfo<unsigned> {
static inline unsigned getEmptyKey() { return ~0U; }
@@ -190,6 +191,31 @@ template <> struct DenseMapInfo<StringRef> {
}
};
+// Provide DenseMapInfo for ArrayRefs.
+template <typename T> struct DenseMapInfo<ArrayRef<T>> {
+ static inline ArrayRef<T> getEmptyKey() {
+ return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(0)),
+ size_t(0));
+ }
+ static inline ArrayRef<T> getTombstoneKey() {
+ return ArrayRef<T>(reinterpret_cast<const T *>(~static_cast<uintptr_t>(1)),
+ size_t(0));
+ }
+ static unsigned getHashValue(ArrayRef<T> Val) {
+ assert(Val.data() != getEmptyKey().data() && "Cannot hash the empty key!");
+ assert(Val.data() != getTombstoneKey().data() &&
+ "Cannot hash the tombstone key!");
+ return (unsigned)(hash_value(Val));
+ }
+ static bool isEqual(ArrayRef<T> LHS, ArrayRef<T> RHS) {
+ if (RHS.data() == getEmptyKey().data())
+ return LHS.data() == getEmptyKey().data();
+ if (RHS.data() == getTombstoneKey().data())
+ return LHS.data() == getTombstoneKey().data();
+ return LHS == RHS;
+ }
+};
+
} // end namespace llvm
#endif
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index d34024005dfe..ef09dce37980 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -42,6 +42,7 @@ class DenseSet {
static_assert(sizeof(typename MapTy::value_type) == sizeof(ValueT),
"DenseMap buckets unexpectedly large!");
MapTy TheMap;
+
public:
typedef ValueT key_type;
typedef ValueT value_type;
@@ -79,6 +80,7 @@ public:
class Iterator {
typename MapTy::iterator I;
friend class DenseSet;
+
public:
typedef typename MapTy::iterator::difference_type difference_type;
typedef ValueT value_type;
@@ -99,6 +101,7 @@ public:
class ConstIterator {
typename MapTy::const_iterator I;
friend class DenseSet;
+
public:
typedef typename MapTy::const_iterator::difference_type difference_type;
typedef ValueT value_type;
@@ -148,7 +151,7 @@ public:
detail::DenseSetEmpty Empty;
return TheMap.insert(std::make_pair(V, Empty));
}
-
+
// Range insertion of values.
template<typename InputIt>
void insert(InputIt I, InputIt E) {
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
index d79b9acacfa9..c9317b8539b3 100644
--- a/include/llvm/ADT/DepthFirstIterator.h
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -58,7 +58,6 @@ public:
SetType &Visited;
};
-
// Generic Depth First Iterator
template<class GraphT,
class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
@@ -76,21 +75,22 @@ class df_iterator : public std::iterator<std::forward_iterator_tag,
// VisitStack - Used to maintain the ordering. Top = current block
// First element is node pointer, second is the 'next child' to visit
// if the int in PointerIntTy is 0, the 'next child' to visit is invalid
- std::vector<std::pair<PointerIntTy, ChildItTy> > VisitStack;
+ std::vector<std::pair<PointerIntTy, ChildItTy>> VisitStack;
+
private:
inline df_iterator(NodeType *Node) {
this->Visited.insert(Node);
- VisitStack.push_back(std::make_pair(PointerIntTy(Node, 0),
- GT::child_begin(Node)));
+ VisitStack.push_back(
+ std::make_pair(PointerIntTy(Node, 0), GT::child_begin(Node)));
}
- inline df_iterator() {
- // End is when stack is empty
+ inline df_iterator() {
+ // End is when stack is empty
}
inline df_iterator(NodeType *Node, SetType &S)
: df_iterator_storage<SetType, ExtStorage>(S) {
if (!S.count(Node)) {
- VisitStack.push_back(std::make_pair(PointerIntTy(Node, 0),
- GT::child_begin(Node)));
+ VisitStack.push_back(
+ std::make_pair(PointerIntTy(Node, 0), GT::child_begin(Node)));
this->Visited.insert(Node);
}
}
@@ -115,8 +115,8 @@ private:
// Has our next sibling been visited?
if (Next && this->Visited.insert(Next).second) {
// No, do it now.
- VisitStack.push_back(std::make_pair(PointerIntTy(Next, 0),
- GT::child_begin(Next)));
+ VisitStack.push_back(
+ std::make_pair(PointerIntTy(Next, 0), GT::child_begin(Next)));
return;
}
}
@@ -195,7 +195,6 @@ public:
}
};
-
// Provide global constructors that automatically figure out correct types...
//
template <class T>
@@ -237,7 +236,6 @@ iterator_range<df_ext_iterator<T, SetTy>> depth_first_ext(const T& G,
return make_range(df_ext_begin(G, S), df_ext_end(G, S));
}
-
// Provide global definitions of inverse depth first iterators...
template <class T,
class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeType*, 8>,
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 52d10c1c1245..c9205396591b 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -122,9 +122,10 @@ protected:
/// is greater than twice the number of buckets.
unsigned NumNodes;
- ~FoldingSetImpl();
-
explicit FoldingSetImpl(unsigned Log2InitSize = 6);
+ FoldingSetImpl(FoldingSetImpl &&Arg);
+ FoldingSetImpl &operator=(FoldingSetImpl &&RHS);
+ ~FoldingSetImpl();
public:
//===--------------------------------------------------------------------===//
@@ -137,7 +138,6 @@ public:
void *NextInFoldingSetBucket;
public:
-
Node() : NextInFoldingSetBucket(nullptr) {}
// Accessors
@@ -182,13 +182,11 @@ public:
bool empty() const { return NumNodes == 0; }
private:
-
/// GrowHashTable - Double the size of the hash table and rehash everything.
///
void GrowHashTable();
protected:
-
/// GetNodeProfile - Instantiations of the FoldingSet template implement
/// this function to gather data bits for the given node.
virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0;
@@ -269,6 +267,7 @@ template<typename T, typename Ctx> struct ContextualFoldingSetTrait
class FoldingSetNodeIDRef {
const unsigned *Data;
size_t Size;
+
public:
FoldingSetNodeIDRef() : Data(nullptr), Size(0) {}
FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
@@ -393,6 +392,10 @@ DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
/// implementation of the folding set to the node class T. T must be a
/// subclass of FoldingSetNode and implement a Profile function.
///
+/// Note that this set type is movable and move-assignable. However, its
+/// moved-from state is not a valid state for anything other than
+/// move-assigning and destroying. This is primarily to enable movable APIs
+/// that incorporate these objects.
template <class T> class FoldingSet final : public FoldingSetImpl {
private:
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
@@ -417,8 +420,13 @@ private:
public:
explicit FoldingSet(unsigned Log2InitSize = 6)
- : FoldingSetImpl(Log2InitSize)
- {}
+ : FoldingSetImpl(Log2InitSize) {}
+
+ FoldingSet(FoldingSet &&Arg) : FoldingSetImpl(std::move(Arg)) {}
+ FoldingSet &operator=(FoldingSet &&RHS) {
+ (void)FoldingSetImpl::operator=(std::move(RHS));
+ return *this;
+ }
typedef FoldingSetIterator<T> iterator;
iterator begin() { return iterator(Buckets); }
@@ -498,7 +506,6 @@ public:
Ctx getContext() const { return Context; }
-
typedef FoldingSetIterator<T> iterator;
iterator begin() { return iterator(Buckets); }
iterator end() { return iterator(Buckets+NumBuckets); }
@@ -614,9 +621,7 @@ public:
}
};
-
-template<class T>
-class FoldingSetIterator : public FoldingSetIteratorImpl {
+template <class T> class FoldingSetIterator : public FoldingSetIteratorImpl {
public:
explicit FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {}
@@ -666,8 +671,7 @@ public:
}
};
-
-template<class T>
+template <class T>
class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl {
public:
explicit FoldingSetBucketIterator(void **Bucket) :
@@ -694,6 +698,7 @@ public:
template <typename T>
class FoldingSetNodeWrapper : public FoldingSetNode {
T data;
+
public:
template <typename... Ts>
explicit FoldingSetNodeWrapper(Ts &&... Args)
@@ -716,12 +721,12 @@ public:
/// information that would otherwise only be required for recomputing an ID.
class FastFoldingSetNode : public FoldingSetNode {
FoldingSetNodeID FastID;
+
protected:
explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
+
public:
- void Profile(FoldingSetNodeID &ID) const {
- ID.AddNodeID(FastID);
- }
+ void Profile(FoldingSetNodeID &ID) const { ID.AddNodeID(FastID); }
};
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h
index 748d3e4bf9ff..a1d26bd97045 100644
--- a/include/llvm/ADT/ImmutableList.h
+++ b/include/llvm/ADT/ImmutableList.h
@@ -28,7 +28,7 @@ class ImmutableListImpl : public FoldingSetNode {
T Head;
const ImmutableListImpl* Tail;
- ImmutableListImpl(const T& head, const ImmutableListImpl* tail = 0)
+ ImmutableListImpl(const T& head, const ImmutableListImpl* tail = nullptr)
: Head(head), Tail(tail) {}
friend class ImmutableListFactory<T>;
@@ -72,7 +72,7 @@ public:
// This constructor should normally only be called by ImmutableListFactory<T>.
// There may be cases, however, when one needs to extract the internal pointer
// and reconstruct a list object from that pointer.
- ImmutableList(const ImmutableListImpl<T>* x = 0) : X(x) {}
+ ImmutableList(const ImmutableListImpl<T>* x = nullptr) : X(x) {}
const ImmutableListImpl<T>* getInternalPointer() const {
return X;
@@ -81,7 +81,7 @@ public:
class iterator {
const ImmutableListImpl<T>* L;
public:
- iterator() : L(0) {}
+ iterator() : L(nullptr) {}
iterator(ImmutableList l) : L(l.getInternalPointer()) {}
iterator& operator++() { L = L->getTail(); return *this; }
@@ -128,7 +128,7 @@ public:
/// getTail - Returns the tail of the list, which is another (possibly empty)
/// ImmutableList.
ImmutableList getTail() {
- return X ? X->getTail() : 0;
+ return X ? X->getTail() : nullptr;
}
void Profile(FoldingSetNodeID& ID) const {
@@ -190,7 +190,7 @@ public:
}
ImmutableList<T> getEmptyList() const {
- return ImmutableList<T>(0);
+ return ImmutableList<T>(nullptr);
}
ImmutableList<T> create(const T& X) {
@@ -226,4 +226,4 @@ struct isPodLike<ImmutableList<T> > { static const bool value = true; };
} // end llvm namespace
-#endif
+#endif // LLVM_ADT_IMMUTABLELIST_H
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index 438dec2333c5..7480cd73da61 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -55,7 +55,6 @@ struct ImutKeyValueInfo {
}
};
-
template <typename KeyT, typename ValT,
typename ValInfo = ImutKeyValueInfo<KeyT,ValT> >
class ImmutableMap {
@@ -79,9 +78,11 @@ public:
explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {
if (Root) { Root->retain(); }
}
+
ImmutableMap(const ImmutableMap &X) : Root(X.Root) {
if (Root) { Root->retain(); }
}
+
ImmutableMap &operator=(const ImmutableMap &X) {
if (Root != X.Root) {
if (X.Root) { X.Root->retain(); }
@@ -90,6 +91,7 @@ public:
}
return *this;
}
+
~ImmutableMap() {
if (Root) { Root->release(); }
}
@@ -99,11 +101,10 @@ public:
const bool Canonicalize;
public:
- Factory(bool canonicalize = true)
- : Canonicalize(canonicalize) {}
-
- Factory(BumpPtrAllocator& Alloc, bool canonicalize = true)
- : F(Alloc), Canonicalize(canonicalize) {}
+ Factory(bool canonicalize = true) : Canonicalize(canonicalize) {}
+
+ Factory(BumpPtrAllocator &Alloc, bool canonicalize = true)
+ : F(Alloc), Canonicalize(canonicalize) {}
ImmutableMap getEmptyMap() { return ImmutableMap(F.getEmptyTree()); }
@@ -143,14 +144,12 @@ public:
return Root;
}
- TreeTy *getRootWithoutRetain() const {
- return Root;
- }
-
+ TreeTy *getRootWithoutRetain() const { return Root; }
+
void manualRetain() {
if (Root) Root->retain();
}
-
+
void manualRelease() {
if (Root) Root->release();
}
@@ -224,7 +223,7 @@ public:
return nullptr;
}
-
+
/// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
/// which key is the highest in the ordering of keys in the map. This
/// method returns NULL if the map is empty.
@@ -260,20 +259,21 @@ public:
typedef typename ValInfo::data_type_ref data_type_ref;
typedef ImutAVLTree<ValInfo> TreeTy;
typedef typename TreeTy::Factory FactoryTy;
-
+
protected:
TreeTy *Root;
FactoryTy *Factory;
-
+
public:
/// Constructs a map from a pointer to a tree root. In general one
/// should use a Factory object to create maps instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableMapRef(const TreeTy* R, FactoryTy *F)
- : Root(const_cast<TreeTy*>(R)),
- Factory(F) {
- if (Root) { Root->retain(); }
+ explicit ImmutableMapRef(const TreeTy *R, FactoryTy *F)
+ : Root(const_cast<TreeTy *>(R)), Factory(F) {
+ if (Root) {
+ Root->retain();
+ }
}
explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X,
@@ -282,21 +282,21 @@ public:
Factory(F.getTreeFactory()) {
if (Root) { Root->retain(); }
}
-
- ImmutableMapRef(const ImmutableMapRef &X)
- : Root(X.Root),
- Factory(X.Factory) {
- if (Root) { Root->retain(); }
+
+ ImmutableMapRef(const ImmutableMapRef &X) : Root(X.Root), Factory(X.Factory) {
+ if (Root) {
+ Root->retain();
+ }
}
ImmutableMapRef &operator=(const ImmutableMapRef &X) {
if (Root != X.Root) {
if (X.Root)
X.Root->retain();
-
+
if (Root)
Root->release();
-
+
Root = X.Root;
Factory = X.Factory;
}
@@ -307,7 +307,7 @@ public:
if (Root)
Root->release();
}
-
+
static inline ImmutableMapRef getEmptyMap(FactoryTy *F) {
return ImmutableMapRef(0, F);
}
@@ -329,31 +329,34 @@ public:
TreeTy *NewT = Factory->remove(Root, K);
return ImmutableMapRef(NewT, Factory);
}
-
+
bool contains(key_type_ref K) const {
return Root ? Root->contains(K) : false;
}
-
+
ImmutableMap<KeyT, ValT> asImmutableMap() const {
return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root));
}
-
+
bool operator==(const ImmutableMapRef &RHS) const {
return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
}
-
+
bool operator!=(const ImmutableMapRef &RHS) const {
return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
}
-
+
bool isEmpty() const { return !Root; }
-
+
//===--------------------------------------------------===//
// For testing.
//===--------------------------------------------------===//
-
- void verify() const { if (Root) Root->verify(); }
-
+
+ void verify() const {
+ if (Root)
+ Root->verify();
+ }
+
//===--------------------------------------------------===//
// Iterators.
//===--------------------------------------------------===//
@@ -370,38 +373,36 @@ public:
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
-
- data_type* lookup(key_type_ref K) const {
+
+ data_type *lookup(key_type_ref K) const {
if (Root) {
TreeTy* T = Root->find(K);
if (T) return &T->getValue().second;
}
-
- return 0;
+
+ return nullptr;
}
-
+
/// getMaxElement - Returns the <key,value> pair in the ImmutableMap for
/// which key is the highest in the ordering of keys in the map. This
/// method returns NULL if the map is empty.
value_type* getMaxElement() const {
return Root ? &(Root->getMaxElement()->getValue()) : 0;
}
-
+
//===--------------------------------------------------===//
// Utility methods.
//===--------------------------------------------------===//
-
+
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
-
- static inline void Profile(FoldingSetNodeID& ID, const ImmutableMapRef &M) {
+
+ static inline void Profile(FoldingSetNodeID &ID, const ImmutableMapRef &M) {
ID.AddPointer(M.Root);
}
-
- inline void Profile(FoldingSetNodeID& ID) const {
- return Profile(ID, *this);
- }
+
+ inline void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
};
-
+
} // end namespace llvm
-#endif
+#endif // LLVM_ADT_IMMUTABLEMAP_H
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index 65b2da793d7c..8057ec10be00 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -154,7 +154,7 @@ public:
template <class X>
IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.get()) {
- S.Obj = 0;
+ S.Obj = nullptr;
}
template <class X>
@@ -190,7 +190,7 @@ public:
}
void resetWithoutRelease() {
- Obj = 0;
+ Obj = nullptr;
}
private:
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index 855ab890392e..d9acaf6d23b0 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -159,6 +159,25 @@ template <typename T> struct isPodLike<Optional<T> > {
template<typename T, typename U>
void operator==(const Optional<T> &X, const Optional<U> &Y);
+template<typename T>
+bool operator==(const Optional<T> &X, NoneType) {
+ return !X.hasValue();
+}
+
+template<typename T>
+bool operator==(NoneType, const Optional<T> &X) {
+ return X == None;
+}
+
+template<typename T>
+bool operator!=(const Optional<T> &X, NoneType) {
+ return !(X == None);
+}
+
+template<typename T>
+bool operator!=(NoneType, const Optional<T> &X) {
+ return X != None;
+}
/// \brief Poison comparison between two \c Optional objects. Clients needs to
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h
index 1ae2a77e7eaf..09267173fd77 100644
--- a/include/llvm/ADT/PackedVector.h
+++ b/include/llvm/ADT/PackedVector.h
@@ -83,9 +83,9 @@ public:
PackedVector &Vec;
const unsigned Idx;
- reference(); // Undefined
+ reference(); // Undefined
public:
- reference(PackedVector &vec, unsigned idx) : Vec(vec), Idx(idx) { }
+ reference(PackedVector &vec, unsigned idx) : Vec(vec), Idx(idx) {}
reference &operator=(T val) {
Vec.setValue(Vec.Bits, Idx, val);
@@ -96,16 +96,16 @@ public:
}
};
- PackedVector() { }
+ PackedVector() = default;
explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) { }
bool empty() const { return Bits.empty(); }
- unsigned size() const { return Bits.size() >> (BitNum-1); }
-
+ unsigned size() const { return Bits.size() >> (BitNum - 1); }
+
void clear() { Bits.clear(); }
-
- void resize(unsigned N) { Bits.resize(N << (BitNum-1)); }
+
+ void resize(unsigned N) { Bits.resize(N << (BitNum - 1)); }
void reserve(unsigned N) { Bits.reserve(N << (BitNum-1)); }
@@ -135,24 +135,14 @@ public:
return Bits != RHS.Bits;
}
- const PackedVector &operator=(const PackedVector &RHS) {
- Bits = RHS.Bits;
- return *this;
- }
-
PackedVector &operator|=(const PackedVector &RHS) {
Bits |= RHS.Bits;
return *this;
}
-
- void swap(PackedVector &RHS) {
- Bits.swap(RHS.Bits);
- }
};
-// Leave BitNum=0 undefined.
-template <typename T>
-class PackedVector<T, 0>;
+// Leave BitNum=0 undefined.
+template <typename T> class PackedVector<T, 0>;
} // end llvm namespace
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
index 45a40db85c04..0058d85d1ae4 100644
--- a/include/llvm/ADT/PointerIntPair.h
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -21,8 +21,10 @@
namespace llvm {
-template<typename T>
-struct DenseMapInfo;
+template <typename T> struct DenseMapInfo;
+
+template <typename PointerT, unsigned IntBits, typename PtrTraits>
+struct PointerIntPairInfo;
/// PointerIntPair - This class implements a pair of a pointer and small
/// integer. It is designed to represent this in the space required by one
@@ -38,83 +40,35 @@ struct DenseMapInfo;
/// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
/// ... and the two bools will land in different bits.
///
-template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
- typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
+template <typename PointerTy, unsigned IntBits, typename IntType = unsigned,
+ typename PtrTraits = PointerLikeTypeTraits<PointerTy>,
+ typename Info = PointerIntPairInfo<PointerTy, IntBits, PtrTraits>>
class PointerIntPair {
intptr_t Value;
- static_assert(PtrTraits::NumLowBitsAvailable <
- std::numeric_limits<uintptr_t>::digits,
- "cannot use a pointer type that has all bits free");
- static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
- "PointerIntPair with integer size too large for pointer");
- enum : uintptr_t {
- /// PointerBitMask - The bits that come from the pointer.
- PointerBitMask =
- ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
- /// IntShift - The number of low bits that we reserve for other uses, and
- /// keep zero.
- IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
-
- /// IntMask - This is the unshifted mask for valid bits of the int type.
- IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
-
- // ShiftedIntMask - This is the bits for the integer shifted in place.
- ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
- };
public:
PointerIntPair() : Value(0) {}
PointerIntPair(PointerTy PtrVal, IntType IntVal) {
setPointerAndInt(PtrVal, IntVal);
}
- explicit PointerIntPair(PointerTy PtrVal) {
- initWithPointer(PtrVal);
- }
+ explicit PointerIntPair(PointerTy PtrVal) { initWithPointer(PtrVal); }
- PointerTy getPointer() const {
- return PtrTraits::getFromVoidPointer(
- reinterpret_cast<void*>(Value & PointerBitMask));
- }
+ PointerTy getPointer() const { return Info::getPointer(Value); }
- IntType getInt() const {
- return (IntType)((Value >> IntShift) & IntMask);
- }
+ IntType getInt() const { return (IntType)Info::getInt(Value); }
void setPointer(PointerTy PtrVal) {
- intptr_t PtrWord
- = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ~PointerBitMask) == 0 &&
- "Pointer is not sufficiently aligned");
- // Preserve all low bits, just update the pointer.
- Value = PtrWord | (Value & ~PointerBitMask);
+ Value = Info::updatePointer(Value, PtrVal);
}
- void setInt(IntType IntVal) {
- intptr_t IntWord = static_cast<intptr_t>(IntVal);
- assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
-
- // Preserve all bits other than the ones we are updating.
- Value &= ~ShiftedIntMask; // Remove integer field.
- Value |= IntWord << IntShift; // Set new integer.
- }
+ void setInt(IntType IntVal) { Value = Info::updateInt(Value, IntVal); }
void initWithPointer(PointerTy PtrVal) {
- intptr_t PtrWord
- = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ~PointerBitMask) == 0 &&
- "Pointer is not sufficiently aligned");
- Value = PtrWord;
+ Value = Info::updatePointer(0, PtrVal);
}
void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
- intptr_t PtrWord
- = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ~PointerBitMask) == 0 &&
- "Pointer is not sufficiently aligned");
- intptr_t IntWord = static_cast<intptr_t>(IntVal);
- assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
-
- Value = PtrWord | (IntWord << IntShift);
+ Value = Info::updateInt(Info::updatePointer(0, PtrVal), IntVal);
}
PointerTy const *getAddrOfPointer() const {
@@ -128,11 +82,15 @@ public:
return reinterpret_cast<PointerTy *>(&Value);
}
- void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
- void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
+ void *getOpaqueValue() const { return reinterpret_cast<void *>(Value); }
+ void setFromOpaqueValue(void *Val) {
+ Value = reinterpret_cast<intptr_t>(Val);
+ }
static PointerIntPair getFromOpaqueValue(void *V) {
- PointerIntPair P; P.setFromOpaqueValue(V); return P;
+ PointerIntPair P;
+ P.setFromOpaqueValue(V);
+ return P;
}
// Allow PointerIntPairs to be created from const void * if and only if the
@@ -142,23 +100,81 @@ public:
return getFromOpaqueValue(const_cast<void *>(V));
}
- bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
- bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
- bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
- bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
- bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
- bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
+ bool operator==(const PointerIntPair &RHS) const {
+ return Value == RHS.Value;
+ }
+ bool operator!=(const PointerIntPair &RHS) const {
+ return Value != RHS.Value;
+ }
+ bool operator<(const PointerIntPair &RHS) const { return Value < RHS.Value; }
+ bool operator>(const PointerIntPair &RHS) const { return Value > RHS.Value; }
+ bool operator<=(const PointerIntPair &RHS) const {
+ return Value <= RHS.Value;
+ }
+ bool operator>=(const PointerIntPair &RHS) const {
+ return Value >= RHS.Value;
+ }
+};
+
+template <typename PointerT, unsigned IntBits, typename PtrTraits>
+struct PointerIntPairInfo {
+ static_assert(PtrTraits::NumLowBitsAvailable <
+ std::numeric_limits<uintptr_t>::digits,
+ "cannot use a pointer type that has all bits free");
+ static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
+ "PointerIntPair with integer size too large for pointer");
+ enum : uintptr_t {
+ /// PointerBitMask - The bits that come from the pointer.
+ PointerBitMask =
+ ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1),
+
+ /// IntShift - The number of low bits that we reserve for other uses, and
+ /// keep zero.
+ IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits,
+
+ /// IntMask - This is the unshifted mask for valid bits of the int type.
+ IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1),
+
+ // ShiftedIntMask - This is the bits for the integer shifted in place.
+ ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
+ };
+
+ static PointerT getPointer(intptr_t Value) {
+ return PtrTraits::getFromVoidPointer(
+ reinterpret_cast<void *>(Value & PointerBitMask));
+ }
+
+ static intptr_t getInt(intptr_t Value) {
+ return (Value >> IntShift) & IntMask;
+ }
+
+ static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr) {
+ intptr_t PtrWord =
+ reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
+ assert((PtrWord & ~PointerBitMask) == 0 &&
+ "Pointer is not sufficiently aligned");
+ // Preserve all low bits, just update the pointer.
+ return PtrWord | (OrigValue & ~PointerBitMask);
+ }
+
+ static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) {
+ intptr_t IntWord = static_cast<intptr_t>(Int);
+ assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
+
+ // Preserve all bits other than the ones we are updating.
+ return (OrigValue & ~ShiftedIntMask) | IntWord << IntShift;
+ }
};
template <typename T> struct isPodLike;
-template<typename PointerTy, unsigned IntBits, typename IntType>
-struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
- static const bool value = true;
+template <typename PointerTy, unsigned IntBits, typename IntType>
+struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType>> {
+ static const bool value = true;
};
-
+
// Provide specialization of DenseMapInfo for PointerIntPair.
-template<typename PointerTy, unsigned IntBits, typename IntType>
-struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
+template <typename PointerTy, unsigned IntBits, typename IntType>
+struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>> {
typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
static Ty getEmptyKey() {
uintptr_t Val = static_cast<uintptr_t>(-1);
@@ -178,10 +194,10 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
};
// Teach SmallPtrSet that PointerIntPair is "basically a pointer".
-template<typename PointerTy, unsigned IntBits, typename IntType,
- typename PtrTraits>
-class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
- PtrTraits> > {
+template <typename PointerTy, unsigned IntBits, typename IntType,
+ typename PtrTraits>
+class PointerLikeTypeTraits<
+ PointerIntPair<PointerTy, IntBits, IntType, PtrTraits>> {
public:
static inline void *
getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
@@ -195,9 +211,7 @@ public:
getFromVoidPointer(const void *P) {
return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
}
- enum {
- NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits
- };
+ enum { NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits };
};
} // end namespace llvm
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
index f27b81113ec5..6b3fe5749ad5 100644
--- a/include/llvm/ADT/PointerUnion.h
+++ b/include/llvm/ADT/PointerUnion.h
@@ -21,492 +21,454 @@
namespace llvm {
- template <typename T>
- struct PointerUnionTypeSelectorReturn {
- typedef T Return;
- };
+template <typename T> struct PointerUnionTypeSelectorReturn {
+ typedef T Return;
+};
- /// \brief Get a type based on whether two types are the same or not. For:
- /// @code
- /// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret;
- /// @endcode
- /// Ret will be EQ type if T1 is same as T2 or NE type otherwise.
- template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
- struct PointerUnionTypeSelector {
- typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return;
- };
+/// Get a type based on whether two types are the same or not.
+///
+/// For:
+///
+/// \code
+/// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret;
+/// \endcode
+///
+/// Ret will be EQ type if T1 is same as T2 or NE type otherwise.
+template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
+struct PointerUnionTypeSelector {
+ typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return;
+};
- template <typename T, typename RET_EQ, typename RET_NE>
- struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> {
- typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return;
- };
+template <typename T, typename RET_EQ, typename RET_NE>
+struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> {
+ typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return;
+};
- template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
- struct PointerUnionTypeSelectorReturn<
- PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE> > {
- typedef typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return
- Return;
- };
+template <typename T1, typename T2, typename RET_EQ, typename RET_NE>
+struct PointerUnionTypeSelectorReturn<
+ PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>> {
+ typedef
+ typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return Return;
+};
- /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
- /// for the two template arguments.
- template <typename PT1, typename PT2>
- class PointerUnionUIntTraits {
- public:
- static inline void *getAsVoidPointer(void *P) { return P; }
- static inline void *getFromVoidPointer(void *P) { return P; }
- enum {
- PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable),
- PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable),
- NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
- };
+/// Provide PointerLikeTypeTraits for void* that is used by PointerUnion
+/// for the two template arguments.
+template <typename PT1, typename PT2> class PointerUnionUIntTraits {
+public:
+ static inline void *getAsVoidPointer(void *P) { return P; }
+ static inline void *getFromVoidPointer(void *P) { return P; }
+ enum {
+ PT1BitsAv = (int)(PointerLikeTypeTraits<PT1>::NumLowBitsAvailable),
+ PT2BitsAv = (int)(PointerLikeTypeTraits<PT2>::NumLowBitsAvailable),
+ NumLowBitsAvailable = PT1BitsAv < PT2BitsAv ? PT1BitsAv : PT2BitsAv
};
+};
- /// PointerUnion - This implements a discriminated union of two pointer types,
- /// and keeps the discriminator bit-mangled into the low bits of the pointer.
- /// This allows the implementation to be extremely efficient in space, but
- /// permits a very natural and type-safe API.
- ///
- /// Common use patterns would be something like this:
- /// PointerUnion<int*, float*> P;
- /// P = (int*)0;
- /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0"
- /// X = P.get<int*>(); // ok.
- /// Y = P.get<float*>(); // runtime assertion failure.
- /// Z = P.get<double*>(); // compile time failure.
- /// P = (float*)0;
- /// Y = P.get<float*>(); // ok.
- /// X = P.get<int*>(); // runtime assertion failure.
- template <typename PT1, typename PT2>
- class PointerUnion {
- public:
- typedef PointerIntPair<void*, 1, bool,
- PointerUnionUIntTraits<PT1,PT2> > ValTy;
- private:
- ValTy Val;
+/// A discriminated union of two pointer types, with the discriminator in the
+/// low bit of the pointer.
+///
+/// This implementation is extremely efficient in space due to leveraging the
+/// low bits of the pointer, while exposing a natural and type-safe API.
+///
+/// Common use patterns would be something like this:
+/// PointerUnion<int*, float*> P;
+/// P = (int*)0;
+/// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0"
+/// X = P.get<int*>(); // ok.
+/// Y = P.get<float*>(); // runtime assertion failure.
+/// Z = P.get<double*>(); // compile time failure.
+/// P = (float*)0;
+/// Y = P.get<float*>(); // ok.
+/// X = P.get<int*>(); // runtime assertion failure.
+template <typename PT1, typename PT2> class PointerUnion {
+public:
+ typedef PointerIntPair<void *, 1, bool, PointerUnionUIntTraits<PT1, PT2>>
+ ValTy;
- struct IsPT1 {
- static const int Num = 0;
- };
- struct IsPT2 {
- static const int Num = 1;
- };
- template <typename T>
- struct UNION_DOESNT_CONTAIN_TYPE { };
+private:
+ ValTy Val;
- public:
- PointerUnion() {}
+ struct IsPT1 {
+ static const int Num = 0;
+ };
+ struct IsPT2 {
+ static const int Num = 1;
+ };
+ template <typename T> struct UNION_DOESNT_CONTAIN_TYPE {};
- PointerUnion(PT1 V) : Val(
- const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {
- }
- PointerUnion(PT2 V) : Val(
- const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)), 1) {
- }
+public:
+ PointerUnion() {}
- /// isNull - Return true 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<PT1>::getFromVoidPointer(Val.getPointer());
- }
- explicit operator bool() const { return !isNull(); }
+ PointerUnion(PT1 V)
+ : Val(const_cast<void *>(
+ PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {}
+ PointerUnion(PT2 V)
+ : Val(const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(V)),
+ 1) {}
- /// is<T>() return true if the Union currently holds the type matching T.
- template<typename T>
- int is() const {
- typedef typename
- ::llvm::PointerUnionTypeSelector<PT1, T, IsPT1,
- ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2,
- UNION_DOESNT_CONTAIN_TYPE<T> > >::Return Ty;
- int TyNo = Ty::Num;
- return static_cast<int>(Val.getInt()) == TyNo;
- }
+ /// 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<PT1>::getFromVoidPointer(Val.getPointer());
+ }
+ explicit operator bool() const { return !isNull(); }
- /// get<T>() - Return the value of the specified pointer type. If the
- /// specified pointer type is incorrect, assert.
- template<typename T>
- T get() const {
- assert(is<T>() && "Invalid accessor called");
- return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
- }
+ /// Test if the Union currently holds the type matching T.
+ template <typename T> int is() const {
+ typedef typename ::llvm::PointerUnionTypeSelector<
+ PT1, T, IsPT1, ::llvm::PointerUnionTypeSelector<
+ PT2, T, IsPT2, UNION_DOESNT_CONTAIN_TYPE<T>>>::Return
+ Ty;
+ int TyNo = Ty::Num;
+ return static_cast<int>(Val.getInt()) == TyNo;
+ }
- /// dyn_cast<T>() - If the current value is of the specified pointer type,
- /// return it, otherwise return null.
- template<typename T>
- T dyn_cast() const {
- if (is<T>()) return get<T>();
- return T();
- }
+ /// Returns the value of the specified pointer type.
+ ///
+ /// If the specified pointer type is incorrect, assert.
+ template <typename T> T get() const {
+ assert(is<T>() && "Invalid accessor called");
+ return PointerLikeTypeTraits<T>::getFromVoidPointer(Val.getPointer());
+ }
- /// \brief If the union is set to the first pointer type get an address
- /// pointing to it.
- PT1 const *getAddrOfPtr1() const {
- return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
- }
+ /// Returns the current pointer if it is of the specified pointer type,
+ /// otherwises returns null.
+ template <typename T> T dyn_cast() const {
+ if (is<T>())
+ return get<T>();
+ return T();
+ }
- /// \brief If the union is set to the first pointer type get an address
- /// pointing to it.
- PT1 *getAddrOfPtr1() {
- assert(is<PT1>() && "Val is not the first pointer");
- assert(get<PT1>() == Val.getPointer() &&
- "Can't get the address because PointerLikeTypeTraits changes the ptr");
- return (PT1 *)Val.getAddrOfPointer();
- }
+ /// If the union is set to the first pointer type get an address pointing to
+ /// it.
+ PT1 const *getAddrOfPtr1() const {
+ return const_cast<PointerUnion *>(this)->getAddrOfPtr1();
+ }
- /// \brief Assignment from nullptr which just clears the union.
- const PointerUnion &operator=(std::nullptr_t) {
- Val.initWithPointer(nullptr);
- return *this;
- }
+ /// If the union is set to the first pointer type get an address pointing to
+ /// it.
+ PT1 *getAddrOfPtr1() {
+ assert(is<PT1>() && "Val is not the first pointer");
+ assert(
+ get<PT1>() == Val.getPointer() &&
+ "Can't get the address because PointerLikeTypeTraits changes the ptr");
+ return (PT1 *)Val.getAddrOfPointer();
+ }
- /// Assignment operators - Allow assigning into this union from either
- /// pointer type, setting the discriminator to remember what it came from.
- const PointerUnion &operator=(const PT1 &RHS) {
- Val.initWithPointer(
- const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
- return *this;
- }
- const PointerUnion &operator=(const PT2 &RHS) {
- Val.setPointerAndInt(
+ /// Assignment from nullptr which just clears the union.
+ const PointerUnion &operator=(std::nullptr_t) {
+ Val.initWithPointer(nullptr);
+ return *this;
+ }
+
+ /// Assignment operators - Allow assigning into this union from either
+ /// pointer type, setting the discriminator to remember what it came from.
+ const PointerUnion &operator=(const PT1 &RHS) {
+ Val.initWithPointer(
+ const_cast<void *>(PointerLikeTypeTraits<PT1>::getAsVoidPointer(RHS)));
+ return *this;
+ }
+ const PointerUnion &operator=(const PT2 &RHS) {
+ Val.setPointerAndInt(
const_cast<void *>(PointerLikeTypeTraits<PT2>::getAsVoidPointer(RHS)),
1);
- return *this;
- }
-
- void *getOpaqueValue() const { return Val.getOpaqueValue(); }
- static inline PointerUnion getFromOpaqueValue(void *VP) {
- PointerUnion V;
- V.Val = ValTy::getFromOpaqueValue(VP);
- return V;
- }
- };
-
- template<typename PT1, typename PT2>
- static bool operator==(PointerUnion<PT1, PT2> lhs,
- PointerUnion<PT1, PT2> rhs) {
- return lhs.getOpaqueValue() == rhs.getOpaqueValue();
+ return *this;
}
- template<typename PT1, typename PT2>
- static bool operator!=(PointerUnion<PT1, PT2> lhs,
- PointerUnion<PT1, PT2> rhs) {
- return lhs.getOpaqueValue() != rhs.getOpaqueValue();
+ void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ static inline PointerUnion getFromOpaqueValue(void *VP) {
+ PointerUnion V;
+ V.Val = ValTy::getFromOpaqueValue(VP);
+ return V;
}
+};
+
+template <typename PT1, typename PT2>
+static bool operator==(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+ return lhs.getOpaqueValue() == rhs.getOpaqueValue();
+}
- template<typename PT1, typename PT2>
- static bool operator<(PointerUnion<PT1, PT2> lhs,
- PointerUnion<PT1, PT2> rhs) {
- return lhs.getOpaqueValue() < rhs.getOpaqueValue();
+template <typename PT1, typename PT2>
+static bool operator!=(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+ return lhs.getOpaqueValue() != rhs.getOpaqueValue();
+}
+
+template <typename PT1, typename PT2>
+static bool operator<(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) {
+ return lhs.getOpaqueValue() < rhs.getOpaqueValue();
+}
+
+// Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
+// # low bits available = min(PT1bits,PT2bits)-1.
+template <typename PT1, typename PT2>
+class PointerLikeTypeTraits<PointerUnion<PT1, PT2>> {
+public:
+ static inline void *getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
+ return P.getOpaqueValue();
}
+ static inline PointerUnion<PT1, PT2> getFromVoidPointer(void *P) {
+ return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
+ }
+
+ // The number of bits available are the min of the two pointer types.
+ enum {
+ NumLowBitsAvailable = PointerLikeTypeTraits<
+ typename PointerUnion<PT1, PT2>::ValTy>::NumLowBitsAvailable
+ };
+};
- // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has
- // # low bits available = min(PT1bits,PT2bits)-1.
- template<typename PT1, typename PT2>
- class PointerLikeTypeTraits<PointerUnion<PT1, PT2> > {
- public:
- static inline void *
- getAsVoidPointer(const PointerUnion<PT1, PT2> &P) {
- return P.getOpaqueValue();
+/// A pointer union of three pointer types. See documentation for PointerUnion
+/// for usage.
+template <typename PT1, typename PT2, typename PT3> class PointerUnion3 {
+public:
+ typedef PointerUnion<PT1, PT2> InnerUnion;
+ typedef PointerUnion<InnerUnion, PT3> ValTy;
+
+private:
+ ValTy Val;
+
+ struct IsInnerUnion {
+ ValTy Val;
+ IsInnerUnion(ValTy val) : Val(val) {}
+ template <typename T> int is() const {
+ return Val.template is<InnerUnion>() &&
+ Val.template get<InnerUnion>().template is<T>();
}
- static inline PointerUnion<PT1, PT2>
- getFromVoidPointer(void *P) {
- return PointerUnion<PT1, PT2>::getFromOpaqueValue(P);
+ template <typename T> T get() const {
+ return Val.template get<InnerUnion>().template get<T>();
}
-
- // The number of bits available are the min of the two pointer types.
- enum {
- NumLowBitsAvailable =
- PointerLikeTypeTraits<typename PointerUnion<PT1,PT2>::ValTy>
- ::NumLowBitsAvailable
- };
};
-
- /// PointerUnion3 - This is a pointer union of three pointer types. See
- /// documentation for PointerUnion for usage.
- template <typename PT1, typename PT2, typename PT3>
- class PointerUnion3 {
- public:
- typedef PointerUnion<PT1, PT2> InnerUnion;
- typedef PointerUnion<InnerUnion, PT3> ValTy;
- private:
+ struct IsPT3 {
ValTy Val;
+ IsPT3(ValTy val) : Val(val) {}
+ template <typename T> int is() const { return Val.template is<T>(); }
+ template <typename T> T get() const { return Val.template get<T>(); }
+ };
- struct IsInnerUnion {
- ValTy Val;
- IsInnerUnion(ValTy val) : Val(val) { }
- template<typename T>
- int is() const {
- return Val.template is<InnerUnion>() &&
- Val.template get<InnerUnion>().template is<T>();
- }
- template<typename T>
- T get() const {
- return Val.template get<InnerUnion>().template get<T>();
- }
- };
+public:
+ PointerUnion3() {}
- struct IsPT3 {
- ValTy Val;
- IsPT3(ValTy val) : Val(val) { }
- template<typename T>
- int is() const {
- return Val.template is<T>();
- }
- template<typename T>
- T get() const {
- return Val.template get<T>();
- }
- };
+ PointerUnion3(PT1 V) { Val = InnerUnion(V); }
+ PointerUnion3(PT2 V) { Val = InnerUnion(V); }
+ PointerUnion3(PT3 V) { Val = V; }
- public:
- PointerUnion3() {}
+ /// Test if the pointer held in the union is null, regardless of
+ /// which type it is.
+ bool isNull() const { return Val.isNull(); }
+ explicit operator bool() const { return !isNull(); }
- PointerUnion3(PT1 V) {
- Val = InnerUnion(V);
- }
- PointerUnion3(PT2 V) {
- Val = InnerUnion(V);
- }
- PointerUnion3(PT3 V) {
- Val = V;
- }
+ /// Test if the Union currently holds the type matching T.
+ template <typename T> int is() const {
+ // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
+ typedef typename ::llvm::PointerUnionTypeSelector<
+ PT1, T, IsInnerUnion,
+ ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return
+ Ty;
+ return Ty(Val).template is<T>();
+ }
- /// isNull - Return true if the pointer held in the union is null,
- /// regardless of which type it is.
- bool isNull() const { return Val.isNull(); }
- explicit operator bool() const { return !isNull(); }
+ /// Returns the value of the specified pointer type.
+ ///
+ /// If the specified pointer type is incorrect, assert.
+ template <typename T> T get() const {
+ assert(is<T>() && "Invalid accessor called");
+ // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
+ typedef typename ::llvm::PointerUnionTypeSelector<
+ PT1, T, IsInnerUnion,
+ ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return
+ Ty;
+ return Ty(Val).template get<T>();
+ }
- /// is<T>() return true if the Union currently holds the type matching T.
- template<typename T>
- int is() const {
- // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
- typedef typename
- ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
- ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
- >::Return Ty;
- return Ty(Val).template is<T>();
- }
+ /// Returns the current pointer if it is of the specified pointer type,
+ /// otherwises returns null.
+ template <typename T> T dyn_cast() const {
+ if (is<T>())
+ return get<T>();
+ return T();
+ }
- /// get<T>() - Return the value of the specified pointer type. If the
- /// specified pointer type is incorrect, assert.
- template<typename T>
- T get() const {
- assert(is<T>() && "Invalid accessor called");
- // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3.
- typedef typename
- ::llvm::PointerUnionTypeSelector<PT1, T, IsInnerUnion,
- ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3 >
- >::Return Ty;
- return Ty(Val).template get<T>();
- }
+ /// Assignment from nullptr which just clears the union.
+ const PointerUnion3 &operator=(std::nullptr_t) {
+ Val = nullptr;
+ return *this;
+ }
- /// dyn_cast<T>() - If the current value is of the specified pointer type,
- /// return it, otherwise return null.
- template<typename T>
- T dyn_cast() const {
- if (is<T>()) return get<T>();
- return T();
- }
+ /// Assignment operators - Allow assigning into this union from either
+ /// pointer type, setting the discriminator to remember what it came from.
+ const PointerUnion3 &operator=(const PT1 &RHS) {
+ Val = InnerUnion(RHS);
+ return *this;
+ }
+ const PointerUnion3 &operator=(const PT2 &RHS) {
+ Val = InnerUnion(RHS);
+ return *this;
+ }
+ const PointerUnion3 &operator=(const PT3 &RHS) {
+ Val = RHS;
+ return *this;
+ }
- /// \brief Assignment from nullptr which just clears the union.
- const PointerUnion3 &operator=(std::nullptr_t) {
- Val = nullptr;
- return *this;
- }
+ void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ static inline PointerUnion3 getFromOpaqueValue(void *VP) {
+ PointerUnion3 V;
+ V.Val = ValTy::getFromOpaqueValue(VP);
+ return V;
+ }
+};
- /// Assignment operators - Allow assigning into this union from either
- /// pointer type, setting the discriminator to remember what it came from.
- const PointerUnion3 &operator=(const PT1 &RHS) {
- Val = InnerUnion(RHS);
- return *this;
- }
- const PointerUnion3 &operator=(const PT2 &RHS) {
- Val = InnerUnion(RHS);
- return *this;
- }
- const PointerUnion3 &operator=(const PT3 &RHS) {
- Val = RHS;
- return *this;
- }
+// Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
+// # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
+template <typename PT1, typename PT2, typename PT3>
+class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3>> {
+public:
+ static inline void *getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerUnion3<PT1, PT2, PT3> getFromVoidPointer(void *P) {
+ return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
+ }
- void *getOpaqueValue() const { return Val.getOpaqueValue(); }
- static inline PointerUnion3 getFromOpaqueValue(void *VP) {
- PointerUnion3 V;
- V.Val = ValTy::getFromOpaqueValue(VP);
- return V;
- }
+ // The number of bits available are the min of the two pointer types.
+ enum {
+ NumLowBitsAvailable = PointerLikeTypeTraits<
+ typename PointerUnion3<PT1, PT2, PT3>::ValTy>::NumLowBitsAvailable
};
+};
- // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has
- // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
- template<typename PT1, typename PT2, typename PT3>
- class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3> > {
- public:
- static inline void *
- getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) {
- return P.getOpaqueValue();
- }
- static inline PointerUnion3<PT1, PT2, PT3>
- getFromVoidPointer(void *P) {
- return PointerUnion3<PT1, PT2, PT3>::getFromOpaqueValue(P);
- }
+/// A pointer union of four pointer types. See documentation for PointerUnion
+/// for usage.
+template <typename PT1, typename PT2, typename PT3, typename PT4>
+class PointerUnion4 {
+public:
+ typedef PointerUnion<PT1, PT2> InnerUnion1;
+ typedef PointerUnion<PT3, PT4> InnerUnion2;
+ typedef PointerUnion<InnerUnion1, InnerUnion2> ValTy;
- // The number of bits available are the min of the two pointer types.
- enum {
- NumLowBitsAvailable =
- PointerLikeTypeTraits<typename PointerUnion3<PT1, PT2, PT3>::ValTy>
- ::NumLowBitsAvailable
- };
- };
+private:
+ ValTy Val;
- /// PointerUnion4 - This is a pointer union of four pointer types. See
- /// documentation for PointerUnion for usage.
- template <typename PT1, typename PT2, typename PT3, typename PT4>
- class PointerUnion4 {
- public:
- typedef PointerUnion<PT1, PT2> InnerUnion1;
- typedef PointerUnion<PT3, PT4> InnerUnion2;
- typedef PointerUnion<InnerUnion1, InnerUnion2> ValTy;
- private:
- ValTy Val;
- public:
- PointerUnion4() {}
+public:
+ PointerUnion4() {}
- PointerUnion4(PT1 V) {
- Val = InnerUnion1(V);
- }
- PointerUnion4(PT2 V) {
- Val = InnerUnion1(V);
- }
- PointerUnion4(PT3 V) {
- Val = InnerUnion2(V);
- }
- PointerUnion4(PT4 V) {
- Val = InnerUnion2(V);
- }
+ PointerUnion4(PT1 V) { Val = InnerUnion1(V); }
+ PointerUnion4(PT2 V) { Val = InnerUnion1(V); }
+ PointerUnion4(PT3 V) { Val = InnerUnion2(V); }
+ PointerUnion4(PT4 V) { Val = InnerUnion2(V); }
- /// isNull - Return true if the pointer held in the union is null,
- /// regardless of which type it is.
- bool isNull() const { return Val.isNull(); }
- explicit operator bool() const { return !isNull(); }
+ /// Test if the pointer held in the union is null, regardless of
+ /// which type it is.
+ bool isNull() const { return Val.isNull(); }
+ explicit operator bool() const { return !isNull(); }
- /// is<T>() return true if the Union currently holds the type matching T.
- template<typename T>
- int is() const {
- // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
- typedef typename
- ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
- ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
- >::Return Ty;
- return Val.template is<Ty>() &&
- Val.template get<Ty>().template is<T>();
- }
+ /// Test if the Union currently holds the type matching T.
+ template <typename T> int is() const {
+ // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
+ typedef typename ::llvm::PointerUnionTypeSelector<
+ PT1, T, InnerUnion1, ::llvm::PointerUnionTypeSelector<
+ PT2, T, InnerUnion1, InnerUnion2>>::Return Ty;
+ return Val.template is<Ty>() && Val.template get<Ty>().template is<T>();
+ }
- /// get<T>() - Return the value of the specified pointer type. If the
- /// specified pointer type is incorrect, assert.
- template<typename T>
- T get() const {
- assert(is<T>() && "Invalid accessor called");
- // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
- typedef typename
- ::llvm::PointerUnionTypeSelector<PT1, T, InnerUnion1,
- ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, InnerUnion2 >
- >::Return Ty;
- return Val.template get<Ty>().template get<T>();
- }
+ /// Returns the value of the specified pointer type.
+ ///
+ /// If the specified pointer type is incorrect, assert.
+ template <typename T> T get() const {
+ assert(is<T>() && "Invalid accessor called");
+ // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2.
+ typedef typename ::llvm::PointerUnionTypeSelector<
+ PT1, T, InnerUnion1, ::llvm::PointerUnionTypeSelector<
+ PT2, T, InnerUnion1, InnerUnion2>>::Return Ty;
+ return Val.template get<Ty>().template get<T>();
+ }
- /// dyn_cast<T>() - If the current value is of the specified pointer type,
- /// return it, otherwise return null.
- template<typename T>
- T dyn_cast() const {
- if (is<T>()) return get<T>();
- return T();
- }
+ /// Returns the current pointer if it is of the specified pointer type,
+ /// otherwises returns null.
+ template <typename T> T dyn_cast() const {
+ if (is<T>())
+ return get<T>();
+ return T();
+ }
- /// \brief Assignment from nullptr which just clears the union.
- const PointerUnion4 &operator=(std::nullptr_t) {
- Val = nullptr;
- return *this;
- }
+ /// Assignment from nullptr which just clears the union.
+ const PointerUnion4 &operator=(std::nullptr_t) {
+ Val = nullptr;
+ return *this;
+ }
- /// Assignment operators - Allow assigning into this union from either
- /// pointer type, setting the discriminator to remember what it came from.
- const PointerUnion4 &operator=(const PT1 &RHS) {
- Val = InnerUnion1(RHS);
- return *this;
- }
- const PointerUnion4 &operator=(const PT2 &RHS) {
- Val = InnerUnion1(RHS);
- return *this;
- }
- const PointerUnion4 &operator=(const PT3 &RHS) {
- Val = InnerUnion2(RHS);
- return *this;
- }
- const PointerUnion4 &operator=(const PT4 &RHS) {
- Val = InnerUnion2(RHS);
- return *this;
- }
+ /// Assignment operators - Allow assigning into this union from either
+ /// pointer type, setting the discriminator to remember what it came from.
+ const PointerUnion4 &operator=(const PT1 &RHS) {
+ Val = InnerUnion1(RHS);
+ return *this;
+ }
+ const PointerUnion4 &operator=(const PT2 &RHS) {
+ Val = InnerUnion1(RHS);
+ return *this;
+ }
+ const PointerUnion4 &operator=(const PT3 &RHS) {
+ Val = InnerUnion2(RHS);
+ return *this;
+ }
+ const PointerUnion4 &operator=(const PT4 &RHS) {
+ Val = InnerUnion2(RHS);
+ return *this;
+ }
- void *getOpaqueValue() const { return Val.getOpaqueValue(); }
- static inline PointerUnion4 getFromOpaqueValue(void *VP) {
- PointerUnion4 V;
- V.Val = ValTy::getFromOpaqueValue(VP);
- return V;
- }
- };
+ void *getOpaqueValue() const { return Val.getOpaqueValue(); }
+ static inline PointerUnion4 getFromOpaqueValue(void *VP) {
+ PointerUnion4 V;
+ V.Val = ValTy::getFromOpaqueValue(VP);
+ return V;
+ }
+};
- // Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
- // # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
- template<typename PT1, typename PT2, typename PT3, typename PT4>
- class PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4> > {
- public:
- static inline void *
- getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
- return P.getOpaqueValue();
- }
- static inline PointerUnion4<PT1, PT2, PT3, PT4>
- getFromVoidPointer(void *P) {
- return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
- }
+// Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has
+// # low bits available = min(PT1bits,PT2bits,PT2bits)-2.
+template <typename PT1, typename PT2, typename PT3, typename PT4>
+class PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4>> {
+public:
+ static inline void *
+ getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) {
+ return P.getOpaqueValue();
+ }
+ static inline PointerUnion4<PT1, PT2, PT3, PT4> getFromVoidPointer(void *P) {
+ return PointerUnion4<PT1, PT2, PT3, PT4>::getFromOpaqueValue(P);
+ }
- // The number of bits available are the min of the two pointer types.
- enum {
- NumLowBitsAvailable =
- PointerLikeTypeTraits<typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>
- ::NumLowBitsAvailable
- };
+ // The number of bits available are the min of the two pointer types.
+ enum {
+ NumLowBitsAvailable = PointerLikeTypeTraits<
+ typename PointerUnion4<PT1, PT2, PT3, PT4>::ValTy>::NumLowBitsAvailable
};
+};
- // Teach DenseMap how to use PointerUnions as keys.
- template<typename T, typename U>
- struct DenseMapInfo<PointerUnion<T, U> > {
- typedef PointerUnion<T, U> Pair;
- typedef DenseMapInfo<T> FirstInfo;
- typedef DenseMapInfo<U> SecondInfo;
+// Teach DenseMap how to use PointerUnions as keys.
+template <typename T, typename U> struct DenseMapInfo<PointerUnion<T, U>> {
+ typedef PointerUnion<T, U> Pair;
+ typedef DenseMapInfo<T> FirstInfo;
+ typedef DenseMapInfo<U> SecondInfo;
+
+ static inline Pair getEmptyKey() { return Pair(FirstInfo::getEmptyKey()); }
+ static inline Pair getTombstoneKey() {
+ return Pair(FirstInfo::getTombstoneKey());
+ }
+ static unsigned getHashValue(const Pair &PairVal) {
+ intptr_t key = (intptr_t)PairVal.getOpaqueValue();
+ return DenseMapInfo<intptr_t>::getHashValue(key);
+ }
+ static bool isEqual(const Pair &LHS, const Pair &RHS) {
+ return LHS.template is<T>() == RHS.template is<T>() &&
+ (LHS.template is<T>() ? FirstInfo::isEqual(LHS.template get<T>(),
+ RHS.template get<T>())
+ : SecondInfo::isEqual(LHS.template get<U>(),
+ RHS.template get<U>()));
+ }
+};
- static inline Pair getEmptyKey() {
- return Pair(FirstInfo::getEmptyKey());
- }
- static inline Pair getTombstoneKey() {
- return Pair(FirstInfo::getTombstoneKey());
- }
- static unsigned getHashValue(const Pair &PairVal) {
- intptr_t key = (intptr_t)PairVal.getOpaqueValue();
- return DenseMapInfo<intptr_t>::getHashValue(key);
- }
- static bool isEqual(const Pair &LHS, const Pair &RHS) {
- return LHS.template is<T>() == RHS.template is<T>() &&
- (LHS.template is<T>() ?
- FirstInfo::isEqual(LHS.template get<T>(),
- RHS.template get<T>()) :
- SecondInfo::isEqual(LHS.template get<U>(),
- RHS.template get<U>()));
- }
- };
}
#endif
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
index 759a2db24f2a..ce343a161b7b 100644
--- a/include/llvm/ADT/PostOrderIterator.h
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -215,8 +215,8 @@ struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
};
template <class T>
-ipo_iterator<T> ipo_begin(const T &G, bool Reverse = false) {
- return ipo_iterator<T>::begin(G, Reverse);
+ipo_iterator<T> ipo_begin(const T &G) {
+ return ipo_iterator<T>::begin(G);
}
template <class T>
@@ -225,8 +225,8 @@ ipo_iterator<T> ipo_end(const T &G){
}
template <class T>
-iterator_range<ipo_iterator<T>> inverse_post_order(const T &G, bool Reverse = false) {
- return make_range(ipo_begin(G, Reverse), ipo_end(G));
+iterator_range<ipo_iterator<T>> inverse_post_order(const T &G) {
+ return make_range(ipo_begin(G), ipo_end(G));
}
// Provide global definitions of external inverse postorder iterators...
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
index b68345a1dcf6..d4360fa8d218 100644
--- a/include/llvm/ADT/STLExtras.h
+++ b/include/llvm/ADT/STLExtras.h
@@ -196,6 +196,41 @@ inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
return mapped_iterator<ItTy, FuncTy>(I, F);
}
+/// \brief Metafunction to determine if type T has a member called rbegin().
+template <typename T> struct has_rbegin {
+ template <typename U> static char(&f(const U &, decltype(&U::rbegin)))[1];
+ static char(&f(...))[2];
+ const static bool value = sizeof(f(std::declval<T>(), nullptr)) == 1;
+};
+
+// Returns an iterator_range over the given container which iterates in reverse.
+// Note that the container must have rbegin()/rend() methods for this to work.
+template <typename ContainerTy>
+auto reverse(ContainerTy &&C,
+ typename std::enable_if<has_rbegin<ContainerTy>::value>::type * =
+ nullptr) -> decltype(make_range(C.rbegin(), C.rend())) {
+ return make_range(C.rbegin(), C.rend());
+}
+
+// Returns a std::reverse_iterator wrapped around the given iterator.
+template <typename IteratorTy>
+std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
+ return std::reverse_iterator<IteratorTy>(It);
+}
+
+// Returns an iterator_range over the given container which iterates in reverse.
+// Note that the container must have begin()/end() methods which return
+// bidirectional iterators for this to work.
+template <typename ContainerTy>
+auto reverse(
+ ContainerTy &&C,
+ typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * = nullptr)
+ -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),
+ llvm::make_reverse_iterator(std::begin(C)))) {
+ return make_range(llvm::make_reverse_iterator(std::end(C)),
+ llvm::make_reverse_iterator(std::begin(C)));
+}
+
//===----------------------------------------------------------------------===//
// Extra additions to <utility>
//===----------------------------------------------------------------------===//
@@ -329,13 +364,28 @@ void DeleteContainerSeconds(Container &C) {
}
/// Provide wrappers to std::all_of which take ranges instead of having to pass
-/// being/end explicitly.
+/// begin/end explicitly.
template<typename R, class UnaryPredicate>
bool all_of(R &&Range, UnaryPredicate &&P) {
return std::all_of(Range.begin(), Range.end(),
std::forward<UnaryPredicate>(P));
}
+/// Provide wrappers to std::any_of which take ranges instead of having to pass
+/// begin/end explicitly.
+template <typename R, class UnaryPredicate>
+bool any_of(R &&Range, UnaryPredicate &&P) {
+ return std::any_of(Range.begin(), Range.end(),
+ std::forward<UnaryPredicate>(P));
+}
+
+/// Provide wrappers to std::find which take ranges instead of having to pass
+/// begin/end explicitly.
+template<typename R, class T>
+auto find(R &&Range, const T &val) -> decltype(Range.begin()) {
+ return std::find(Range.begin(), Range.end(), val);
+}
+
//===----------------------------------------------------------------------===//
// Extra additions to <memory>
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/ADT/ScopedHashTable.h b/include/llvm/ADT/ScopedHashTable.h
index 5abe76c12259..4af3d6d37e33 100644
--- a/include/llvm/ADT/ScopedHashTable.h
+++ b/include/llvm/ADT/ScopedHashTable.h
@@ -1,4 +1,4 @@
-//===- ScopedHashTable.h - A simple scoped hash table ---------------------===//
+//===- ScopedHashTable.h - A simple scoped hash table -----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -47,8 +47,8 @@ class ScopedHashTableVal {
K Key;
V Val;
ScopedHashTableVal(const K &key, const V &val) : Key(key), Val(val) {}
-public:
+public:
const K &getKey() const { return Key; }
const V &getValue() const { return Val; }
V &getValue() { return Val; }
@@ -56,7 +56,7 @@ public:
ScopedHashTableVal *getNextForKey() { return NextForKey; }
const ScopedHashTableVal *getNextForKey() const { return NextForKey; }
ScopedHashTableVal *getNextInScope() { return NextInScope; }
-
+
template <typename AllocatorTy>
static ScopedHashTableVal *Create(ScopedHashTableVal *nextInScope,
ScopedHashTableVal *nextForKey,
@@ -66,12 +66,11 @@ public:
// Set up the value.
new (New) ScopedHashTableVal(key, val);
New->NextInScope = nextInScope;
- New->NextForKey = nextForKey;
+ New->NextForKey = nextForKey;
return New;
}
-
- template <typename AllocatorTy>
- void Destroy(AllocatorTy &Allocator) {
+
+ template <typename AllocatorTy> void Destroy(AllocatorTy &Allocator) {
// Free memory referenced by the item.
this->~ScopedHashTableVal();
Allocator.Deallocate(this);
@@ -90,15 +89,16 @@ class ScopedHashTableScope {
/// LastValInScope - This is the last value that was inserted for this scope
/// or null if none have been inserted yet.
ScopedHashTableVal<K, V> *LastValInScope;
- void operator=(ScopedHashTableScope&) = delete;
- ScopedHashTableScope(ScopedHashTableScope&) = delete;
+ void operator=(ScopedHashTableScope &) = delete;
+ ScopedHashTableScope(ScopedHashTableScope &) = delete;
+
public:
ScopedHashTableScope(ScopedHashTable<K, V, KInfo, AllocatorTy> &HT);
~ScopedHashTableScope();
ScopedHashTableScope *getParentScope() { return PrevScope; }
const ScopedHashTableScope *getParentScope() const { return PrevScope; }
-
+
private:
friend class ScopedHashTable<K, V, KInfo, AllocatorTy>;
ScopedHashTableVal<K, V> *getLastValInScope() {
@@ -109,10 +109,10 @@ private:
}
};
-
-template <typename K, typename V, typename KInfo = DenseMapInfo<K> >
+template <typename K, typename V, typename KInfo = DenseMapInfo<K>>
class ScopedHashTableIterator {
ScopedHashTableVal<K, V> *Node;
+
public:
ScopedHashTableIterator(ScopedHashTableVal<K, V> *node) : Node(node) {}
@@ -141,7 +141,6 @@ public:
}
};
-
template <typename K, typename V, typename KInfo, typename AllocatorTy>
class ScopedHashTable {
public:
@@ -149,23 +148,24 @@ public:
/// to the name of the scope for this hash table.
typedef ScopedHashTableScope<K, V, KInfo, AllocatorTy> ScopeTy;
typedef unsigned size_type;
+
private:
typedef ScopedHashTableVal<K, V> ValTy;
DenseMap<K, ValTy*, KInfo> TopLevelMap;
ScopeTy *CurScope;
-
+
AllocatorTy Allocator;
-
- ScopedHashTable(const ScopedHashTable&); // NOT YET IMPLEMENTED
- void operator=(const ScopedHashTable&); // NOT YET IMPLEMENTED
+
+ ScopedHashTable(const ScopedHashTable &); // NOT YET IMPLEMENTED
+ void operator=(const ScopedHashTable &); // NOT YET IMPLEMENTED
friend class ScopedHashTableScope<K, V, KInfo, AllocatorTy>;
+
public:
ScopedHashTable() : CurScope(nullptr) {}
ScopedHashTable(AllocatorTy A) : CurScope(0), Allocator(A) {}
~ScopedHashTable() {
assert(!CurScope && TopLevelMap.empty() && "Scope imbalance!");
}
-
/// Access to the allocator.
AllocatorTy &getAllocator() { return Allocator; }
@@ -180,7 +180,7 @@ public:
typename DenseMap<K, ValTy*, KInfo>::iterator I = TopLevelMap.find(Key);
if (I != TopLevelMap.end())
return I->second->getValue();
-
+
return V();
}
@@ -198,7 +198,7 @@ public:
if (I == TopLevelMap.end()) return end();
return iterator(I->second);
}
-
+
ScopeTy *getCurScope() { return CurScope; }
const ScopeTy *getCurScope() const { return CurScope; }
diff --git a/include/llvm/ADT/SetOperations.h b/include/llvm/ADT/SetOperations.h
index 71f5db380f6e..7c9f2fbe066e 100644
--- a/include/llvm/ADT/SetOperations.h
+++ b/include/llvm/ADT/SetOperations.h
@@ -39,7 +39,7 @@ bool set_union(S1Ty &S1, const S2Ty &S2) {
template <class S1Ty, class S2Ty>
void set_intersect(S1Ty &S1, const S2Ty &S2) {
for (typename S1Ty::iterator I = S1.begin(); I != S1.end();) {
- const typename S1Ty::key_type &E = *I;
+ const auto &E = *I;
++I;
if (!S2.count(E)) S1.erase(E); // Erase element if not in S2
}
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
index a7fd408c854a..bc563570c203 100644
--- a/include/llvm/ADT/SetVector.h
+++ b/include/llvm/ADT/SetVector.h
@@ -20,6 +20,7 @@
#ifndef LLVM_ADT_SETVECTOR_H
#define LLVM_ADT_SETVECTOR_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallSet.h"
#include <algorithm>
#include <cassert>
@@ -33,7 +34,7 @@ namespace llvm {
/// property of a deterministic iteration order. The order of iteration is the
/// order of insertion.
template <typename T, typename Vector = std::vector<T>,
- typename Set = SmallSet<T, 16> >
+ typename Set = DenseSet<T>>
class SetVector {
public:
typedef T value_type;
@@ -44,6 +45,8 @@ public:
typedef Vector vector_type;
typedef typename vector_type::const_iterator iterator;
typedef typename vector_type::const_iterator const_iterator;
+ typedef typename vector_type::const_reverse_iterator reverse_iterator;
+ typedef typename vector_type::const_reverse_iterator const_reverse_iterator;
typedef typename vector_type::size_type size_type;
/// \brief Construct an empty SetVector
@@ -55,6 +58,8 @@ public:
insert(Start, End);
}
+ ArrayRef<T> getArrayRef() const { return vector_; }
+
/// \brief Determine if the SetVector is empty or not.
bool empty() const {
return vector_.empty();
@@ -85,6 +90,26 @@ public:
return vector_.end();
}
+ /// \brief Get an reverse_iterator to the end of the SetVector.
+ reverse_iterator rbegin() {
+ return vector_.rbegin();
+ }
+
+ /// \brief Get a const_reverse_iterator to the end of the SetVector.
+ const_reverse_iterator rbegin() const {
+ return vector_.rbegin();
+ }
+
+ /// \brief Get a reverse_iterator to the beginning of the SetVector.
+ reverse_iterator rend() {
+ return vector_.rend();
+ }
+
+ /// \brief Get a const_reverse_iterator to the beginning of the SetVector.
+ const_reverse_iterator rend() const {
+ return vector_.rend();
+ }
+
/// \brief Return the last element of the SetVector.
const T &back() const {
assert(!empty() && "Cannot call back() on empty SetVector!");
@@ -150,7 +175,6 @@ public:
return true;
}
-
/// \brief Count the number of elements of a given key in the SetVector.
/// \returns 0 if the element is not in the SetVector, 1 if it is.
size_type count(const key_type &key) const {
@@ -169,7 +193,7 @@ public:
set_.erase(back());
vector_.pop_back();
}
-
+
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() {
T Ret = back();
pop_back();
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index ae3d645396fd..4aa3bc217f41 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -551,19 +551,18 @@ public:
}
private:
- template<bool AddBits, bool InvertMask>
+ template <bool AddBits, bool InvertMask>
void applyMask(const uint32_t *Mask, unsigned MaskWords) {
- if (NumBaseBits == 64 && MaskWords >= 2) {
- uint64_t M = Mask[0] | (uint64_t(Mask[1]) << 32);
- if (InvertMask) M = ~M;
- if (AddBits) setSmallBits(getSmallBits() | M);
- else setSmallBits(getSmallBits() & ~M);
- } else {
- uint32_t M = Mask[0];
- if (InvertMask) M = ~M;
- if (AddBits) setSmallBits(getSmallBits() | M);
- else setSmallBits(getSmallBits() & ~M);
- }
+ assert(MaskWords <= sizeof(uintptr_t) && "Mask is larger than base!");
+ uintptr_t M = Mask[0];
+ if (NumBaseBits == 64)
+ M |= uint64_t(Mask[1]) << 32;
+ if (InvertMask)
+ M = ~M;
+ if (AddBits)
+ setSmallBits(getSmallBits() | M);
+ else
+ setSmallBits(getSmallBits() & ~M);
}
};
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index 3e3c9c154ef4..3d98e8fac43b 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -48,6 +48,7 @@ class SmallPtrSetIteratorImpl;
///
class SmallPtrSetImplBase {
friend class SmallPtrSetIteratorImpl;
+
protected:
/// SmallArray - Points to a fixed size set of buckets, used in 'small mode'.
const void **SmallArray;
@@ -133,6 +134,7 @@ private:
void Grow(unsigned NewSize);
void operator=(const SmallPtrSetImplBase &RHS) = delete;
+
protected:
/// swap - Swaps the elements of two sets.
/// Note: This method assumes that both sets have the same small size.
@@ -148,6 +150,7 @@ class SmallPtrSetIteratorImpl {
protected:
const void *const *Bucket;
const void *const *End;
+
public:
explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E)
: Bucket(BP), End(E) {
@@ -178,14 +181,14 @@ protected:
template<typename PtrTy>
class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
typedef PointerLikeTypeTraits<PtrTy> PtrTraits;
-
+
public:
typedef PtrTy value_type;
typedef PtrTy reference;
typedef PtrTy pointer;
typedef std::ptrdiff_t difference_type;
typedef std::forward_iterator_tag iterator_category;
-
+
explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
: SmallPtrSetIteratorImpl(BP, E) {}
@@ -231,7 +234,6 @@ template<unsigned N>
struct RoundUpToPowerOfTwo {
enum { Val = RoundUpToPowerOfTwoH<N, (N&(N-1)) == 0>::Val };
};
-
/// \brief A templated base class for \c SmallPtrSet which provides the
/// typesafe interface that is common across all small sizes.
@@ -242,7 +244,8 @@ template <typename PtrType>
class SmallPtrSetImpl : public SmallPtrSetImplBase {
typedef PointerLikeTypeTraits<PtrType> PtrTraits;
- SmallPtrSetImpl(const SmallPtrSetImpl&) = delete;
+ SmallPtrSetImpl(const SmallPtrSetImpl &) = delete;
+
protected:
// Constructors that forward to the base.
SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that)
@@ -303,6 +306,7 @@ class SmallPtrSet : public SmallPtrSetImpl<PtrType> {
enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
/// SmallStorage - Fixed size storage used in 'small mode'.
const void *SmallStorage[SmallSizePowTwo];
+
public:
SmallPtrSet() : BaseT(SmallStorage, SmallSizePowTwo) {}
SmallPtrSet(const SmallPtrSet &that) : BaseT(SmallStorage, that) {}
@@ -333,7 +337,6 @@ public:
SmallPtrSetImplBase::swap(RHS);
}
};
-
}
namespace std {
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
index bc6493554c8b..39a57b87b2a7 100644
--- a/include/llvm/ADT/SmallSet.h
+++ b/include/llvm/ADT/SmallSet.h
@@ -37,6 +37,7 @@ class SmallSet {
std::set<T, C> Set;
typedef typename SmallVector<T, N>::const_iterator VIterator;
typedef typename SmallVector<T, N>::iterator mutable_iterator;
+
public:
typedef size_t size_type;
SmallSet() {}
@@ -92,7 +93,7 @@ public:
for (; I != E; ++I)
insert(*I);
}
-
+
bool erase(const T &V) {
if (!isSmall())
return Set.erase(V);
@@ -108,6 +109,7 @@ public:
Vector.clear();
Set.clear();
}
+
private:
bool isSmall() const { return Set.empty(); }
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index b9384702c3ba..d1062acbbb61 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -109,9 +109,13 @@ public:
typedef const T *const_pointer;
// forward iterator creation methods.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
iterator begin() { return (iterator)this->BeginX; }
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
const_iterator begin() const { return (const_iterator)this->BeginX; }
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
iterator end() { return (iterator)this->EndX; }
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
const_iterator end() const { return (const_iterator)this->EndX; }
protected:
iterator capacity_ptr() { return (iterator)this->CapacityX; }
@@ -124,6 +128,7 @@ public:
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
size_type size() const { return end()-begin(); }
size_type max_size() const { return size_type(-1) / sizeof(T); }
@@ -135,10 +140,12 @@ public:
/// Return a pointer to the vector's buffer, even if empty().
const_pointer data() const { return const_pointer(begin()); }
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
reference operator[](size_type idx) {
assert(idx < size());
return begin()[idx];
}
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
const_reference operator[](size_type idx) const {
assert(idx < size());
return begin()[idx];
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 20cbe2cddfc2..e6e72413da4e 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -39,7 +39,6 @@ namespace llvm {
/// etc) do not perform as well in practice as a linked list with this iterator
/// kept up to date. They are also significantly more memory intensive.
-
template <unsigned ElementSize = 128>
struct SparseBitVectorElement
: public ilist_node<SparseBitVectorElement<ElementSize> > {
@@ -204,6 +203,7 @@ public:
BecameZero = allzero;
return changed;
}
+
// Intersect this Element with the complement of RHS and return true if this
// one changed. BecameZero is set to true if this element became all-zero
// bits.
@@ -226,6 +226,7 @@ public:
BecameZero = allzero;
return changed;
}
+
// Three argument version of intersectWithComplement that intersects
// RHS1 & ~RHS2 into this element
void intersectWithComplement(const SparseBitVectorElement &RHS1,
@@ -408,12 +409,13 @@ class SparseBitVector {
// bitmap.
return AtEnd == RHS.AtEnd && RHS.BitNumber == BitNumber;
}
+
bool operator!=(const SparseBitVectorIterator &RHS) const {
return !(*this == RHS);
}
- SparseBitVectorIterator(): BitVector(NULL) {
- }
+ SparseBitVectorIterator(): BitVector(nullptr) {
+ }
SparseBitVectorIterator(const SparseBitVector<ElementSize> *RHS,
bool end = false):BitVector(RHS) {
@@ -453,6 +455,9 @@ public:
// Assignment
SparseBitVector& operator=(const SparseBitVector& RHS) {
+ if (this == &RHS)
+ return *this;
+
Elements.clear();
ElementListConstIter ElementIter = RHS.Elements.begin();
@@ -559,6 +564,9 @@ public:
// Union our bitmap with the RHS and return true if we changed.
bool operator|=(const SparseBitVector &RHS) {
+ if (this == &RHS)
+ return false;
+
bool changed = false;
ElementListIter Iter1 = Elements.begin();
ElementListConstIter Iter2 = RHS.Elements.begin();
@@ -587,6 +595,9 @@ public:
// Intersect our bitmap with the RHS and return true if ours changed.
bool operator&=(const SparseBitVector &RHS) {
+ if (this == &RHS)
+ return false;
+
bool changed = false;
ElementListIter Iter1 = Elements.begin();
ElementListConstIter Iter2 = RHS.Elements.begin();
@@ -619,9 +630,13 @@ public:
ElementListIter IterTmp = Iter1;
++Iter1;
Elements.erase(IterTmp);
+ changed = true;
}
}
- Elements.erase(Iter1, Elements.end());
+ if (Iter1 != Elements.end()) {
+ Elements.erase(Iter1, Elements.end());
+ changed = true;
+ }
CurrElementIter = Elements.begin();
return changed;
}
@@ -629,6 +644,14 @@ public:
// Intersect our bitmap with the complement of the RHS and return true
// if ours changed.
bool intersectWithComplement(const SparseBitVector &RHS) {
+ if (this == &RHS) {
+ if (!empty()) {
+ clear();
+ return true;
+ }
+ return false;
+ }
+
bool changed = false;
ElementListIter Iter1 = Elements.begin();
ElementListConstIter Iter2 = RHS.Elements.begin();
@@ -669,12 +692,20 @@ public:
return intersectWithComplement(*RHS);
}
-
// Three argument version of intersectWithComplement.
// Result of RHS1 & ~RHS2 is stored into this bitmap.
void intersectWithComplement(const SparseBitVector<ElementSize> &RHS1,
const SparseBitVector<ElementSize> &RHS2)
{
+ if (this == &RHS1) {
+ intersectWithComplement(RHS2);
+ return;
+ } else if (this == &RHS2) {
+ SparseBitVector RHS2Copy(RHS2);
+ intersectWithComplement(RHS1, RHS2Copy);
+ return;
+ }
+
Elements.clear();
CurrElementIter = Elements.begin();
ElementListConstIter Iter1 = RHS1.Elements.begin();
@@ -719,8 +750,6 @@ public:
Elements.push_back(NewElement);
++Iter1;
}
-
- return;
}
void intersectWithComplement(const SparseBitVector<ElementSize> *RHS1,
@@ -855,9 +884,6 @@ operator-(const SparseBitVector<ElementSize> &LHS,
return Result;
}
-
-
-
// Dump a SparseBitVector to a stream
template <unsigned ElementSize>
void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
@@ -875,4 +901,4 @@ void dump(const SparseBitVector<ElementSize> &LHS, raw_ostream &out) {
}
} // end namespace llvm
-#endif
+#endif // LLVM_ADT_SPARSEBITVECTOR_H
diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h
index d98abc375e8a..7c84e3ef6b4d 100644
--- a/include/llvm/ADT/Statistic.h
+++ b/include/llvm/ADT/Statistic.h
@@ -28,9 +28,11 @@
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Valgrind.h"
+#include <memory>
namespace llvm {
class raw_ostream;
+class raw_fd_ostream;
class Statistic {
public:
@@ -170,6 +172,9 @@ void EnableStatistics();
/// \brief Check if statistics are enabled.
bool AreStatisticsEnabled();
+/// \brief Return a file stream to print our output on.
+std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
+
/// \brief Print statistics to the file returned by CreateInfoOutputFile().
void PrintStatistics();
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index 9d038560bf92..700bb9e10ef7 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -30,6 +30,7 @@ namespace llvm {
/// StringMapEntryBase - Shared base class of StringMapEntry instances.
class StringMapEntryBase {
unsigned StrLen;
+
public:
explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {}
@@ -48,6 +49,7 @@ protected:
unsigned NumItems;
unsigned NumTombstones;
unsigned ItemSize;
+
protected:
explicit StringMapImpl(unsigned itemSize)
: TheTable(nullptr),
@@ -85,8 +87,10 @@ protected:
/// RemoveKey - Remove the StringMapEntry for the specified key from the
/// table, returning it. If the key is not in the table, this returns null.
StringMapEntryBase *RemoveKey(StringRef Key);
+
private:
void init(unsigned Size);
+
public:
static StringMapEntryBase *getTombstoneVal() {
return (StringMapEntryBase*)-1;
@@ -112,6 +116,7 @@ public:
template<typename ValueTy>
class StringMapEntry : public StringMapEntryBase {
StringMapEntry(StringMapEntry &E) = delete;
+
public:
ValueTy second;
@@ -205,7 +210,6 @@ public:
}
};
-
/// StringMap - This is an unconventional map that is specialized for handling
/// keys that are "strings", which are basically ranges of bytes. This does some
/// funky memory allocation and hashing things to make it extremely efficient,
@@ -213,9 +217,10 @@ public:
template<typename ValueTy, typename AllocatorTy = MallocAllocator>
class StringMap : public StringMapImpl {
AllocatorTy Allocator;
+
public:
typedef StringMapEntry<ValueTy> MapEntryTy;
-
+
StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
explicit StringMap(unsigned InitialSize)
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
@@ -227,6 +232,13 @@ public:
: StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
Allocator(A) {}
+ StringMap(std::initializer_list<std::pair<StringRef, ValueTy>> List)
+ : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
+ for (const auto &P : List) {
+ insert(P);
+ }
+ }
+
StringMap(StringMap &&RHS)
: StringMapImpl(std::move(RHS)), Allocator(std::move(RHS.Allocator)) {}
@@ -386,11 +398,10 @@ public:
}
};
-
-template<typename ValueTy>
-class StringMapConstIterator {
+template <typename ValueTy> class StringMapConstIterator {
protected:
StringMapEntryBase **Ptr;
+
public:
typedef StringMapEntry<ValueTy> value_type;
@@ -447,7 +458,6 @@ public:
return static_cast<StringMapEntry<ValueTy>*>(*this->Ptr);
}
};
-
}
#endif
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index 95660a49f1f1..350032b8c4e7 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -10,6 +10,7 @@
#ifndef LLVM_ADT_STRINGREF_H
#define LLVM_ADT_STRINGREF_H
+#include "llvm/Support/Compiler.h"
#include <algorithm>
#include <cassert>
#include <cstring>
@@ -53,6 +54,7 @@ namespace llvm {
// Workaround memcmp issue with null pointers (undefined behavior)
// by providing a specialized version
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
if (Length == 0) { return 0; }
return ::memcmp(Lhs,Rhs,Length);
@@ -73,6 +75,7 @@ namespace llvm {
}
/// Construct a string ref from a pointer and length.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ StringRef(const char *data, size_t length)
: Data(data), Length(length) {
assert((data || length == 0) &&
@@ -80,6 +83,7 @@ namespace llvm {
}
/// Construct a string ref from an std::string.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
/*implicit*/ StringRef(const std::string &Str)
: Data(Str.data()), Length(Str.length()) {}
@@ -104,12 +108,15 @@ namespace llvm {
/// data - Get a pointer to the start of the string (which may not be null
/// terminated).
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
const char *data() const { return Data; }
/// empty - Check if the string is empty.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
bool empty() const { return Length == 0; }
/// size - Get the string size.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
size_t size() const { return Length; }
/// front - Get the first character in the string.
@@ -133,6 +140,7 @@ namespace llvm {
/// equals - Check for string equality, this is more efficient than
/// compare() when the relative ordering of inequal strings isn't needed.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
bool equals(StringRef RHS) const {
return (Length == RHS.Length &&
compareMemory(Data, RHS.Data, RHS.Length) == 0);
@@ -145,6 +153,7 @@ namespace llvm {
/// compare - Compare two strings; the result is -1, 0, or 1 if this string
/// is lexicographically less than, equal to, or greater than the \p RHS.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
int compare(StringRef RHS) const {
// Check the prefix for a mismatch.
if (int Res = compareMemory(Data, RHS.Data, std::min(Length, RHS.Length)))
@@ -212,6 +221,7 @@ namespace llvm {
/// @{
/// Check if this string starts with the given \p Prefix.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
bool startswith(StringRef Prefix) const {
return Length >= Prefix.Length &&
compareMemory(Data, Prefix.Data, Prefix.Length) == 0;
@@ -221,6 +231,7 @@ namespace llvm {
bool startswith_lower(StringRef Prefix) const;
/// Check if this string ends with the given \p Suffix.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
bool endswith(StringRef Suffix) const {
return Length >= Suffix.Length &&
compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
@@ -237,6 +248,7 @@ namespace llvm {
///
/// \returns The index of the first occurrence of \p C, or npos if not
/// found.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
size_t find(char C, size_t From = 0) const {
size_t FindBegin = std::min(From, Length);
if (FindBegin < Length) { // Avoid calling memchr with nullptr.
@@ -402,6 +414,7 @@ namespace llvm {
/// \param N The number of characters to included in the substring. If N
/// exceeds the number of characters remaining in the string, the string
/// suffix (starting with \p Start) will be returned.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef substr(size_t Start, size_t N = npos) const {
Start = std::min(Start, Length);
return StringRef(Data + Start, std::min(N, Length - Start));
@@ -409,6 +422,7 @@ namespace llvm {
/// Return a StringRef equal to 'this' but with the first \p N elements
/// dropped.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef drop_front(size_t N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(N);
@@ -416,6 +430,7 @@ namespace llvm {
/// Return a StringRef equal to 'this' but with the last \p N elements
/// dropped.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef drop_back(size_t N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return substr(0, size()-N);
@@ -431,6 +446,7 @@ namespace llvm {
/// substring. If this is npos, or less than \p Start, or exceeds the
/// number of characters remaining in the string, the string suffix
/// (starting with \p Start) will be returned.
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringRef slice(size_t Start, size_t End) const {
Start = std::min(Start, Length);
End = std::min(std::max(Start, End), Length);
@@ -474,7 +490,7 @@ namespace llvm {
/// Split into substrings around the occurrences of a separator string.
///
/// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
- /// \p MaxSplit splits are done and consequently <= \p MaxSplit
+ /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1
/// elements are added to A.
/// If \p KeepEmpty is false, empty strings are not added to \p A. They
/// still count when considering \p MaxSplit
@@ -489,6 +505,23 @@ namespace llvm {
StringRef Separator, int MaxSplit = -1,
bool KeepEmpty = true) const;
+ /// Split into substrings around the occurrences of a separator character.
+ ///
+ /// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
+ /// \p MaxSplit splits are done and consequently <= \p MaxSplit + 1
+ /// elements are added to A.
+ /// If \p KeepEmpty is false, empty strings are not added to \p A. They
+ /// still count when considering \p MaxSplit
+ /// An useful invariant is that
+ /// Separator.join(A) == *this if MaxSplit == -1 and KeepEmpty == true
+ ///
+ /// \param A - Where to put the substrings.
+ /// \param Separator - The string to split on.
+ /// \param MaxSplit - The maximum number of times the string is split.
+ /// \param KeepEmpty - True if empty substring should be added.
+ void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1,
+ bool KeepEmpty = true) const;
+
/// Split into two substrings around the last occurrence of a separator
/// character.
///
@@ -530,10 +563,12 @@ namespace llvm {
/// @name StringRef Comparison Operators
/// @{
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
inline bool operator==(StringRef LHS, StringRef RHS) {
return LHS.equals(RHS);
}
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
inline bool operator!=(StringRef LHS, StringRef RHS) {
return !(LHS == RHS);
}
diff --git a/include/llvm/ADT/StringSet.h b/include/llvm/ADT/StringSet.h
index 3e0cc200b6dd..08626dc7af84 100644
--- a/include/llvm/ADT/StringSet.h
+++ b/include/llvm/ADT/StringSet.h
@@ -23,6 +23,11 @@ namespace llvm {
class StringSet : public llvm::StringMap<char, AllocatorTy> {
typedef llvm::StringMap<char, AllocatorTy> base;
public:
+ StringSet() = default;
+ StringSet(std::initializer_list<StringRef> S) {
+ for (StringRef X : S)
+ insert(X);
+ }
std::pair<typename base::iterator, bool> insert(StringRef Key) {
assert(!Key.empty());
diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h
index 0393a0c373ef..42b0fc4bc441 100644
--- a/include/llvm/ADT/StringSwitch.h
+++ b/include/llvm/ADT/StringSwitch.h
@@ -14,6 +14,7 @@
#define LLVM_ADT_STRINGSWITCH_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstring>
@@ -48,10 +49,12 @@ class StringSwitch {
const T *Result;
public:
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
explicit StringSwitch(StringRef S)
: Str(S), Result(nullptr) { }
template<unsigned N>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Case(const char (&S)[N], const T& Value) {
if (!Result && N-1 == Str.size() &&
(std::memcmp(S, Str.data(), N-1) == 0)) {
@@ -62,6 +65,7 @@ public:
}
template<unsigned N>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
if (!Result && Str.size() >= N-1 &&
std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0) {
@@ -72,6 +76,7 @@ public:
}
template<unsigned N>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
if (!Result && Str.size() >= N-1 &&
std::memcmp(S, Str.data(), N-1) == 0) {
@@ -82,32 +87,66 @@ public:
}
template<unsigned N0, unsigned N1>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const T& Value) {
- return Case(S0, Value).Case(S1, Value);
+ if (!Result && (
+ (N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
+ (N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0))) {
+ Result = &Value;
+ }
+
+ return *this;
}
template<unsigned N0, unsigned N1, unsigned N2>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const T& Value) {
- return Case(S0, Value).Case(S1, Value).Case(S2, Value);
+ if (!Result && (
+ (N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
+ (N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
+ (N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0))) {
+ Result = &Value;
+ }
+
+ return *this;
}
template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const char (&S3)[N3],
const T& Value) {
- return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value);
+ if (!Result && (
+ (N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
+ (N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
+ (N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0) ||
+ (N3-1 == Str.size() && std::memcmp(S3, Str.data(), N3-1) == 0))) {
+ Result = &Value;
+ }
+
+ return *this;
}
template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
StringSwitch& Cases(const char (&S0)[N0], const char (&S1)[N1],
const char (&S2)[N2], const char (&S3)[N3],
const char (&S4)[N4], const T& Value) {
- return Case(S0, Value).Case(S1, Value).Case(S2, Value).Case(S3, Value)
- .Case(S4, Value);
+ if (!Result && (
+ (N0-1 == Str.size() && std::memcmp(S0, Str.data(), N0-1) == 0) ||
+ (N1-1 == Str.size() && std::memcmp(S1, Str.data(), N1-1) == 0) ||
+ (N2-1 == Str.size() && std::memcmp(S2, Str.data(), N2-1) == 0) ||
+ (N3-1 == Str.size() && std::memcmp(S3, Str.data(), N3-1) == 0) ||
+ (N4-1 == Str.size() && std::memcmp(S4, Str.data(), N4-1) == 0))) {
+ Result = &Value;
+ }
+
+ return *this;
}
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
R Default(const T& Value) const {
if (Result)
return *Result;
@@ -115,6 +154,7 @@ public:
return Value;
}
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
operator R() const {
assert(Result && "Fell off the end of a string-switch");
return *Result;
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
index f29608f3d3d1..487aa46cf642 100644
--- a/include/llvm/ADT/TinyPtrVector.h
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -15,7 +15,7 @@
#include "llvm/ADT/SmallVector.h"
namespace llvm {
-
+
/// TinyPtrVector - This class is specialized for cases where there are
/// normally 0 or 1 element in a vector, but is general enough to go beyond that
/// when required.
@@ -150,7 +150,6 @@ public:
return Val.getAddrOfPtr1();
return Val.template get<VecTy *>()->begin();
-
}
iterator end() {
if (Val.template is<EltTy>())
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 947812d94ecb..e01db0a61fd5 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -50,6 +50,7 @@ public:
armeb, // ARM (big endian): armeb
aarch64, // AArch64 (little endian): aarch64
aarch64_be, // AArch64 (big endian): aarch64_be
+ avr, // AVR: Atmel AVR microcontroller
bpfel, // eBPF or extended BPF or 64-bit BPF (little endian)
bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian)
hexagon, // Hexagon: hexagon
@@ -75,8 +76,8 @@ public:
xcore, // XCore: xcore
nvptx, // NVPTX: 32-bit
nvptx64, // NVPTX: 64-bit
- le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
- le64, // le64: generic little-endian 64-bit CPU (PNaCl / Emscripten)
+ le32, // le32: generic little-endian 32-bit CPU (PNaCl)
+ le64, // le64: generic little-endian 64-bit CPU (PNaCl)
amdil, // AMDIL
amdil64, // AMDIL with 64-bit pointers
hsail, // AMD HSAIL
@@ -92,12 +93,14 @@ public:
enum SubArchType {
NoSubArch,
+ ARMSubArch_v8_2a,
ARMSubArch_v8_1a,
ARMSubArch_v8,
ARMSubArch_v7,
ARMSubArch_v7em,
ARMSubArch_v7m,
ARMSubArch_v7s,
+ ARMSubArch_v7k,
ARMSubArch_v6,
ARMSubArch_v6m,
ARMSubArch_v6k,
@@ -124,7 +127,8 @@ public:
MipsTechnologies,
NVIDIA,
CSR,
- LastVendorType = CSR
+ Myriad,
+ LastVendorType = Myriad
};
enum OSType {
UnknownOS,
@@ -153,7 +157,10 @@ public:
NVCL, // NVIDIA OpenCL
AMDHSA, // AMD HSA Runtime
PS4,
- LastOSType = PS4
+ ELFIAMCU,
+ TvOS, // Apple tvOS
+ WatchOS, // Apple watchOS
+ LastOSType = WatchOS
};
enum EnvironmentType {
UnknownEnvironment,
@@ -170,7 +177,9 @@ public:
MSVC,
Itanium,
Cygnus,
- LastEnvironmentType = Cygnus
+ AMDOpenCL,
+ CoreCLR,
+ LastEnvironmentType = CoreCLR
};
enum ObjectFormatType {
UnknownObjectFormat,
@@ -205,7 +214,7 @@ public:
/// @name Constructors
/// @{
- /// \brief Default constructor is the same as an empty string and leaves all
+ /// Default constructor is the same as an empty string and leaves all
/// triple fields unknown.
Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {}
@@ -231,7 +240,7 @@ public:
/// common case in which otherwise valid components are in the wrong order.
static std::string normalize(StringRef Str);
- /// \brief Return the normalized form of this triple's string.
+ /// Return the normalized form of this triple's string.
std::string normalize() const { return normalize(Data); }
/// @}
@@ -259,7 +268,7 @@ public:
/// getEnvironment - Get the parsed environment type of this triple.
EnvironmentType getEnvironment() const { return Environment; }
- /// \brief Parse the version number from the OS name component of the
+ /// Parse the version number from the OS name component of the
/// triple, if present.
///
/// For example, "fooos1.2.3" would return (1, 2, 3).
@@ -295,10 +304,15 @@ public:
unsigned &Micro) const;
/// getiOSVersion - Parse the version number as with getOSVersion. This should
- /// only be called with IOS triples.
+ /// only be called with IOS or generic triples.
void getiOSVersion(unsigned &Major, unsigned &Minor,
unsigned &Micro) const;
+ /// getWatchOSVersion - Parse the version number as with getOSVersion. This
+ /// should only be called with WatchOS or generic triples.
+ void getWatchOSVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const;
+
/// @}
/// @name Direct Component Access
/// @{
@@ -331,7 +345,7 @@ public:
/// @name Convenience Predicates
/// @{
- /// \brief Test whether the architecture is 64-bit
+ /// Test whether the architecture is 64-bit
///
/// Note that this tests for 64-bit pointer width, and nothing else. Note
/// that we intentionally expose only three predicates, 64-bit, 32-bit, and
@@ -340,12 +354,12 @@ public:
/// system is provided.
bool isArch64Bit() const;
- /// \brief Test whether the architecture is 32-bit
+ /// Test whether the architecture is 32-bit
///
/// Note that this tests for 32-bit pointer width, and nothing else.
bool isArch32Bit() const;
- /// \brief Test whether the architecture is 16-bit
+ /// Test whether the architecture is 16-bit
///
/// Note that this tests for 16-bit pointer width, and nothing else.
bool isArch16Bit() const;
@@ -396,13 +410,27 @@ public:
}
/// Is this an iOS triple.
+ /// Note: This identifies tvOS as a variant of iOS. If that ever
+ /// changes, i.e., if the two operating systems diverge or their version
+ /// numbers get out of sync, that will need to be changed.
+ /// watchOS has completely different version numbers so it is not included.
bool isiOS() const {
- return getOS() == Triple::IOS;
+ return getOS() == Triple::IOS || isTvOS();
+ }
+
+ /// Is this an Apple tvOS triple.
+ bool isTvOS() const {
+ return getOS() == Triple::TvOS;
+ }
+
+ /// Is this an Apple watchOS triple.
+ bool isWatchOS() const {
+ return getOS() == Triple::WatchOS;
}
- /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
+ /// isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
bool isOSDarwin() const {
- return isMacOSX() || isiOS();
+ return isMacOSX() || isiOS() || isWatchOS();
}
bool isOSNetBSD() const {
@@ -427,16 +455,26 @@ public:
return getOS() == Triple::Bitrig;
}
+ bool isOSIAMCU() const {
+ return getOS() == Triple::ELFIAMCU;
+ }
+
+ /// Checks if the environment could be MSVC.
bool isWindowsMSVCEnvironment() const {
return getOS() == Triple::Win32 &&
(getEnvironment() == Triple::UnknownEnvironment ||
getEnvironment() == Triple::MSVC);
}
+ /// Checks if the environment is MSVC.
bool isKnownWindowsMSVCEnvironment() const {
return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC;
}
+ bool isWindowsCoreCLREnvironment() const {
+ return getOS() == Triple::Win32 && getEnvironment() == Triple::CoreCLR;
+ }
+
bool isWindowsItaniumEnvironment() const {
return getOS() == Triple::Win32 && getEnvironment() == Triple::Itanium;
}
@@ -449,60 +487,63 @@ public:
return getOS() == Triple::Win32 && getEnvironment() == Triple::GNU;
}
- /// \brief Tests for either Cygwin or MinGW OS
+ /// Tests for either Cygwin or MinGW OS
bool isOSCygMing() const {
return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment();
}
- /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
+ /// Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
bool isOSMSVCRT() const {
return isWindowsMSVCEnvironment() || isWindowsGNUEnvironment() ||
isWindowsItaniumEnvironment();
}
- /// \brief Tests whether the OS is Windows.
+ /// Tests whether the OS is Windows.
bool isOSWindows() const {
return getOS() == Triple::Win32;
}
- /// \brief Tests whether the OS is NaCl (Native Client)
+ /// Tests whether the OS is NaCl (Native Client)
bool isOSNaCl() const {
return getOS() == Triple::NaCl;
}
- /// \brief Tests whether the OS is Linux.
+ /// Tests whether the OS is Linux.
bool isOSLinux() const {
return getOS() == Triple::Linux;
}
- /// \brief Tests whether the OS uses the ELF binary format.
+ /// Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
return getObjectFormat() == Triple::ELF;
}
- /// \brief Tests whether the OS uses the COFF binary format.
+ /// Tests whether the OS uses the COFF binary format.
bool isOSBinFormatCOFF() const {
return getObjectFormat() == Triple::COFF;
}
- /// \brief Tests whether the environment is MachO.
+ /// Tests whether the environment is MachO.
bool isOSBinFormatMachO() const {
return getObjectFormat() == Triple::MachO;
}
- /// \brief Tests whether the target is the PS4 CPU
+ /// Tests whether the target is the PS4 CPU
bool isPS4CPU() const {
return getArch() == Triple::x86_64 &&
getVendor() == Triple::SCEI &&
getOS() == Triple::PS4;
}
- /// \brief Tests whether the target is the PS4 platform
+ /// Tests whether the target is the PS4 platform
bool isPS4() const {
return getVendor() == Triple::SCEI &&
getOS() == Triple::PS4;
}
+ /// Tests whether the target is Android
+ bool isAndroid() const { return getEnvironment() == Triple::Android; }
+
/// @}
/// @name Mutators
/// @{
@@ -553,7 +594,7 @@ public:
/// @name Helpers to build variants of a particular triple.
/// @{
- /// \brief Form a triple with a 32-bit variant of the current architecture.
+ /// Form a triple with a 32-bit variant of the current architecture.
///
/// This can be used to move across "families" of architectures where useful.
///
@@ -561,7 +602,7 @@ public:
/// architecture if no such variant can be found.
llvm::Triple get32BitArchVariant() const;
- /// \brief Form a triple with a 64-bit variant of the current architecture.
+ /// Form a triple with a 64-bit variant of the current architecture.
///
/// This can be used to move across "families" of architectures where useful.
///
@@ -589,7 +630,7 @@ public:
///
/// \param Arch the architecture name (e.g., "armv7s"). If it is an empty
/// string then the triple's arch name is used.
- const char* getARMCPUForArch(StringRef Arch = StringRef()) const;
+ StringRef getARMCPUForArch(StringRef Arch = StringRef()) const;
/// @}
/// @name Static helpers for IDs.
diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h
index a9cb2f5709eb..e1ab4b56023f 100644
--- a/include/llvm/ADT/UniqueVector.h
+++ b/include/llvm/ADT/UniqueVector.h
@@ -11,6 +11,7 @@
#define LLVM_ADT_UNIQUEVECTOR_H
#include <cassert>
+#include <cstddef>
#include <map>
#include <vector>
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
index a7b9306b3a73..3044a6c435f1 100644
--- a/include/llvm/ADT/ilist.h
+++ b/include/llvm/ADT/ilist.h
@@ -104,6 +104,53 @@ struct ilist_sentinel_traits {
}
};
+template <typename NodeTy> class ilist_half_node;
+template <typename NodeTy> class ilist_node;
+
+/// Traits with an embedded ilist_node as a sentinel.
+///
+/// FIXME: The downcast in createSentinel() is UB.
+template <typename NodeTy> struct ilist_embedded_sentinel_traits {
+ /// Get hold of the node that marks the end of the list.
+ NodeTy *createSentinel() const {
+ // Since i(p)lists always publicly derive from their corresponding traits,
+ // placing a data member in this class will augment the i(p)list. But since
+ // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
+ // there is a legal viable downcast from it to NodeTy. We use this trick to
+ // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
+ // sentinel. Dereferencing the sentinel is forbidden (save the
+ // ilist_node<NodeTy>), so no one will ever notice the superposition.
+ return static_cast<NodeTy *>(&Sentinel);
+ }
+ static void destroySentinel(NodeTy *) {}
+
+ NodeTy *provideInitialHead() const { return createSentinel(); }
+ NodeTy *ensureHead(NodeTy *) const { return createSentinel(); }
+ static void noteHead(NodeTy *, NodeTy *) {}
+
+private:
+ mutable ilist_node<NodeTy> Sentinel;
+};
+
+/// Trait with an embedded ilist_half_node as a sentinel.
+///
+/// FIXME: The downcast in createSentinel() is UB.
+template <typename NodeTy> struct ilist_half_embedded_sentinel_traits {
+ /// Get hold of the node that marks the end of the list.
+ NodeTy *createSentinel() const {
+ // See comment in ilist_embedded_sentinel_traits::createSentinel().
+ return static_cast<NodeTy *>(&Sentinel);
+ }
+ static void destroySentinel(NodeTy *) {}
+
+ NodeTy *provideInitialHead() const { return createSentinel(); }
+ NodeTy *ensureHead(NodeTy *) const { return createSentinel(); }
+ static void noteHead(NodeTy *, NodeTy *) {}
+
+private:
+ mutable ilist_half_node<NodeTy> Sentinel;
+};
+
/// ilist_node_traits - A fragment for template traits for intrusive list
/// that provides default node related operations.
///
@@ -173,8 +220,8 @@ private:
template<class T> void operator-(T) const;
public:
- ilist_iterator(pointer NP) : NodePtr(NP) {}
- ilist_iterator(reference NR) : NodePtr(&NR) {}
+ explicit ilist_iterator(pointer NP) : NodePtr(NP) {}
+ explicit ilist_iterator(reference NR) : NodePtr(&NR) {}
ilist_iterator() : NodePtr(nullptr) {}
// This is templated so that we can allow constructing a const iterator from
@@ -191,8 +238,10 @@ public:
return *this;
}
+ void reset(pointer NP) { NodePtr = NP; }
+
// Accessors...
- operator pointer() const {
+ explicit operator pointer() const {
return NodePtr;
}
@@ -202,11 +251,11 @@ public:
pointer operator->() const { return &operator*(); }
// Comparison operators
- bool operator==(const ilist_iterator &RHS) const {
- return NodePtr == RHS.NodePtr;
+ template <class Y> bool operator==(const ilist_iterator<Y> &RHS) const {
+ return NodePtr == RHS.getNodePtrUnchecked();
}
- bool operator!=(const ilist_iterator &RHS) const {
- return NodePtr != RHS.NodePtr;
+ template <class Y> bool operator!=(const ilist_iterator<Y> &RHS) const {
+ return NodePtr != RHS.getNodePtrUnchecked();
}
// Increment and decrement operators...
@@ -422,7 +471,7 @@ public:
this->setPrev(CurNode, New);
this->addNodeToList(New); // Notify traits that we added a node...
- return New;
+ return iterator(New);
}
iterator insertAfter(iterator where, NodeTy *New) {
@@ -443,7 +492,7 @@ public:
else
Head = NextNode;
this->setPrev(NextNode, PrevNode);
- IT = NextNode;
+ IT.reset(NextNode);
this->removeNodeFromList(Node); // Notify traits that we removed a node...
// Set the next/prev pointers of the current node to null. This isn't
@@ -461,12 +510,18 @@ public:
return remove(MutIt);
}
+ NodeTy *remove(NodeTy *IT) { return remove(iterator(IT)); }
+ NodeTy *remove(NodeTy &IT) { return remove(iterator(IT)); }
+
// erase - remove a node from the controlled sequence... and delete it.
iterator erase(iterator where) {
this->deleteNode(remove(where));
return where;
}
+ iterator erase(NodeTy *IT) { return erase(iterator(IT)); }
+ iterator erase(NodeTy &IT) { return erase(iterator(IT)); }
+
/// Remove all nodes from the list like clear(), but do not call
/// removeNodeFromList() or deleteNode().
///
@@ -522,7 +577,7 @@ private:
this->setNext(Last, PosNext);
this->setPrev(PosNext, Last);
- this->transferNodesFromList(L2, First, PosNext);
+ this->transferNodesFromList(L2, iterator(First), iterator(PosNext));
// Now that everything is set, restore the pointers to the list sentinels.
L2.setTail(L2Sentinel);
@@ -579,6 +634,83 @@ public:
void splice(iterator where, iplist &L2, iterator first, iterator last) {
if (first != last) transfer(where, L2, first, last);
}
+ void splice(iterator where, iplist &L2, NodeTy &N) {
+ splice(where, L2, iterator(N));
+ }
+ void splice(iterator where, iplist &L2, NodeTy *N) {
+ splice(where, L2, iterator(N));
+ }
+
+ template <class Compare>
+ void merge(iplist &Right, Compare comp) {
+ if (this == &Right)
+ return;
+ iterator First1 = begin(), Last1 = end();
+ iterator First2 = Right.begin(), Last2 = Right.end();
+ while (First1 != Last1 && First2 != Last2) {
+ if (comp(*First2, *First1)) {
+ iterator Next = First2;
+ transfer(First1, Right, First2, ++Next);
+ First2 = Next;
+ } else {
+ ++First1;
+ }
+ }
+ if (First2 != Last2)
+ transfer(Last1, Right, First2, Last2);
+ }
+ void merge(iplist &Right) { return merge(Right, op_less); }
+
+ template <class Compare>
+ void sort(Compare comp) {
+ // The list is empty, vacuously sorted.
+ if (empty())
+ return;
+ // The list has a single element, vacuously sorted.
+ if (std::next(begin()) == end())
+ return;
+ // Find the split point for the list.
+ iterator Center = begin(), End = begin();
+ while (End != end() && std::next(End) != end()) {
+ Center = std::next(Center);
+ End = std::next(std::next(End));
+ }
+ // Split the list into two.
+ iplist RightHalf;
+ RightHalf.splice(RightHalf.begin(), *this, Center, end());
+
+ // Sort the two sublists.
+ sort(comp);
+ RightHalf.sort(comp);
+
+ // Merge the two sublists back together.
+ merge(RightHalf, comp);
+ }
+ void sort() { sort(op_less); }
+
+ /// \brief Get the previous node, or \c nullptr for the list head.
+ NodeTy *getPrevNode(NodeTy &N) const {
+ auto I = N.getIterator();
+ if (I == begin())
+ return nullptr;
+ return &*std::prev(I);
+ }
+ /// \brief Get the previous node, or \c nullptr for the list head.
+ const NodeTy *getPrevNode(const NodeTy &N) const {
+ return getPrevNode(const_cast<NodeTy &>(N));
+ }
+
+ /// \brief Get the next node, or \c nullptr for the list tail.
+ NodeTy *getNextNode(NodeTy &N) const {
+ auto Next = std::next(N.getIterator());
+ if (Next == end())
+ return nullptr;
+ return &*Next;
+ }
+ /// \brief Get the next node, or \c nullptr for the list tail.
+ const NodeTy *getNextNode(const NodeTy &N) const {
+ return getNextNode(const_cast<NodeTy &>(N));
+ }
};
diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h
index 26d0b55e4093..7e5a0e0e5ad8 100644
--- a/include/llvm/ADT/ilist_node.h
+++ b/include/llvm/ADT/ilist_node.h
@@ -19,12 +19,15 @@ namespace llvm {
template<typename NodeTy>
struct ilist_traits;
+template <typename NodeTy> struct ilist_embedded_sentinel_traits;
+template <typename NodeTy> struct ilist_half_embedded_sentinel_traits;
/// ilist_half_node - Base class that provides prev services for sentinels.
///
template<typename NodeTy>
class ilist_half_node {
friend struct ilist_traits<NodeTy>;
+ friend struct ilist_half_embedded_sentinel_traits<NodeTy>;
NodeTy *Prev;
protected:
NodeTy *getPrev() { return Prev; }
@@ -36,6 +39,8 @@ protected:
template<typename NodeTy>
struct ilist_nextprev_traits;
+template <typename NodeTy> class ilist_iterator;
+
/// ilist_node - Base class that provides next/prev services for nodes
/// that use ilist_nextprev_traits or ilist_default_traits.
///
@@ -43,6 +48,8 @@ template<typename NodeTy>
class ilist_node : private ilist_half_node<NodeTy> {
friend struct ilist_nextprev_traits<NodeTy>;
friend struct ilist_traits<NodeTy>;
+ friend struct ilist_half_embedded_sentinel_traits<NodeTy>;
+ friend struct ilist_embedded_sentinel_traits<NodeTy>;
NodeTy *Next;
NodeTy *getNext() { return Next; }
const NodeTy *getNext() const { return Next; }
@@ -51,53 +58,63 @@ protected:
ilist_node() : Next(nullptr) {}
public:
- /// @name Adjacent Node Accessors
- /// @{
-
- /// \brief Get the previous node, or 0 for the list head.
- NodeTy *getPrevNode() {
- NodeTy *Prev = this->getPrev();
+ ilist_iterator<NodeTy> getIterator() {
+ // FIXME: Stop downcasting to create the iterator (potential UB).
+ return ilist_iterator<NodeTy>(static_cast<NodeTy *>(this));
+ }
+ ilist_iterator<const NodeTy> getIterator() const {
+ // FIXME: Stop downcasting to create the iterator (potential UB).
+ return ilist_iterator<const NodeTy>(static_cast<const NodeTy *>(this));
+ }
+};
- // Check for sentinel.
- if (!Prev->getNext())
- return nullptr;
+/// An ilist node that can access its parent list.
+///
+/// Requires \c NodeTy to have \a getParent() to find the parent node, and the
+/// \c ParentTy to have \a getSublistAccess() to get a reference to the list.
+template <typename NodeTy, typename ParentTy>
+class ilist_node_with_parent : public ilist_node<NodeTy> {
+protected:
+ ilist_node_with_parent() = default;
- return Prev;
+private:
+ /// Forward to NodeTy::getParent().
+ ///
+ /// Note: do not use the name "getParent()". We want a compile error
+ /// (instead of recursion) when the subclass fails to implement \a
+ /// getParent().
+ const ParentTy *getNodeParent() const {
+ return static_cast<const NodeTy *>(this)->getParent();
}
- /// \brief Get the previous node, or 0 for the list head.
+public:
+ /// @name Adjacent Node Accessors
+ /// @{
+ /// \brief Get the previous node, or \c nullptr for the list head.
+ NodeTy *getPrevNode() {
+ // Should be separated to a reused function, but then we couldn't use auto
+ // (and would need the type of the list).
+ const auto &List =
+ getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
+ return List.getPrevNode(*static_cast<NodeTy *>(this));
+ }
+ /// \brief Get the previous node, or \c nullptr for the list head.
const NodeTy *getPrevNode() const {
- const NodeTy *Prev = this->getPrev();
-
- // Check for sentinel.
- if (!Prev->getNext())
- return nullptr;
-
- return Prev;
+ return const_cast<ilist_node_with_parent *>(this)->getPrevNode();
}
- /// \brief Get the next node, or 0 for the list tail.
+ /// \brief Get the next node, or \c nullptr for the list tail.
NodeTy *getNextNode() {
- NodeTy *Next = getNext();
-
- // Check for sentinel.
- if (!Next->getNext())
- return nullptr;
-
- return Next;
+ // Should be separated to a reused function, but then we couldn't use auto
+ // (and would need the type of the list).
+ const auto &List =
+ getNodeParent()->*(ParentTy::getSublistAccess((NodeTy *)nullptr));
+ return List.getNextNode(*static_cast<NodeTy *>(this));
}
-
- /// \brief Get the next node, or 0 for the list tail.
+ /// \brief Get the next node, or \c nullptr for the list tail.
const NodeTy *getNextNode() const {
- const NodeTy *Next = getNext();
-
- // Check for sentinel.
- if (!Next->getNext())
- return nullptr;
-
- return Next;
+ return const_cast<ilist_node_with_parent *>(this)->getNextNode();
}
-
/// @}
};
diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h
index 523a86f02e08..3dd679bd9b79 100644
--- a/include/llvm/ADT/iterator_range.h
+++ b/include/llvm/ADT/iterator_range.h
@@ -20,6 +20,7 @@
#define LLVM_ADT_ITERATOR_RANGE_H
#include <utility>
+#include <iterator>
namespace llvm {
@@ -32,6 +33,12 @@ class iterator_range {
IteratorT begin_iterator, end_iterator;
public:
+ //TODO: Add SFINAE to test that the Container's iterators match the range's
+ // iterators.
+ template <typename Container>
+ iterator_range(Container &&c)
+ //TODO: Consider ADL/non-member begin/end calls.
+ : begin_iterator(c.begin()), end_iterator(c.end()) {}
iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
: begin_iterator(std::move(begin_iterator)),
end_iterator(std::move(end_iterator)) {}
@@ -51,6 +58,11 @@ template <class T> iterator_range<T> make_range(T x, T y) {
template <typename T> iterator_range<T> make_range(std::pair<T, T> p) {
return iterator_range<T>(std::move(p.first), std::move(p.second));
}
+
+template<typename T>
+iterator_range<decltype(begin(std::declval<T>()))> drop_begin(T &&t, int n) {
+ return make_range(std::next(begin(t), n), end(t));
+}
}
#endif