aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/ADT
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-04-23 16:57:46 -0700
committerStephen Hines <srhines@google.com>2014-04-24 15:53:16 -0700
commit36b56886974eae4f9c5ebc96befd3e7bfe5de338 (patch)
treee6cfb69fbbd937f450eeb83bfb83b9da3b01275a /include/llvm/ADT
parent69a8640022b04415ae9fac62f8ab090601d8f889 (diff)
downloadexternal_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.zip
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.gz
external_llvm-36b56886974eae4f9c5ebc96befd3e7bfe5de338.tar.bz2
Update to LLVM 3.5a.
Change-Id: Ifadecab779f128e62e430c2b4f6ddd84953ed617
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r--include/llvm/ADT/APFloat.h4
-rw-r--r--include/llvm/ADT/APInt.h35
-rw-r--r--include/llvm/ADT/APSInt.h14
-rw-r--r--include/llvm/ADT/ArrayRef.h10
-rw-r--r--include/llvm/ADT/BitVector.h24
-rw-r--r--include/llvm/ADT/DenseMap.h43
-rw-r--r--include/llvm/ADT/DenseSet.h9
-rw-r--r--include/llvm/ADT/EquivalenceClasses.h1
-rw-r--r--include/llvm/ADT/FoldingSet.h28
-rw-r--r--include/llvm/ADT/Hashing.h25
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h30
-rw-r--r--include/llvm/ADT/MapVector.h6
-rw-r--r--include/llvm/ADT/Optional.h7
-rw-r--r--include/llvm/ADT/OwningPtr.h18
-rw-r--r--include/llvm/ADT/PointerIntPair.h26
-rw-r--r--include/llvm/ADT/PointerUnion.h2
-rw-r--r--include/llvm/ADT/SCCIterator.h188
-rw-r--r--include/llvm/ADT/STLExtras.h233
-rw-r--r--include/llvm/ADT/SetVector.h5
-rw-r--r--include/llvm/ADT/SmallBitVector.h4
-rw-r--r--include/llvm/ADT/SmallPtrSet.h108
-rw-r--r--include/llvm/ADT/SmallSet.h11
-rw-r--r--include/llvm/ADT/SmallString.h3
-rw-r--r--include/llvm/ADT/SmallVector.h36
-rw-r--r--include/llvm/ADT/SparseBitVector.h2
-rw-r--r--include/llvm/ADT/SparseMultiSet.h17
-rw-r--r--include/llvm/ADT/SparseSet.h14
-rw-r--r--include/llvm/ADT/StringExtras.h7
-rw-r--r--include/llvm/ADT/StringMap.h35
-rw-r--r--include/llvm/ADT/StringRef.h18
-rw-r--r--include/llvm/ADT/TinyPtrVector.h8
-rw-r--r--include/llvm/ADT/Triple.h113
-rw-r--r--include/llvm/ADT/ValueMap.h377
-rw-r--r--include/llvm/ADT/iterator_range.h45
-rw-r--r--include/llvm/ADT/polymorphic_ptr.h117
35 files changed, 686 insertions, 937 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 43a7866..acfefe9 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -1,4 +1,4 @@
-//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==//
+//===- llvm/ADT/APFloat.h - Arbitrary Precision Floating Point ---*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -196,6 +196,7 @@ public:
explicit APFloat(double d);
explicit APFloat(float f);
APFloat(const APFloat &);
+ APFloat(APFloat &&);
~APFloat();
/// @}
@@ -411,6 +412,7 @@ public:
/// @}
APFloat &operator=(const APFloat &);
+ APFloat &operator=(APFloat &&);
/// \brief Overload to compute a hash code for an APFloat value.
///
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index d494ad2..aa3c3f6 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -284,12 +284,10 @@ public:
initSlowCase(that);
}
-#if LLVM_HAS_RVALUE_REFERENCES
/// \brief Move Constructor.
APInt(APInt &&that) : BitWidth(that.BitWidth), VAL(that.VAL) {
that.BitWidth = 0;
}
-#endif
/// \brief Destructor.
~APInt() {
@@ -656,7 +654,6 @@ public:
return AssignSlowCase(RHS);
}
-#if LLVM_HAS_RVALUE_REFERENCES
/// @brief Move assignment operator.
APInt &operator=(APInt &&that) {
if (!isSingleWord())
@@ -669,7 +666,6 @@ public:
return *this;
}
-#endif
/// \brief Assignment operator.
///
@@ -1265,7 +1261,7 @@ public:
/// \returns the number of words to hold the integer value with a given bit
/// width.
static unsigned getNumWords(unsigned BitWidth) {
- return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
+ return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
}
/// \brief Compute the number of active bits in the value
@@ -1504,6 +1500,35 @@ public:
return BitWidth - (*this - 1).countLeadingZeros();
}
+ /// \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
+ ///
+ /// to get around any mathematical concerns resulting from
+ /// referencing 2 in a space where 2 does no exist.
+ unsigned nearestLogBase2() const {
+ // Special case when we have a bitwidth of 1. If VAL is 1, then we
+ // get 0. If VAL is 0, we get UINT64_MAX which gets truncated to
+ // UINT32_MAX.
+ if (BitWidth == 1)
+ return VAL - 1;
+
+ // Handle the zero case.
+ if (!getBoolValue())
+ return UINT32_MAX;
+
+ // The non-zero case is handled by computing:
+ //
+ // nearestLogBase2(x) = logBase2(x) + x[logBase2(x)-1].
+ //
+ // where x[i] is referring to the value of the ith bit of x.
+ unsigned lg = logBase2();
+ return lg + unsigned((*this)[lg - 1]);
+ }
+
/// \returns the log base 2 of this APInt if its an exact power of two, -1
/// otherwise
int32_t exactLogBase2() const {
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index ad035a7..053deff 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -30,18 +30,12 @@ public:
explicit APSInt(uint32_t BitWidth, bool isUnsigned = true)
: APInt(BitWidth, 0), IsUnsigned(isUnsigned) {}
- explicit APSInt(const APInt &I, bool isUnsigned = true)
- : APInt(I), IsUnsigned(isUnsigned) {}
+ explicit APSInt(APInt I, bool isUnsigned = true)
+ : APInt(std::move(I)), IsUnsigned(isUnsigned) {}
- APSInt &operator=(const APSInt &RHS) {
- APInt::operator=(RHS);
- IsUnsigned = RHS.IsUnsigned;
- return *this;
- }
-
- APSInt &operator=(const APInt &RHS) {
+ APSInt &operator=(APInt RHS) {
// Retain our current sign.
- APInt::operator=(RHS);
+ APInt::operator=(std::move(RHS));
return *this;
}
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index e5562c3..fcf280d 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
#include <vector>
namespace llvm {
@@ -76,7 +77,7 @@ namespace llvm {
/// Construct an ArrayRef from a std::vector.
template<typename A>
/*implicit*/ ArrayRef(const std::vector<T, A> &Vec)
- : Data(Vec.empty() ? (T*)0 : &Vec[0]), Length(Vec.size()) {}
+ : Data(Vec.data()), Length(Vec.size()) {}
/// Construct an ArrayRef from a C array.
template <size_t N>
@@ -120,6 +121,13 @@ namespace llvm {
return Data[Length-1];
}
+ // copy - Allocate copy in BumpPtrAllocator and return ArrayRef<T> to it.
+ ArrayRef<T> copy(BumpPtrAllocator &Allocator) {
+ T *Buff = Allocator.Allocate<T>(Length);
+ std::copy(begin(), end(), Buff);
+ return ArrayRef<T>(Buff, Length);
+ }
+
/// equals - Check for element-wise equality.
bool equals(ArrayRef RHS) const {
if (Length != RHS.Length)
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 8fb538f..b531820 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -58,14 +58,14 @@ public:
reference& operator=(bool t) {
if (t)
- *WordRef |= 1L << BitPos;
+ *WordRef |= BitWord(1) << BitPos;
else
- *WordRef &= ~(1L << BitPos);
+ *WordRef &= ~(BitWord(1) << BitPos);
return *this;
}
operator bool() const {
- return ((*WordRef) & (1L << BitPos)) ? true : false;
+ return ((*WordRef) & (BitWord(1) << BitPos)) ? true : false;
}
};
@@ -98,12 +98,10 @@ public:
std::memcpy(Bits, RHS.Bits, Capacity * sizeof(BitWord));
}
-#if LLVM_HAS_RVALUE_REFERENCES
BitVector(BitVector &&RHS)
: Bits(RHS.Bits), Size(RHS.Size), Capacity(RHS.Capacity) {
RHS.Bits = 0;
}
-#endif
~BitVector() {
std::free(Bits);
@@ -240,7 +238,7 @@ public:
}
BitVector &set(unsigned Idx) {
- Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ Bits[Idx / BITWORD_SIZE] |= BitWord(1) << (Idx % BITWORD_SIZE);
return *this;
}
@@ -267,7 +265,8 @@ public:
Bits[I / BITWORD_SIZE] = ~0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
- Bits[I / BITWORD_SIZE] |= PostfixMask;
+ if (I < E)
+ Bits[I / BITWORD_SIZE] |= PostfixMask;
return *this;
}
@@ -278,7 +277,7 @@ public:
}
BitVector &reset(unsigned Idx) {
- Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ Bits[Idx / BITWORD_SIZE] &= ~(BitWord(1) << (Idx % BITWORD_SIZE));
return *this;
}
@@ -305,7 +304,8 @@ public:
Bits[I / BITWORD_SIZE] = 0UL;
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
- Bits[I / BITWORD_SIZE] &= ~PostfixMask;
+ if (I < E)
+ Bits[I / BITWORD_SIZE] &= ~PostfixMask;
return *this;
}
@@ -318,7 +318,7 @@ public:
}
BitVector &flip(unsigned Idx) {
- Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
+ Bits[Idx / BITWORD_SIZE] ^= BitWord(1) << (Idx % BITWORD_SIZE);
return *this;
}
@@ -330,7 +330,7 @@ public:
bool operator[](unsigned Idx) const {
assert (Idx < Size && "Out-of-bounds Bit access.");
- BitWord Mask = 1L << (Idx % BITWORD_SIZE);
+ BitWord Mask = BitWord(1) << (Idx % BITWORD_SIZE);
return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
}
@@ -459,7 +459,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
const BitVector &operator=(BitVector &&RHS) {
if (this == &RHS) return *this;
@@ -472,7 +471,6 @@ public:
return *this;
}
-#endif
void swap(BitVector &RHS) {
std::swap(Bits, RHS.Bits);
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index ce322cc..037989f 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -161,7 +161,6 @@ public:
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
}
-#if LLVM_HAS_RVALUE_REFERENCES
// Inserts key,value pair into the map if the key isn't already in the map.
// If the key is already in the map, it returns false and doesn't update the
// value.
@@ -177,8 +176,7 @@ public:
TheBucket);
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
}
-#endif
-
+
/// insert - Range insertion of pairs.
template<typename InputIt>
void insert(InputIt I, InputIt E) {
@@ -218,7 +216,6 @@ public:
return FindAndConstruct(Key).second;
}
-#if LLVM_HAS_RVALUE_REFERENCES
value_type& FindAndConstruct(KeyT &&Key) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
@@ -230,7 +227,6 @@ public:
ValueT &operator[](KeyT &&Key) {
return FindAndConstruct(std::move(Key)).second;
}
-#endif
/// isPointerIntoBucketsArray - Return true if the specified pointer points
/// somewhere into the DenseMap's array of buckets (i.e. either to a key or
@@ -289,8 +285,8 @@ protected:
bool FoundVal = LookupBucketFor(B->first, DestBucket);
(void)FoundVal; // silence warning.
assert(!FoundVal && "Key already in new map?");
- DestBucket->first = llvm_move(B->first);
- new (&DestBucket->second) ValueT(llvm_move(B->second));
+ DestBucket->first = std::move(B->first);
+ new (&DestBucket->second) ValueT(std::move(B->second));
incrementNumEntries();
// Free the value.
@@ -403,7 +399,6 @@ private:
return TheBucket;
}
-#if LLVM_HAS_RVALUE_REFERENCES
BucketT *InsertIntoBucket(const KeyT &Key, ValueT &&Value,
BucketT *TheBucket) {
TheBucket = InsertIntoBucketImpl(Key, TheBucket);
@@ -420,7 +415,6 @@ private:
new (&TheBucket->second) ValueT(std::move(Value));
return TheBucket;
}
-#endif
BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
// If the load of the hash table is more than 3/4, or if fewer than 1/8 of
@@ -555,12 +549,10 @@ public:
copyFrom(other);
}
-#if LLVM_HAS_RVALUE_REFERENCES
DenseMap(DenseMap &&other) : BaseT() {
init(0);
swap(other);
}
-#endif
template<typename InputIt>
DenseMap(const InputIt &I, const InputIt &E) {
@@ -585,7 +577,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
DenseMap& operator=(DenseMap &&other) {
this->destroyAll();
operator delete(Buckets);
@@ -593,7 +584,6 @@ public:
swap(other);
return *this;
}
-#endif
void copyFrom(const DenseMap& other) {
this->destroyAll();
@@ -719,12 +709,10 @@ public:
copyFrom(other);
}
-#if LLVM_HAS_RVALUE_REFERENCES
SmallDenseMap(SmallDenseMap &&other) : BaseT() {
init(0);
swap(other);
}
-#endif
template<typename InputIt>
SmallDenseMap(const InputIt &I, const InputIt &E) {
@@ -765,10 +753,10 @@ public:
// Swap separately and handle any assymetry.
std::swap(LHSB->first, RHSB->first);
if (hasLHSValue) {
- new (&RHSB->second) ValueT(llvm_move(LHSB->second));
+ new (&RHSB->second) ValueT(std::move(LHSB->second));
LHSB->second.~ValueT();
} else if (hasRHSValue) {
- new (&LHSB->second) ValueT(llvm_move(RHSB->second));
+ new (&LHSB->second) ValueT(std::move(RHSB->second));
RHSB->second.~ValueT();
}
}
@@ -784,7 +772,7 @@ public:
SmallDenseMap &LargeSide = Small ? RHS : *this;
// First stash the large side's rep and move the small side across.
- LargeRep TmpRep = llvm_move(*LargeSide.getLargeRep());
+ LargeRep TmpRep = std::move(*LargeSide.getLargeRep());
LargeSide.getLargeRep()->~LargeRep();
LargeSide.Small = true;
// This is similar to the standard move-from-old-buckets, but the bucket
@@ -794,11 +782,11 @@ public:
for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
BucketT *NewB = &LargeSide.getInlineBuckets()[i],
*OldB = &SmallSide.getInlineBuckets()[i];
- new (&NewB->first) KeyT(llvm_move(OldB->first));
+ new (&NewB->first) KeyT(std::move(OldB->first));
OldB->first.~KeyT();
if (!KeyInfoT::isEqual(NewB->first, EmptyKey) &&
!KeyInfoT::isEqual(NewB->first, TombstoneKey)) {
- new (&NewB->second) ValueT(llvm_move(OldB->second));
+ new (&NewB->second) ValueT(std::move(OldB->second));
OldB->second.~ValueT();
}
}
@@ -806,7 +794,7 @@ public:
// The hard part of moving the small buckets across is done, just move
// the TmpRep into its new home.
SmallSide.Small = false;
- new (SmallSide.getLargeRep()) LargeRep(llvm_move(TmpRep));
+ new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
}
SmallDenseMap& operator=(const SmallDenseMap& other) {
@@ -814,7 +802,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
SmallDenseMap& operator=(SmallDenseMap &&other) {
this->destroyAll();
deallocateBuckets();
@@ -822,7 +809,6 @@ public:
swap(other);
return *this;
}
-#endif
void copyFrom(const SmallDenseMap& other) {
this->destroyAll();
@@ -830,7 +816,7 @@ public:
Small = true;
if (other.getNumBuckets() > InlineBuckets) {
Small = false;
- allocateBuckets(other.getNumBuckets());
+ new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets()));
}
this->BaseT::copyFrom(other);
}
@@ -866,8 +852,8 @@ public:
!KeyInfoT::isEqual(P->first, TombstoneKey)) {
assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
"Too many inline buckets!");
- new (&TmpEnd->first) KeyT(llvm_move(P->first));
- new (&TmpEnd->second) ValueT(llvm_move(P->second));
+ new (&TmpEnd->first) KeyT(std::move(P->first));
+ new (&TmpEnd->second) ValueT(std::move(P->second));
++TmpEnd;
P->second.~ValueT();
}
@@ -882,7 +868,7 @@ public:
return;
}
- LargeRep OldRep = llvm_move(*getLargeRep());
+ LargeRep OldRep = std::move(*getLargeRep());
getLargeRep()->~LargeRep();
if (AtLeast <= InlineBuckets) {
Small = true;
@@ -991,7 +977,8 @@ class DenseMapIterator {
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, true>;
public:
typedef ptrdiff_t difference_type;
- typedef typename conditional<IsConst, const Bucket, Bucket>::type value_type;
+ typedef typename std::conditional<IsConst, const Bucket, Bucket>::type
+ value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef std::forward_iterator_tag iterator_category;
diff --git a/include/llvm/ADT/DenseSet.h b/include/llvm/ADT/DenseSet.h
index d699ad5..1d8c39c 100644
--- a/include/llvm/ADT/DenseSet.h
+++ b/include/llvm/ADT/DenseSet.h
@@ -27,7 +27,9 @@ class DenseSet {
typedef DenseMap<ValueT, char, ValueInfoT> MapTy;
MapTy TheMap;
public:
- DenseSet(const DenseSet &Other) : TheMap(Other.TheMap) {}
+ typedef ValueT key_type;
+ typedef ValueT value_type;
+
explicit DenseSet(unsigned NumInitBuckets = 0) : TheMap(NumInitBuckets) {}
bool empty() const { return TheMap.empty(); }
@@ -54,11 +56,6 @@ public:
TheMap.swap(RHS.TheMap);
}
- DenseSet &operator=(const DenseSet &RHS) {
- TheMap = RHS.TheMap;
- return *this;
- }
-
// Iterators.
class Iterator {
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
index 1d81772..2256ee7 100644
--- a/include/llvm/ADT/EquivalenceClasses.h
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -249,7 +249,6 @@ public:
explicit member_iterator() {}
explicit member_iterator(const ECValue *N) : Node(N) {}
- member_iterator(const member_iterator &I) : Node(I.Node) {}
reference operator*() const {
assert(Node != 0 && "Dereferencing end()!");
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 1b2c94c..188010d 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -18,12 +18,12 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
class APFloat;
class APInt;
- class BumpPtrAllocator;
/// This folding set used for two purposes:
/// 1. Given information about a node we want to create, look up the unique
@@ -278,6 +278,8 @@ public:
bool operator==(FoldingSetNodeIDRef) const;
+ bool operator!=(FoldingSetNodeIDRef RHS) const { return !(*this == RHS); }
+
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
bool operator<(FoldingSetNodeIDRef) const;
@@ -331,6 +333,9 @@ public:
bool operator==(const FoldingSetNodeID &RHS) const;
bool operator==(const FoldingSetNodeIDRef RHS) const;
+ bool operator!=(const FoldingSetNodeID &RHS) const { return !(*this == RHS); }
+ bool operator!=(const FoldingSetNodeIDRef RHS) const { return !(*this ==RHS);}
+
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
bool operator<(const FoldingSetNodeID &RHS) const;
@@ -391,20 +396,20 @@ template<class T> class FoldingSet : public FoldingSetImpl {
private:
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier.
- virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const {
+ void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override {
T *TN = static_cast<T *>(N);
FoldingSetTrait<T>::Profile(*TN, ID);
}
/// NodeEquals - Instantiations may optionally provide a way to compare a
/// node with a specified ID.
- virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
- FoldingSetNodeID &TempID) const {
+ bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID);
}
/// ComputeNodeHash - Instantiations may optionally provide a way to compute a
/// hash value directly from a node.
- virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const {
+ unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
}
@@ -468,20 +473,19 @@ private:
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier.
- virtual void GetNodeProfile(FoldingSetImpl::Node *N,
- FoldingSetNodeID &ID) const {
+ void GetNodeProfile(FoldingSetImpl::Node *N,
+ FoldingSetNodeID &ID) const override {
T *TN = static_cast<T *>(N);
ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
}
- virtual bool NodeEquals(FoldingSetImpl::Node *N,
- const FoldingSetNodeID &ID, unsigned IDHash,
- FoldingSetNodeID &TempID) const {
+ bool NodeEquals(FoldingSetImpl::Node *N, const FoldingSetNodeID &ID,
+ unsigned IDHash, FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
Context);
}
- virtual unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
- FoldingSetNodeID &TempID) const {
+ unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
+ FoldingSetNodeID &TempID) const override {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
}
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index e434417..4bffd8e 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -109,7 +109,8 @@ public:
/// differing argument types even if they would implicit promote to a common
/// type without changing the value.
template <typename T>
-typename enable_if<is_integral_or_enum<T>, hash_code>::type hash_value(T value);
+typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
+hash_value(T value);
/// \brief Compute a hash_code for a pointer's address.
///
@@ -352,24 +353,24 @@ inline size_t get_execution_seed() {
// and pointers, but there are platforms where it doesn't and we would like to
// support user-defined types which happen to satisfy this property.
template <typename T> struct is_hashable_data
- : integral_constant<bool, ((is_integral_or_enum<T>::value ||
- is_pointer<T>::value) &&
- 64 % sizeof(T) == 0)> {};
+ : std::integral_constant<bool, ((is_integral_or_enum<T>::value ||
+ std::is_pointer<T>::value) &&
+ 64 % sizeof(T) == 0)> {};
// Special case std::pair to detect when both types are viable and when there
// is no alignment-derived padding in the pair. This is a bit of a lie because
// std::pair isn't truly POD, but it's close enough in all reasonable
// implementations for our use case of hashing the underlying data.
template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
- : integral_constant<bool, (is_hashable_data<T>::value &&
- is_hashable_data<U>::value &&
- (sizeof(T) + sizeof(U)) ==
- sizeof(std::pair<T, U>))> {};
+ : std::integral_constant<bool, (is_hashable_data<T>::value &&
+ is_hashable_data<U>::value &&
+ (sizeof(T) + sizeof(U)) ==
+ sizeof(std::pair<T, U>))> {};
/// \brief Helper to get the hashable data representation for a type.
/// This variant is enabled when the type itself can be used.
template <typename T>
-typename enable_if<is_hashable_data<T>, T>::type
+typename std::enable_if<is_hashable_data<T>::value, T>::type
get_hashable_data(const T &value) {
return value;
}
@@ -377,7 +378,7 @@ get_hashable_data(const T &value) {
/// This variant is enabled when we must first call hash_value and use the
/// result as our data.
template <typename T>
-typename enable_if_c<!is_hashable_data<T>::value, size_t>::type
+typename std::enable_if<!is_hashable_data<T>::value, size_t>::type
get_hashable_data(const T &value) {
using ::llvm::hash_value;
return hash_value(value);
@@ -451,7 +452,7 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
/// are stored in contiguous memory, this routine avoids copying each value
/// and directly reads from the underlying memory.
template <typename ValueT>
-typename enable_if<is_hashable_data<ValueT>, hash_code>::type
+typename std::enable_if<is_hashable_data<ValueT>::value, hash_code>::type
hash_combine_range_impl(ValueT *first, ValueT *last) {
const size_t seed = get_execution_seed();
const char *s_begin = reinterpret_cast<const char *>(first);
@@ -734,7 +735,7 @@ inline hash_code hash_integer_value(uint64_t value) {
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T>
-typename enable_if<is_integral_or_enum<T>, hash_code>::type
+typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
hash_value(T value) {
return ::llvm::hashing::detail::hash_integer_value(value);
}
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index b8b8861..729e37f 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -23,6 +23,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
+#include <atomic>
#include <memory>
namespace llvm {
@@ -88,6 +89,31 @@ namespace llvm {
static void retain(T *obj) { obj->Retain(); }
static void release(T *obj) { obj->Release(); }
};
+
+/// \brief A thread-safe version of \c llvm::RefCountedBase.
+///
+/// A generic base class for objects that wish to have their lifetimes managed
+/// using reference counts. Classes subclass \c ThreadSafeRefCountedBase to
+/// obtain such functionality, and are typically handled with
+/// \c IntrusiveRefCntPtr "smart pointers" which automatically handle the
+/// management of reference counts.
+template <class Derived>
+class ThreadSafeRefCountedBase {
+ mutable std::atomic<int> RefCount;
+
+protected:
+ ThreadSafeRefCountedBase() : RefCount(0) {}
+
+public:
+ void Retain() const { ++RefCount; }
+
+ void Release() const {
+ int NewRefCount = --RefCount;
+ assert(NewRefCount >= 0 && "Reference count was already zero.");
+ if (NewRefCount == 0)
+ delete static_cast<const Derived*>(this);
+ }
+};
//===----------------------------------------------------------------------===//
/// IntrusiveRefCntPtr - A template class that implements a "smart pointer"
@@ -109,7 +135,7 @@ namespace llvm {
template <typename T>
class IntrusiveRefCntPtr {
T* Obj;
- typedef IntrusiveRefCntPtr this_type;
+
public:
typedef T element_type;
@@ -123,7 +149,6 @@ namespace llvm {
retain();
}
-#if LLVM_HAS_RVALUE_REFERENCES
IntrusiveRefCntPtr(IntrusiveRefCntPtr&& S) : Obj(S.Obj) {
S.Obj = 0;
}
@@ -132,7 +157,6 @@ namespace llvm {
IntrusiveRefCntPtr(IntrusiveRefCntPtr<X>&& S) : Obj(S.getPtr()) {
S.Obj = 0;
}
-#endif
template <class X>
IntrusiveRefCntPtr(const IntrusiveRefCntPtr<X>& S)
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
index f6fcb08..7fd1570 100644
--- a/include/llvm/ADT/MapVector.h
+++ b/include/llvm/ADT/MapVector.h
@@ -1,4 +1,4 @@
-//===- llvm/ADT/MapVector.h - Map with deterministic value order *- C++ -*-===//
+//===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -17,9 +17,7 @@
#ifndef LLVM_ADT_MAPVECTOR_H
#define LLVM_ADT_MAPVECTOR_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
#include <vector>
namespace llvm {
@@ -97,7 +95,7 @@ public:
if (Result.second) {
Vector.push_back(std::make_pair(KV.first, KV.second));
I = Vector.size() - 1;
- return std::make_pair(llvm::prior(end()), true);
+ return std::make_pair(std::prev(end()), true);
}
return std::make_pair(begin() + I, false);
}
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index 194e53f..ae8344d 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -17,13 +17,10 @@
#define LLVM_ADT_OPTIONAL_H
#include "llvm/ADT/None.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
-
-#if LLVM_HAS_RVALUE_REFERENCES
#include <utility>
-#endif
namespace llvm {
@@ -42,7 +39,6 @@ public:
new (storage.buffer) T(*O);
}
-#if LLVM_HAS_RVALUE_REFERENCES
Optional(T &&y) : hasVal(true) {
new (storage.buffer) T(std::forward<T>(y));
}
@@ -70,7 +66,6 @@ public:
}
return *this;
}
-#endif
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h
index 6b9e42e..034bcfd 100644
--- a/include/llvm/ADT/OwningPtr.h
+++ b/include/llvm/ADT/OwningPtr.h
@@ -17,6 +17,7 @@
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstddef>
+#include <memory>
namespace llvm {
@@ -32,13 +33,22 @@ class OwningPtr {
public:
explicit OwningPtr(T *P = 0) : Ptr(P) {}
-#if LLVM_HAS_RVALUE_REFERENCES
OwningPtr(OwningPtr &&Other) : Ptr(Other.take()) {}
OwningPtr &operator=(OwningPtr &&Other) {
reset(Other.take());
return *this;
}
+
+ OwningPtr(std::unique_ptr<T> Other) : Ptr(Other.release()) {}
+
+ OwningPtr &operator=(std::unique_ptr<T> Other) {
+ reset(Other.release());
+ return *this;
+ }
+
+#if LLVM_HAS_RVALUE_REFERENCE_THIS
+ operator std::unique_ptr<T>() && { return std::unique_ptr<T>(take()); }
#endif
~OwningPtr() {
@@ -63,6 +73,10 @@ public:
return Tmp;
}
+ T *release() { return take(); }
+
+ std::unique_ptr<T> take_unique() { return std::unique_ptr<T>(take()); }
+
T &operator*() const {
assert(Ptr && "Cannot dereference null pointer");
return *Ptr;
@@ -96,14 +110,12 @@ class OwningArrayPtr {
public:
explicit OwningArrayPtr(T *P = 0) : Ptr(P) {}
-#if LLVM_HAS_RVALUE_REFERENCES
OwningArrayPtr(OwningArrayPtr &&Other) : Ptr(Other.take()) {}
OwningArrayPtr &operator=(OwningArrayPtr &&Other) {
reset(Other.take());
return *this;
}
-#endif
~OwningArrayPtr() {
delete [] Ptr;
diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h
index 0cfd470..45a40db 100644
--- a/include/llvm/ADT/PointerIntPair.h
+++ b/include/llvm/ADT/PointerIntPair.h
@@ -17,6 +17,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
#include <cassert>
+#include <limits>
namespace llvm {
@@ -41,7 +42,12 @@ template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
class PointerIntPair {
intptr_t Value;
- enum LLVM_ENUM_INT_TYPE(uintptr_t) {
+ 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),
@@ -59,8 +65,6 @@ class PointerIntPair {
public:
PointerIntPair() : Value(0) {}
PointerIntPair(PointerTy PtrVal, IntType IntVal) {
- assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
- "PointerIntPair formed with integer size too large for pointer");
setPointerAndInt(PtrVal, IntVal);
}
explicit PointerIntPair(PointerTy PtrVal) {
@@ -79,7 +83,7 @@ public:
void setPointer(PointerTy PtrVal) {
intptr_t PtrWord
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ assert((PtrWord & ~PointerBitMask) == 0 &&
"Pointer is not sufficiently aligned");
// Preserve all low bits, just update the pointer.
Value = PtrWord | (Value & ~PointerBitMask);
@@ -87,7 +91,7 @@ public:
void setInt(IntType IntVal) {
intptr_t IntWord = static_cast<intptr_t>(IntVal);
- assert(IntWord < (1 << IntBits) && "Integer too large for field");
+ assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
// Preserve all bits other than the ones we are updating.
Value &= ~ShiftedIntMask; // Remove integer field.
@@ -97,7 +101,7 @@ public:
void initWithPointer(PointerTy PtrVal) {
intptr_t PtrWord
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ assert((PtrWord & ~PointerBitMask) == 0 &&
"Pointer is not sufficiently aligned");
Value = PtrWord;
}
@@ -105,10 +109,10 @@ public:
void setPointerAndInt(PointerTy PtrVal, IntType IntVal) {
intptr_t PtrWord
= reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal));
- assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
+ assert((PtrWord & ~PointerBitMask) == 0 &&
"Pointer is not sufficiently aligned");
intptr_t IntWord = static_cast<intptr_t>(IntVal);
- assert(IntWord < (1 << IntBits) && "Integer too large for field");
+ assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
Value = PtrWord | (IntWord << IntShift);
}
@@ -158,13 +162,13 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
static Ty getEmptyKey() {
uintptr_t Val = static_cast<uintptr_t>(-1);
- Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
- return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
+ Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
+ return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
}
static Ty getTombstoneKey() {
uintptr_t Val = static_cast<uintptr_t>(-2);
Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
- return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
+ return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
}
static unsigned getHashValue(Ty V) {
uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
index 05d362f..8cbe8d1 100644
--- a/include/llvm/ADT/PointerUnion.h
+++ b/include/llvm/ADT/PointerUnion.h
@@ -15,8 +15,8 @@
#ifndef LLVM_ADT_POINTERUNION_H
#define LLVM_ADT_POINTERUNION_H
-#include "llvm/Support/Compiler.h"
#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
index 8ce4fd5..58ac149 100644
--- a/include/llvm/ADT/SCCIterator.h
+++ b/include/llvm/ADT/SCCIterator.h
@@ -6,16 +6,18 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected
-// components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm.
-//
-// The SCC iterator has the important property that if a node in SCC S1 has an
-// edge to a node in SCC S2, then it visits S1 *after* S2.
-//
-// To visit S1 *before* S2, use the scc_iterator on the Inverse graph.
-// (NOTE: This requires some simple wrappers and is not supported yet.)
-//
+/// \file
+///
+/// This builds on the llvm/ADT/GraphTraits.h file to find the strongly
+/// connected components (SCCs) of a graph in O(N+E) time using Tarjan's DFS
+/// algorithm.
+///
+/// The SCC iterator has the important property that if a node in SCC S1 has an
+/// edge to a node in SCC S2, then it visits S1 *after* S2.
+///
+/// To visit S1 *before* S2, use the scc_iterator on the Inverse graph. (NOTE:
+/// This requires some simple wrappers and is not supported yet.)
+///
//===----------------------------------------------------------------------===//
#ifndef LLVM_ADT_SCCITERATOR_H
@@ -27,90 +29,111 @@
namespace llvm {
-//===----------------------------------------------------------------------===//
+/// \brief Enumerate the SCCs of a directed graph in reverse topological order
+/// of the SCC DAG.
///
-/// scc_iterator - Enumerate the SCCs of a directed graph, in
-/// reverse topological order of the SCC DAG.
-///
-template<class GraphT, class GT = GraphTraits<GraphT> >
+/// This is implemented using Tarjan's DFS algorithm using an internal stack to
+/// build up a vector of nodes in a particular SCC. Note that it is a forward
+/// iterator and thus you cannot backtrack or re-visit nodes.
+template <class GraphT, class GT = GraphTraits<GraphT> >
class scc_iterator
- : public std::iterator<std::forward_iterator_tag,
- std::vector<typename GT::NodeType>, ptrdiff_t> {
- typedef typename GT::NodeType NodeType;
+ : public std::iterator<std::forward_iterator_tag,
+ std::vector<typename GT::NodeType>, ptrdiff_t> {
+ typedef typename GT::NodeType NodeType;
typedef typename GT::ChildIteratorType ChildItTy;
- typedef std::vector<NodeType*> SccTy;
+ typedef std::vector<NodeType *> SccTy;
typedef std::iterator<std::forward_iterator_tag,
std::vector<typename GT::NodeType>, ptrdiff_t> super;
typedef typename super::reference reference;
typedef typename super::pointer pointer;
+ // Element of VisitStack during DFS.
+ struct StackElement {
+ NodeType *Node; ///< The current node pointer.
+ ChildItTy NextChild; ///< The next child, modified inplace during DFS.
+ unsigned MinVisited; ///< Minimum uplink value of all children of Node.
+
+ StackElement(NodeType *Node, const ChildItTy &Child, unsigned Min)
+ : Node(Node), NextChild(Child), MinVisited(Min) {}
+
+ bool operator==(const StackElement &Other) const {
+ return Node == Other.Node &&
+ NextChild == Other.NextChild &&
+ MinVisited == Other.MinVisited;
+ }
+ };
+
// The visit counters used to detect when a complete SCC is on the stack.
// visitNum is the global counter.
// nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
unsigned visitNum;
DenseMap<NodeType *, unsigned> nodeVisitNumbers;
- // SCCNodeStack - Stack holding nodes of the SCC.
+ // Stack holding nodes of the SCC.
std::vector<NodeType *> SCCNodeStack;
- // CurrentSCC - The current SCC, retrieved using operator*().
+ // The current SCC, retrieved using operator*().
SccTy CurrentSCC;
- // VisitStack - Used to maintain the ordering. Top = current block
- // First element is basic block pointer, second is the 'next child' to visit
- std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
- // MinVisitNumStack - Stack holding the "min" values for each node in the DFS.
- // This is used to track the minimum uplink values for all children of
- // the corresponding node on the VisitStack.
- std::vector<unsigned> MinVisitNumStack;
+ // DFS stack, Used to maintain the ordering. The top contains the current
+ // node, the next child to visit, and the minimum uplink value of all child
+ std::vector<StackElement> VisitStack;
// A single "visit" within the non-recursive DFS traversal.
void DFSVisitOne(NodeType *N) {
- ++visitNum; // Global counter for the visit order
+ ++visitNum;
nodeVisitNumbers[N] = visitNum;
SCCNodeStack.push_back(N);
- MinVisitNumStack.push_back(visitNum);
- VisitStack.push_back(std::make_pair(N, GT::child_begin(N)));
- //dbgs() << "TarjanSCC: Node " << N <<
- // " : visitNum = " << visitNum << "\n";
+ VisitStack.push_back(StackElement(N, GT::child_begin(N), visitNum));
+#if 0 // Enable if needed when debugging.
+ dbgs() << "TarjanSCC: Node " << N <<
+ " : visitNum = " << visitNum << "\n";
+#endif
}
// The stack-based DFS traversal; defined below.
void DFSVisitChildren() {
assert(!VisitStack.empty());
- while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+ while (VisitStack.back().NextChild !=
+ GT::child_end(VisitStack.back().Node)) {
// TOS has at least one more child so continue DFS
- NodeType *childN = *VisitStack.back().second++;
- if (!nodeVisitNumbers.count(childN)) {
+ NodeType *childN = *VisitStack.back().NextChild++;
+ typename DenseMap<NodeType *, unsigned>::iterator Visited =
+ nodeVisitNumbers.find(childN);
+ if (Visited == nodeVisitNumbers.end()) {
// this node has never been seen.
DFSVisitOne(childN);
continue;
}
- unsigned childNum = nodeVisitNumbers[childN];
- if (MinVisitNumStack.back() > childNum)
- MinVisitNumStack.back() = childNum;
+ unsigned childNum = Visited->second;
+ if (VisitStack.back().MinVisited > childNum)
+ VisitStack.back().MinVisited = childNum;
}
}
// Compute the next SCC using the DFS traversal.
void GetNextSCC() {
- assert(VisitStack.size() == MinVisitNumStack.size());
- CurrentSCC.clear(); // Prepare to compute the next SCC
+ CurrentSCC.clear(); // Prepare to compute the next SCC
while (!VisitStack.empty()) {
DFSVisitChildren();
- assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first));
- NodeType *visitingN = VisitStack.back().first;
- unsigned minVisitNum = MinVisitNumStack.back();
+
+ // Pop the leaf on top of the VisitStack.
+ NodeType *visitingN = VisitStack.back().Node;
+ unsigned minVisitNum = VisitStack.back().MinVisited;
+ assert(VisitStack.back().NextChild == GT::child_end(visitingN));
VisitStack.pop_back();
- MinVisitNumStack.pop_back();
- if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum)
- MinVisitNumStack.back() = minVisitNum;
- //dbgs() << "TarjanSCC: Popped node " << visitingN <<
- // " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
- // nodeVisitNumbers[visitingN] << "\n";
+ // Propagate MinVisitNum to parent so we can detect the SCC starting node.
+ if (!VisitStack.empty() && VisitStack.back().MinVisited > minVisitNum)
+ VisitStack.back().MinVisited = minVisitNum;
+
+#if 0 // Enable if needed when debugging.
+ dbgs() << "TarjanSCC: Popped node " << visitingN <<
+ " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
+ nodeVisitNumbers[visitingN] << "\n";
+#endif
if (minVisitNum != nodeVisitNumbers[visitingN])
continue;
@@ -132,36 +155,38 @@ class scc_iterator
DFSVisitOne(entryN);
GetNextSCC();
}
- inline scc_iterator() { /* End is when DFS stack is empty */ }
-public:
- typedef scc_iterator<GraphT, GT> _Self;
+ // End is when the DFS stack is empty.
+ inline scc_iterator() {}
- // Provide static "constructors"...
- static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));}
- static inline _Self end (const GraphT &) { return _Self(); }
+public:
+ static inline scc_iterator begin(const GraphT &G) {
+ return scc_iterator(GT::getEntryNode(G));
+ }
+ static inline scc_iterator end(const GraphT &) { return scc_iterator(); }
- // Direct loop termination test: I.isAtEnd() is more efficient than I == end()
+ /// \brief Direct loop termination test which is more efficient than
+ /// comparison with \c end().
inline bool isAtEnd() const {
assert(!CurrentSCC.empty() || VisitStack.empty());
return CurrentSCC.empty();
}
- inline bool operator==(const _Self& x) const {
+ inline bool operator==(const scc_iterator &x) const {
return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
}
- inline bool operator!=(const _Self& x) const { return !operator==(x); }
+ inline bool operator!=(const scc_iterator &x) const { return !operator==(x); }
- // Iterator traversal: forward iteration only
- inline _Self& operator++() { // Preincrement
+ inline scc_iterator &operator++() {
GetNextSCC();
return *this;
}
- inline _Self operator++(int) { // Postincrement
- _Self tmp = *this; ++*this; return tmp;
+ inline scc_iterator operator++(int) {
+ scc_iterator tmp = *this;
+ ++*this;
+ return tmp;
}
- // Retrieve a reference to the current SCC
inline const SccTy &operator*() const {
assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
return CurrentSCC;
@@ -171,21 +196,24 @@ public:
return CurrentSCC;
}
- // hasLoop() -- Test if the current SCC has a loop. If it has more than one
- // node, this is trivially true. If not, it may still contain a loop if the
- // node has an edge back to itself.
+ /// \brief Test if the current SCC has a loop.
+ ///
+ /// If the SCC has more than one node, this is trivially true. If not, it may
+ /// still contain a loop if the node has an edge back to itself.
bool hasLoop() const {
assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
- if (CurrentSCC.size() > 1) return true;
+ if (CurrentSCC.size() > 1)
+ return true;
NodeType *N = CurrentSCC.front();
- for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI)
+ for (ChildItTy CI = GT::child_begin(N), CE = GT::child_end(N); CI != CE;
+ ++CI)
if (*CI == N)
return true;
return false;
}
- /// ReplaceNode - This informs the scc_iterator that the specified Old node
- /// has been deleted, and New is to be used in its place.
+ /// This informs the \c scc_iterator that the specified \c Old node
+ /// has been deleted, and \c New is to be used in its place.
void ReplaceNode(NodeType *Old, NodeType *New) {
assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?");
nodeVisitNumbers[New] = nodeVisitNumbers[Old];
@@ -193,25 +221,23 @@ public:
}
};
-
-// Global constructor for the SCC iterator.
-template <class T>
-scc_iterator<T> scc_begin(const T &G) {
+/// \brief Construct the begin iterator for a deduced graph type T.
+template <class T> scc_iterator<T> scc_begin(const T &G) {
return scc_iterator<T>::begin(G);
}
-template <class T>
-scc_iterator<T> scc_end(const T &G) {
+/// \brief Construct the end iterator for a deduced graph type T.
+template <class T> scc_iterator<T> scc_end(const T &G) {
return scc_iterator<T>::end(G);
}
-template <class T>
-scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) {
+/// \brief Construct the begin iterator for a deduced graph type T's Inverse<T>.
+template <class T> scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) {
return scc_iterator<Inverse<T> >::begin(G);
}
-template <class T>
-scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) {
+/// \brief Construct the end iterator for a deduced graph type T's Inverse<T>.
+template <class T> scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) {
return scc_iterator<Inverse<T> >::end(G);
}
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
index 3aa8183..ab6884f 100644
--- a/include/llvm/ADT/STLExtras.h
+++ b/include/llvm/ADT/STLExtras.h
@@ -17,10 +17,12 @@
#ifndef LLVM_ADT_STLEXTRAS_H
#define LLVM_ADT_STLEXTRAS_H
+#include "llvm/Support/Compiler.h"
#include <cstddef> // for std::size_t
#include <cstdlib> // for qsort
#include <functional>
#include <iterator>
+#include <memory>
#include <utility> // for std::pair
namespace llvm {
@@ -95,8 +97,6 @@ public:
inline explicit mapped_iterator(const RootIt &I, UnaryFunc F)
: current(I), Fn(F) {}
- inline mapped_iterator(const mapped_iterator &It)
- : current(It.current), Fn(It.Fn) {}
inline value_type operator*() const { // All this work to do this
return Fn(*current); // little change
@@ -141,82 +141,10 @@ inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
return mapped_iterator<ItTy, FuncTy>(I, F);
}
-
-// next/prior - These functions unlike std::advance do not modify the
-// passed iterator but return a copy.
-//
-// next(myIt) returns copy of myIt incremented once
-// next(myIt, n) returns copy of myIt incremented n times
-// prior(myIt) returns copy of myIt decremented once
-// prior(myIt, n) returns copy of myIt decremented n times
-
-template <typename ItTy, typename Dist>
-inline ItTy next(ItTy it, Dist n)
-{
- std::advance(it, n);
- return it;
-}
-
-template <typename ItTy>
-inline ItTy next(ItTy it)
-{
- return ++it;
-}
-
-template <typename ItTy, typename Dist>
-inline ItTy prior(ItTy it, Dist n)
-{
- std::advance(it, -n);
- return it;
-}
-
-template <typename ItTy>
-inline ItTy prior(ItTy it)
-{
- return --it;
-}
-
//===----------------------------------------------------------------------===//
// Extra additions to <utility>
//===----------------------------------------------------------------------===//
-// tie - this function ties two objects and returns a temporary object
-// that is assignable from a std::pair. This can be used to make code
-// more readable when using values returned from functions bundled in
-// a std::pair. Since an example is worth 1000 words:
-//
-// typedef std::map<int, int> Int2IntMap;
-//
-// Int2IntMap myMap;
-// Int2IntMap::iterator where;
-// bool inserted;
-// tie(where, inserted) = myMap.insert(std::make_pair(123,456));
-//
-// if (inserted)
-// // do stuff
-// else
-// // do other stuff
-template <typename T1, typename T2>
-struct tier {
- typedef T1 &first_type;
- typedef T2 &second_type;
-
- first_type first;
- second_type second;
-
- tier(first_type f, second_type s) : first(f), second(s) { }
- tier& operator=(const std::pair<T1, T2>& p) {
- first = p.first;
- second = p.second;
- return *this;
- }
-};
-
-template <typename T1, typename T2>
-inline tier<T1, T2> tie(T1& f, T2& s) {
- return tier<T1, T2>(f, s);
-}
-
/// \brief Function object to check whether the first component of a std::pair
/// compares less than the first component of another std::pair.
struct less_first {
@@ -327,6 +255,163 @@ void DeleteContainerSeconds(Container &C) {
C.clear();
}
+//===----------------------------------------------------------------------===//
+// Extra additions to <memory>
+//===----------------------------------------------------------------------===//
+
+#if LLVM_HAS_VARIADIC_TEMPLATES
+
+// Implement make_unique according to N3656.
+
+/// \brief Constructs a `new T()` with the given args and returns a
+/// `unique_ptr<T>` which owns the object.
+///
+/// Example:
+///
+/// auto p = make_unique<int>();
+/// auto p = make_unique<std::tuple<int, int>>(0, 1);
+template <class T, class... Args>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Args &&... args) {
+ return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+/// \brief Constructs a `new T[n]` with the given args and returns a
+/// `unique_ptr<T[]>` which owns the object.
+///
+/// \param n size of the new array.
+///
+/// Example:
+///
+/// auto p = make_unique<int[]>(2); // value-initializes the array with 0's.
+template <class T>
+typename std::enable_if<std::is_array<T>::value && std::extent<T>::value == 0,
+ std::unique_ptr<T>>::type
+make_unique(size_t n) {
+ return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
+}
+
+/// This function isn't used and is only here to provide better compile errors.
+template <class T, class... Args>
+typename std::enable_if<std::extent<T>::value != 0>::type
+make_unique(Args &&...) LLVM_DELETED_FUNCTION;
+
+#else
+
+template <class T>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique() {
+ return std::unique_ptr<T>(new T());
+}
+
+template <class T, class Arg1>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1) {
+ return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1)));
+}
+
+template <class T, class Arg1, class Arg2>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3) {
+ return std::unique_ptr<T>(new T(std::forward<Arg1>(arg1),
+ std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6, class Arg7>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6, Arg7 &&arg7) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+ std::forward<Arg7>(arg7)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6, class Arg7, class Arg8>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+ std::forward<Arg7>(arg7), std::forward<Arg8>(arg8)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6, class Arg7, class Arg8, class Arg9>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+ std::forward<Arg7>(arg7), std::forward<Arg8>(arg8),
+ std::forward<Arg9>(arg9)));
+}
+
+template <class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5,
+ class Arg6, class Arg7, class Arg8, class Arg9, class Arg10>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, Arg4 &&arg4, Arg5 &&arg5,
+ Arg6 &&arg6, Arg7 &&arg7, Arg8 &&arg8, Arg9 &&arg9, Arg10 &&arg10) {
+ return std::unique_ptr<T>(
+ new T(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2),
+ std::forward<Arg3>(arg3), std::forward<Arg4>(arg4),
+ std::forward<Arg5>(arg5), std::forward<Arg6>(arg6),
+ std::forward<Arg7>(arg7), std::forward<Arg8>(arg8),
+ std::forward<Arg9>(arg9), std::forward<Arg10>(arg10)));
+}
+
+template <class T>
+typename std::enable_if<std::is_array<T>::value &&std::extent<T>::value == 0,
+ std::unique_ptr<T>>::type
+make_unique(size_t n) {
+ return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
+}
+
+#endif
+
} // End llvm namespace
#endif
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
index 5eda37c..1e7d237 100644
--- a/include/llvm/ADT/SetVector.h
+++ b/include/llvm/ADT/SetVector.h
@@ -195,11 +195,10 @@ private:
set_type &set_;
public:
- typedef typename UnaryPredicate::argument_type argument_type;
-
TestAndEraseFromSet(UnaryPredicate P, set_type &set_) : P(P), set_(set_) {}
- bool operator()(argument_type Arg) {
+ template <typename ArgumentT>
+ bool operator()(const ArgumentT &Arg) {
if (P(Arg)) {
set_.erase(Arg);
return true;
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index 86949b2..e965bc4 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -153,11 +153,9 @@ public:
switchToLarge(new BitVector(*RHS.getPointer()));
}
-#if LLVM_HAS_RVALUE_REFERENCES
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
RHS.X = 1;
}
-#endif
~SmallBitVector() {
if (!isSmall())
@@ -506,7 +504,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
const SmallBitVector &operator=(SmallBitVector &&RHS) {
if (this != &RHS) {
clear();
@@ -514,7 +511,6 @@ public:
}
return *this;
}
-#endif
void swap(SmallBitVector &RHS) {
std::swap(X, RHS.X);
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index bd0d883..67104f3 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines the SmallPtrSet class. See the doxygen comment for
-// SmallPtrSetImpl for more details on the algorithm used.
+// SmallPtrSetImplBase for more details on the algorithm used.
//
//===----------------------------------------------------------------------===//
@@ -27,7 +27,7 @@ namespace llvm {
class SmallPtrSetIteratorImpl;
-/// SmallPtrSetImpl - This is the common code shared among all the
+/// SmallPtrSetImplBase - This is the common code shared among all the
/// SmallPtrSet<>'s, which is almost everything. SmallPtrSet has two modes, one
/// for small and one for large sets.
///
@@ -45,7 +45,7 @@ class SmallPtrSetIteratorImpl;
/// (-2), to allow deletion. The hash table is resized when the table is 3/4 or
/// more. When this happens, the table is doubled in size.
///
-class SmallPtrSetImpl {
+class SmallPtrSetImplBase {
friend class SmallPtrSetIteratorImpl;
protected:
/// SmallArray - Points to a fixed size set of buckets, used in 'small mode'.
@@ -60,15 +60,17 @@ protected:
unsigned NumElements;
unsigned NumTombstones;
- // Helper to copy construct a SmallPtrSet.
- SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl& that);
- explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize) :
+ // Helpers to copy and move construct a SmallPtrSet.
+ SmallPtrSetImplBase(const void **SmallStorage, const SmallPtrSetImplBase &that);
+ SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
+ SmallPtrSetImplBase &&that);
+ explicit SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize) :
SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
"Initial size must be a power of two!");
clear();
}
- ~SmallPtrSetImpl();
+ ~SmallPtrSetImplBase();
public:
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; }
@@ -128,13 +130,14 @@ private:
/// Grow - Allocate a larger backing store for the buckets and move it over.
void Grow(unsigned NewSize);
- void operator=(const SmallPtrSetImpl &RHS) LLVM_DELETED_FUNCTION;
+ void operator=(const SmallPtrSetImplBase &RHS) LLVM_DELETED_FUNCTION;
protected:
/// swap - Swaps the elements of two sets.
/// Note: This method assumes that both sets have the same small size.
- void swap(SmallPtrSetImpl &RHS);
+ void swap(SmallPtrSetImplBase &RHS);
- void CopyFrom(const SmallPtrSetImpl &RHS);
+ void CopyFrom(const SmallPtrSetImplBase &RHS);
+ void MoveFrom(unsigned SmallSize, SmallPtrSetImplBase &&RHS);
};
/// SmallPtrSetIteratorImpl - This is the common base class shared between all
@@ -163,8 +166,8 @@ protected:
void AdvanceIfNotValid() {
assert(Bucket <= End);
while (Bucket != End &&
- (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
- *Bucket == SmallPtrSetImpl::getTombstoneMarker()))
+ (*Bucket == SmallPtrSetImplBase::getEmptyMarker() ||
+ *Bucket == SmallPtrSetImplBase::getTombstoneMarker()))
++Bucket;
}
};
@@ -228,26 +231,25 @@ struct RoundUpToPowerOfTwo {
};
-/// SmallPtrSet - This class implements a set which is optimized for holding
-/// SmallSize or less elements. This internally rounds up SmallSize to the next
-/// power of two if it is not already a power of two. See the comments above
-/// SmallPtrSetImpl for details of the algorithm.
-template<class PtrType, unsigned SmallSize>
-class SmallPtrSet : public SmallPtrSetImpl {
- // Make sure that SmallSize is a power of two, round up if not.
- enum { SmallSizePowTwo = RoundUpToPowerOfTwo<SmallSize>::Val };
- /// SmallStorage - Fixed size storage used in 'small mode'.
- const void *SmallStorage[SmallSizePowTwo];
+/// \brief A templated base class for \c SmallPtrSet which provides the
+/// typesafe interface that is common across all small sizes.
+///
+/// This is particularly useful for passing around between interface boundaries
+/// to avoid encoding a particular small size in the interface boundary.
+template <typename PtrType>
+class SmallPtrSetImpl : public SmallPtrSetImplBase {
typedef PointerLikeTypeTraits<PtrType> PtrTraits;
-public:
- SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
- SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(SmallStorage, that) {}
-
- template<typename It>
- SmallPtrSet(It I, It E) : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {
- insert(I, E);
- }
+protected:
+ // Constructors that forward to the base.
+ SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that)
+ : SmallPtrSetImplBase(SmallStorage, that) {}
+ SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize,
+ SmallPtrSetImpl &&that)
+ : SmallPtrSetImplBase(SmallStorage, SmallSize, std::move(that)) {}
+ explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize)
+ : SmallPtrSetImplBase(SmallStorage, SmallSize) {}
+public:
/// insert - This returns true if the pointer was new to the set, false if it
/// was already in the set.
bool insert(PtrType Ptr) {
@@ -260,9 +262,9 @@ public:
return erase_imp(PtrTraits::getAsVoidPointer(Ptr));
}
- /// count - Return true if the specified pointer is in the set.
- bool count(PtrType Ptr) const {
- return count_imp(PtrTraits::getAsVoidPointer(Ptr));
+ /// count - Return 1 if the specified pointer is in the set, 0 otherwise.
+ unsigned count(PtrType Ptr) const {
+ return count_imp(PtrTraits::getAsVoidPointer(Ptr)) ? 1 : 0;
}
template <typename IterT>
@@ -279,18 +281,48 @@ public:
inline iterator end() const {
return iterator(CurArray+CurArraySize, CurArray+CurArraySize);
}
+};
- // Allow assignment from any smallptrset with the same element type even if it
- // doesn't have the same smallsize.
- const SmallPtrSet<PtrType, SmallSize>&
+/// SmallPtrSet - This class implements a set which is optimized for holding
+/// SmallSize or less elements. This internally rounds up SmallSize to the next
+/// power of two if it is not already a power of two. See the comments above
+/// SmallPtrSetImplBase for details of the algorithm.
+template<class PtrType, unsigned SmallSize>
+class SmallPtrSet : public SmallPtrSetImpl<PtrType> {
+ typedef SmallPtrSetImpl<PtrType> BaseT;
+
+ // Make sure that SmallSize is a power of two, round up if not.
+ 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) {}
+ SmallPtrSet(SmallPtrSet &&that)
+ : BaseT(SmallStorage, SmallSizePowTwo, std::move(that)) {}
+
+ template<typename It>
+ SmallPtrSet(It I, It E) : BaseT(SmallStorage, SmallSizePowTwo) {
+ this->insert(I, E);
+ }
+
+ SmallPtrSet<PtrType, SmallSize> &
operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
- CopyFrom(RHS);
+ if (&RHS != this)
+ this->CopyFrom(RHS);
+ return *this;
+ }
+
+ SmallPtrSet<PtrType, SmallSize>&
+ operator=(SmallPtrSet<PtrType, SmallSize> &&RHS) {
+ if (&RHS != this)
+ this->MoveFrom(SmallSizePowTwo, std::move(RHS));
return *this;
}
/// swap - Swaps the elements of two sets.
void swap(SmallPtrSet<PtrType, SmallSize> &RHS) {
- SmallPtrSetImpl::swap(RHS);
+ SmallPtrSetImplBase::swap(RHS);
}
};
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
index 5dfe924..6f36234 100644
--- a/include/llvm/ADT/SmallSet.h
+++ b/include/llvm/ADT/SmallSet.h
@@ -39,16 +39,19 @@ class SmallSet {
public:
SmallSet() {}
- bool empty() const { return Vector.empty() && Set.empty(); }
+ bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
+ return Vector.empty() && Set.empty();
+ }
+
unsigned size() const {
return isSmall() ? Vector.size() : Set.size();
}
- /// count - Return true if the element is in the set.
- bool count(const T &V) const {
+ /// count - Return 1 if the element is in the set, 0 otherwise.
+ unsigned count(const T &V) const {
if (isSmall()) {
// Since the collection is small, just do a linear search.
- return vfind(V) != Vector.end();
+ return vfind(V) == Vector.end() ? 0 : 1;
} else {
return Set.count(V);
}
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
index 2cfb5b9..e569f54 100644
--- a/include/llvm/ADT/SmallString.h
+++ b/include/llvm/ADT/SmallString.h
@@ -34,9 +34,6 @@ public:
template<typename ItTy>
SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
- /// Copy ctor.
- SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {}
-
// Note that in order to add new overloads for append & assign, we have to
// duplicate the inherited versions so as not to inadvertently hide them.
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 505aa8d..0a4140e 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -14,6 +14,7 @@
#ifndef LLVM_ADT_SMALLVECTOR_H
#define LLVM_ADT_SMALLVECTOR_H
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
@@ -183,13 +184,9 @@ protected:
/// std::move, but not all stdlibs actually provide that.
template<typename It1, typename It2>
static It2 move(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
for (; I != E; ++I, ++Dest)
*Dest = ::std::move(*I);
return Dest;
-#else
- return ::std::copy(I, E, Dest);
-#endif
}
/// move_backward - Use move-assignment to move the range
@@ -198,25 +195,17 @@ protected:
/// std::move_backward, but not all stdlibs actually provide that.
template<typename It1, typename It2>
static It2 move_backward(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
while (I != E)
*--Dest = ::std::move(*--E);
return Dest;
-#else
- return ::std::copy_backward(I, E, Dest);
-#endif
}
/// uninitialized_move - Move the range [I, E) into the uninitialized
/// memory starting with "Dest", constructing elements as needed.
template<typename It1, typename It2>
static void uninitialized_move(It1 I, It1 E, It2 Dest) {
-#if LLVM_HAS_RVALUE_REFERENCES
for (; I != E; ++I, ++Dest)
::new ((void*) &*Dest) T(::std::move(*I));
-#else
- ::std::uninitialized_copy(I, E, Dest);
-#endif
}
/// uninitialized_copy - Copy the range [I, E) onto the uninitialized
@@ -244,7 +233,6 @@ public:
goto Retry;
}
-#if LLVM_HAS_RVALUE_REFERENCES
void push_back(T &&Elt) {
if (this->EndX < this->CapacityX) {
Retry:
@@ -255,8 +243,7 @@ public:
this->grow();
goto Retry;
}
-#endif
-
+
void pop_back() {
this->setEnd(this->end()-1);
this->end()->~T();
@@ -428,11 +415,7 @@ public:
}
T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() {
-#if LLVM_HAS_RVALUE_REFERENCES
T Result = ::std::move(this->back());
-#else
- T Result = this->back();
-#endif
this->pop_back();
return Result;
}
@@ -501,7 +484,6 @@ public:
return(N);
}
-#if LLVM_HAS_RVALUE_REFERENCES
iterator insert(iterator I, T &&Elt) {
if (I == this->end()) { // Important special case for empty vector.
this->push_back(::std::move(Elt));
@@ -532,7 +514,6 @@ public:
I = this->begin()+EltNo;
goto Retry;
}
-#endif
iterator insert(iterator I, const T &Elt) {
if (I == this->end()) { // Important special case for empty vector.
@@ -673,9 +654,7 @@ public:
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
-#if LLVM_HAS_RVALUE_REFERENCES
SmallVectorImpl &operator=(SmallVectorImpl &&RHS);
-#endif
bool operator==(const SmallVectorImpl &RHS) const {
if (this->size() != RHS.size()) return false;
@@ -793,7 +772,6 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
template <typename T>
SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
// Avoid self-assignment.
@@ -855,7 +833,6 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
RHS.clear();
return *this;
}
-#endif
/// Storage for the SmallVector elements which aren't contained in
/// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
@@ -894,6 +871,12 @@ public:
this->append(S, E);
}
+ template <typename RangeTy>
+ explicit SmallVector(const llvm::iterator_range<RangeTy> R)
+ : SmallVectorImpl<T>(N) {
+ this->append(R.begin(), R.end());
+ }
+
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(RHS);
@@ -904,7 +887,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
SmallVector(SmallVector &&RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(::std::move(RHS));
@@ -914,8 +896,6 @@ public:
SmallVectorImpl<T>::operator=(::std::move(RHS));
return *this;
}
-#endif
-
};
template<typename T, unsigned N>
diff --git a/include/llvm/ADT/SparseBitVector.h b/include/llvm/ADT/SparseBitVector.h
index 7a10f85..706f248 100644
--- a/include/llvm/ADT/SparseBitVector.h
+++ b/include/llvm/ADT/SparseBitVector.h
@@ -382,7 +382,7 @@ class SparseBitVector {
AtEnd = true;
return;
}
- // Set up for next non zero word in bitmap.
+ // Set up for next non-zero word in bitmap.
BitNumber = Iter->index() * ElementSize;
NextSetBitNumber = Iter->find_first();
BitNumber += NextSetBitNumber;
diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h
index 7f2a6f7..797a898 100644
--- a/include/llvm/ADT/SparseMultiSet.h
+++ b/include/llvm/ADT/SparseMultiSet.h
@@ -76,6 +76,10 @@ template<typename ValueT,
typename KeyFunctorT = llvm::identity<unsigned>,
typename SparseT = uint8_t>
class SparseMultiSet {
+ static_assert(std::numeric_limits<SparseT>::is_integer &&
+ !std::numeric_limits<SparseT>::is_signed,
+ "SparseT must be an unsigned integer type");
+
/// The actual data that's stored, as a doubly-linked list implemented via
/// indices into the DenseVector. The doubly linked list is implemented
/// circular in Prev indices, and INVALID-terminated in Next indices. This
@@ -245,16 +249,6 @@ public:
typedef typename super::pointer pointer;
typedef typename super::reference reference;
- iterator_base(const iterator_base &RHS)
- : SMS(RHS.SMS), Idx(RHS.Idx), SparseIdx(RHS.SparseIdx) { }
-
- const iterator_base &operator=(const iterator_base &RHS) {
- SMS = RHS.SMS;
- Idx = RHS.Idx;
- SparseIdx = RHS.SparseIdx;
- return *this;
- }
-
reference operator*() const {
assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
"Dereferencing iterator of invalid key or index");
@@ -354,9 +348,6 @@ public:
///
iterator findIndex(unsigned Idx) {
assert(Idx < Universe && "Key out of range");
- assert(std::numeric_limits<SparseT>::is_integer &&
- !std::numeric_limits<SparseT>::is_signed &&
- "SparseT must be an unsigned integer type");
const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
for (unsigned i = Sparse[Idx], e = Dense.size(); i < e; i += Stride) {
const unsigned FoundIdx = sparseIndex(Dense[i]);
diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h
index 267a340..b46ccc9 100644
--- a/include/llvm/ADT/SparseSet.h
+++ b/include/llvm/ADT/SparseSet.h
@@ -118,6 +118,10 @@ template<typename ValueT,
typename KeyFunctorT = llvm::identity<unsigned>,
typename SparseT = uint8_t>
class SparseSet {
+ static_assert(std::numeric_limits<SparseT>::is_integer &&
+ !std::numeric_limits<SparseT>::is_signed,
+ "SparseT must be an unsigned integer type");
+
typedef typename KeyFunctorT::argument_type KeyT;
typedef SmallVector<ValueT, 8> DenseT;
DenseT Dense;
@@ -198,9 +202,6 @@ public:
///
iterator findIndex(unsigned Idx) {
assert(Idx < Universe && "Key out of range");
- assert(std::numeric_limits<SparseT>::is_integer &&
- !std::numeric_limits<SparseT>::is_signed &&
- "SparseT must be an unsigned integer type");
const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
for (unsigned i = Sparse[Idx], e = size(); i < e; i += Stride) {
const unsigned FoundIdx = ValIndexOf(Dense[i]);
@@ -227,10 +228,11 @@ public:
return const_cast<SparseSet*>(this)->findIndex(KeyIndexOf(Key));
}
- /// count - Returns true if this set contains an element identified by Key.
+ /// count - Returns 1 if this set contains an element identified by Key,
+ /// 0 otherwise.
///
- bool count(const KeyT &Key) const {
- return find(Key) != end();
+ unsigned count(const KeyT &Key) const {
+ return find(Key) == end() ? 0 : 1;
}
/// insert - Attempts to insert a new element.
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index 56dbb5b..a0b3fe7 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -14,9 +14,9 @@
#ifndef LLVM_ADT_STRINGEXTRAS_H
#define LLVM_ADT_STRINGEXTRAS_H
-#include <iterator>
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
+#include <iterator>
namespace llvm {
template<typename T> class SmallVectorImpl;
@@ -28,6 +28,11 @@ static inline char hexdigit(unsigned X, bool LowerCase = false) {
return X < 10 ? '0' + X : HexChar + X - 10;
}
+/// Construct a string ref from a boolean.
+static inline StringRef toStringRef(bool B) {
+ return StringRef(B ? "true" : "false");
+}
+
/// Interpret the given character \p C as a hexadecimal digit and return its
/// value.
///
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index 0838ebe..4e74cf6 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -26,19 +26,6 @@ namespace llvm {
template<typename ValueTy>
class StringMapEntry;
-/// StringMapEntryInitializer - This datatype can be partially specialized for
-/// various datatypes in a stringmap to allow them to be initialized when an
-/// entry is default constructed for the map.
-template<typename ValueTy>
-class StringMapEntryInitializer {
-public:
- template <typename InitTy>
- static void Initialize(StringMapEntry<ValueTy> &T, InitTy InitVal) {
- T.second = InitVal;
- }
-};
-
-
/// StringMapEntryBase - Shared base class of StringMapEntry instances.
class StringMapEntryBase {
unsigned StrLen;
@@ -149,10 +136,8 @@ public:
InitType InitVal) {
unsigned KeyLength = static_cast<unsigned>(KeyEnd-KeyStart);
- // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill
- // in. Allocate a new item with space for the string at the end and a null
+ // Allocate a new item with space for the string at the end and a null
// terminator.
-
unsigned AllocSize = static_cast<unsigned>(sizeof(StringMapEntry))+
KeyLength+1;
unsigned Alignment = alignOf<StringMapEntry>();
@@ -161,15 +146,12 @@ public:
static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
// Default construct the value.
- new (NewItem) StringMapEntry(KeyLength);
+ new (NewItem) StringMapEntry(KeyLength, InitVal);
// Copy the string information.
char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
memcpy(StrBuffer, KeyStart, KeyLength);
StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
-
- // Initialize the value if the client wants to.
- StringMapEntryInitializer<ValueTy>::Initialize(*NewItem, InitVal);
return NewItem;
}
@@ -313,6 +295,7 @@ public:
return GetOrCreateValue(Key).getValue();
}
+ /// count - Return 1 if the element is in the map, 0 otherwise.
size_type count(StringRef Key) const {
return find(Key) == end() ? 0 : 1;
}
@@ -404,7 +387,17 @@ public:
}
~StringMap() {
- clear();
+ // Delete all the elements in the map, but don't reset the elements
+ // to default values. This is a copy of clear(), but avoids unnecessary
+ // work not required in the destructor.
+ if (!empty()) {
+ for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
+ StringMapEntryBase *Bucket = TheTable[I];
+ if (Bucket && Bucket != getTombstoneVal()) {
+ static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
+ }
+ }
+ }
free(TheTable);
}
};
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index ec0c284..0514d7b 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -10,7 +10,7 @@
#ifndef LLVM_ADT_STRINGREF_H
#define LLVM_ADT_STRINGREF_H
-#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Allocator.h"
#include <algorithm>
#include <cassert>
#include <cstring>
@@ -124,6 +124,13 @@ namespace llvm {
return Data[Length-1];
}
+ // copy - Allocate copy in BumpPtrAllocator and return StringRef to it.
+ StringRef copy(BumpPtrAllocator &Allocator) {
+ char *S = Allocator.Allocate<char>(Length);
+ std::copy(begin(), end(), S);
+ return StringRef(S, Length);
+ }
+
/// equals - Check for string equality, this is more efficient than
/// compare() when the relative ordering of inequal strings isn't needed.
bool equals(StringRef RHS) const {
@@ -333,7 +340,7 @@ namespace llvm {
/// this returns true to signify the error. The string is considered
/// erroneous if empty or if it overflows T.
template <typename T>
- typename enable_if_c<std::numeric_limits<T>::is_signed, bool>::type
+ typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
long long LLVal;
if (getAsSignedInteger(*this, Radix, LLVal) ||
@@ -344,7 +351,7 @@ namespace llvm {
}
template <typename T>
- typename enable_if_c<!std::numeric_limits<T>::is_signed, bool>::type
+ typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
getAsInteger(unsigned Radix, T &Result) const {
unsigned long long ULLVal;
if (getAsUnsignedInteger(*this, Radix, ULLVal) ||
@@ -553,11 +560,6 @@ namespace llvm {
// StringRefs can be treated like a POD type.
template <typename T> struct isPodLike;
template <> struct isPodLike<StringRef> { static const bool value = true; };
-
- /// Construct a string ref from a boolean.
- inline StringRef toStringRef(bool B) {
- return StringRef(B ? "true" : "false");
- }
}
#endif
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
index cc0e7b6..1df8d66 100644
--- a/include/llvm/ADT/TinyPtrVector.h
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -12,9 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Compiler.h"
namespace llvm {
@@ -70,7 +68,6 @@ public:
return *this;
}
-#if LLVM_HAS_RVALUE_REFERENCES
TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
RHS.Val = (EltTy)0;
}
@@ -98,7 +95,6 @@ public:
RHS.Val = (EltTy)0;
return *this;
}
-#endif
// implicit conversion operator to ArrayRef.
operator ArrayRef<EltTy>() const {
@@ -250,7 +246,7 @@ public:
assert(I <= this->end() && "Inserting past the end of the vector.");
if (I == end()) {
push_back(Elt);
- return llvm::prior(end());
+ return std::prev(end());
}
assert(!Val.isNull() && "Null value with non-end insert iterator.");
if (EltTy V = Val.template dyn_cast<EltTy>()) {
@@ -273,7 +269,7 @@ public:
// If we have a single value, convert to a vector.
ptrdiff_t Offset = I - begin();
if (Val.isNull()) {
- if (llvm::next(From) == To) {
+ if (std::next(From) == To) {
Val = *From;
return begin();
}
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 84e0b29..185003d 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -46,32 +46,36 @@ public:
enum ArchType {
UnknownArch,
- arm, // ARM: arm, armv.*, xscale
- aarch64, // AArch64: aarch64
- hexagon, // Hexagon: hexagon
- mips, // MIPS: mips, mipsallegrex
- mipsel, // MIPSEL: mipsel, mipsallegrexel
- mips64, // MIPS64: mips64
- mips64el,// MIPS64EL: mips64el
- msp430, // MSP430: msp430
- ppc, // PPC: powerpc
- ppc64, // PPC64: powerpc64, ppu
- ppc64le, // PPC64LE: powerpc64le
- r600, // R600: AMD GPUs HD2XXX - HD6XXX
- sparc, // Sparc: sparc
- sparcv9, // Sparcv9: Sparcv9
- systemz, // SystemZ: s390x
- tce, // TCE (http://tce.cs.tut.fi/): tce
- thumb, // Thumb: thumb, thumbv.*
- x86, // X86: i[3-9]86
- x86_64, // X86-64: amd64, x86_64
- xcore, // XCore: xcore
- nvptx, // NVPTX: 32-bit
- nvptx64, // NVPTX: 64-bit
- le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
- amdil, // amdil: amd IL
- spir, // SPIR: standard portable IR for OpenCL 32-bit version
- spir64 // SPIR: standard portable IR for OpenCL 64-bit version
+ arm, // ARM (little endian): arm, armv.*, xscale
+ armeb, // ARM (big endian): armeb
+ arm64, // ARM: arm64
+ aarch64, // AArch64 (little endian): aarch64
+ aarch64_be, // AArch64 (big endian): aarch64_be
+ hexagon, // Hexagon: hexagon
+ mips, // MIPS: mips, mipsallegrex
+ mipsel, // MIPSEL: mipsel, mipsallegrexel
+ mips64, // MIPS64: mips64
+ mips64el, // MIPS64EL: mips64el
+ msp430, // MSP430: msp430
+ ppc, // PPC: powerpc
+ ppc64, // PPC64: powerpc64, ppu
+ ppc64le, // PPC64LE: powerpc64le
+ r600, // R600: AMD GPUs HD2XXX - HD6XXX
+ sparc, // Sparc: sparc
+ sparcv9, // Sparcv9: Sparcv9
+ systemz, // SystemZ: s390x
+ tce, // TCE (http://tce.cs.tut.fi/): tce
+ thumb, // Thumb (little endian): thumb, thumbv.*
+ thumbeb, // Thumb (big endian): thumbeb
+ x86, // X86: i[3-9]86
+ x86_64, // X86-64: amd64, x86_64
+ xcore, // XCore: xcore
+ nvptx, // NVPTX: 32-bit
+ nvptx64, // NVPTX: 64-bit
+ le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
+ amdil, // amdil: amd IL
+ spir, // SPIR: standard portable IR for OpenCL 32-bit version
+ spir64 // SPIR: standard portable IR for OpenCL 64-bit version
};
enum VendorType {
UnknownVendor,
@@ -120,10 +124,21 @@ public:
GNUEABI,
GNUEABIHF,
GNUX32,
+ CODE16,
EABI,
- MachO,
+ EABIHF,
Android,
- ELF
+
+ MSVC,
+ Itanium,
+ Cygnus,
+ };
+ enum ObjectFormatType {
+ UnknownObjectFormat,
+
+ COFF,
+ ELF,
+ MachO,
};
private:
@@ -141,13 +156,16 @@ private:
/// The parsed Environment type.
EnvironmentType Environment;
+ /// The object format type.
+ ObjectFormatType ObjectFormat;
+
public:
/// @name Constructors
/// @{
/// \brief Default constructor is the same as an empty string and leaves all
/// triple fields unknown.
- Triple() : Data(), Arch(), Vendor(), OS(), Environment() {}
+ Triple() : Data(), Arch(), Vendor(), OS(), Environment(), ObjectFormat() {}
explicit Triple(const Twine &Str);
Triple(const Twine &ArchStr, const Twine &VendorStr, const Twine &OSStr);
@@ -186,6 +204,9 @@ public:
/// getEnvironment - Get the parsed environment type of this triple.
EnvironmentType getEnvironment() const { return Environment; }
+ /// getFormat - Get the object format for this triple.
+ ObjectFormatType getObjectFormat() const { return ObjectFormat; }
+
/// getOSVersion - Parse the version number from the OS name component of the
/// triple, if present.
///
@@ -314,9 +335,29 @@ public:
return isMacOSX() || isiOS();
}
+ bool isWindowsMSVCEnvironment() const {
+ return getOS() == Triple::Win32 &&
+ (getEnvironment() == Triple::UnknownEnvironment ||
+ getEnvironment() == Triple::MSVC);
+ }
+
+ bool isKnownWindowsMSVCEnvironment() const {
+ return getOS() == Triple::Win32 && getEnvironment() == Triple::MSVC;
+ }
+
+ bool isWindowsCygwinEnvironment() const {
+ return getOS() == Triple::Cygwin ||
+ (getOS() == Triple::Win32 && getEnvironment() == Triple::Cygnus);
+ }
+
+ bool isWindowsGNUEnvironment() const {
+ return getOS() == Triple::MinGW32 ||
+ (getOS() == Triple::Win32 && getEnvironment() == Triple::GNU);
+ }
+
/// \brief Tests for either Cygwin or MinGW OS
bool isOSCygMing() const {
- return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32;
+ return isWindowsCygwinEnvironment() || isWindowsGNUEnvironment();
}
/// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment.
@@ -341,18 +382,17 @@ public:
/// \brief Tests whether the OS uses the ELF binary format.
bool isOSBinFormatELF() const {
- return !isOSDarwin() && !isOSWindows();
+ return getObjectFormat() == Triple::ELF;
}
/// \brief Tests whether the OS uses the COFF binary format.
bool isOSBinFormatCOFF() const {
- return isOSWindows();
+ return getObjectFormat() == Triple::COFF;
}
/// \brief Tests whether the environment is MachO.
- // FIXME: Should this be an OSBinFormat predicate?
- bool isEnvironmentMachO() const {
- return getEnvironment() == Triple::MachO || isOSDarwin();
+ bool isOSBinFormatMachO() const {
+ return getObjectFormat() == Triple::MachO;
}
/// @}
@@ -375,6 +415,9 @@ public:
/// to a known type.
void setEnvironment(EnvironmentType Kind);
+ /// setObjectFormat - Set the object file format
+ void setObjectFormat(ObjectFormatType Kind);
+
/// setTriple - Set all components to the new triple \p Str.
void setTriple(const Twine &Str);
diff --git a/include/llvm/ADT/ValueMap.h b/include/llvm/ADT/ValueMap.h
deleted file mode 100644
index b4fed7a..0000000
--- a/include/llvm/ADT/ValueMap.h
+++ /dev/null
@@ -1,377 +0,0 @@
-//===- llvm/ADT/ValueMap.h - Safe map from Values to data -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the ValueMap class. ValueMap maps Value* or any subclass
-// to an arbitrary other type. It provides the DenseMap interface but updates
-// itself to remain safe when keys are RAUWed or deleted. By default, when a
-// key is RAUWed from V1 to V2, the old mapping V1->target is removed, and a new
-// mapping V2->target is added. If V2 already existed, its old target is
-// overwritten. When a key is deleted, its mapping is removed.
-//
-// You can override a ValueMap's Config parameter to control exactly what
-// happens on RAUW and destruction and to get called back on each event. It's
-// legal to call back into the ValueMap from a Config's callbacks. Config
-// parameters should inherit from ValueMapConfig<KeyT> to get default
-// implementations of all the methods ValueMap uses. See ValueMapConfig for
-// documentation of the functions you can override.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_VALUEMAP_H
-#define LLVM_ADT_VALUEMAP_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/Mutex.h"
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/Support/type_traits.h"
-#include <iterator>
-
-namespace llvm {
-
-template<typename KeyT, typename ValueT, typename Config>
-class ValueMapCallbackVH;
-
-template<typename DenseMapT, typename KeyT>
-class ValueMapIterator;
-template<typename DenseMapT, typename KeyT>
-class ValueMapConstIterator;
-
-/// This class defines the default behavior for configurable aspects of
-/// ValueMap<>. User Configs should inherit from this class to be as compatible
-/// as possible with future versions of ValueMap.
-template<typename KeyT>
-struct ValueMapConfig {
- /// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
- /// false, the ValueMap will leave the original mapping in place.
- enum { FollowRAUW = true };
-
- // All methods will be called with a first argument of type ExtraData. The
- // default implementations in this class take a templated first argument so
- // that users' subclasses can use any type they want without having to
- // override all the defaults.
- struct ExtraData {};
-
- template<typename ExtraDataT>
- static void onRAUW(const ExtraDataT & /*Data*/, KeyT /*Old*/, KeyT /*New*/) {}
- template<typename ExtraDataT>
- static void onDelete(const ExtraDataT &/*Data*/, KeyT /*Old*/) {}
-
- /// Returns a mutex that should be acquired around any changes to the map.
- /// This is only acquired from the CallbackVH (and held around calls to onRAUW
- /// and onDelete) and not inside other ValueMap methods. NULL means that no
- /// mutex is necessary.
- template<typename ExtraDataT>
- static sys::Mutex *getMutex(const ExtraDataT &/*Data*/) { return NULL; }
-};
-
-/// See the file comment.
-template<typename KeyT, typename ValueT, typename Config =ValueMapConfig<KeyT> >
-class ValueMap {
- friend class ValueMapCallbackVH<KeyT, ValueT, Config>;
- typedef ValueMapCallbackVH<KeyT, ValueT, Config> ValueMapCVH;
- typedef DenseMap<ValueMapCVH, ValueT, DenseMapInfo<ValueMapCVH> > MapT;
- typedef typename Config::ExtraData ExtraData;
- MapT Map;
- ExtraData Data;
- ValueMap(const ValueMap&) LLVM_DELETED_FUNCTION;
- ValueMap& operator=(const ValueMap&) LLVM_DELETED_FUNCTION;
-public:
- typedef KeyT key_type;
- typedef ValueT mapped_type;
- typedef std::pair<KeyT, ValueT> value_type;
-
- explicit ValueMap(unsigned NumInitBuckets = 64)
- : Map(NumInitBuckets), Data() {}
- explicit ValueMap(const ExtraData &Data, unsigned NumInitBuckets = 64)
- : Map(NumInitBuckets), Data(Data) {}
-
- ~ValueMap() {}
-
- typedef ValueMapIterator<MapT, KeyT> iterator;
- typedef ValueMapConstIterator<MapT, KeyT> const_iterator;
- inline iterator begin() { return iterator(Map.begin()); }
- inline iterator end() { return iterator(Map.end()); }
- inline const_iterator begin() const { return const_iterator(Map.begin()); }
- inline const_iterator end() const { return const_iterator(Map.end()); }
-
- bool empty() const { return Map.empty(); }
- unsigned size() const { return Map.size(); }
-
- /// Grow the map so that it has at least Size buckets. Does not shrink
- void resize(size_t Size) { Map.resize(Size); }
-
- void clear() { Map.clear(); }
-
- /// count - Return true if the specified key is in the map.
- bool count(const KeyT &Val) const {
- return Map.find_as(Val) != Map.end();
- }
-
- iterator find(const KeyT &Val) {
- return iterator(Map.find_as(Val));
- }
- const_iterator find(const KeyT &Val) const {
- return const_iterator(Map.find_as(Val));
- }
-
- /// lookup - Return the entry for the specified key, or a default
- /// constructed value if no such entry exists.
- ValueT lookup(const KeyT &Val) const {
- typename MapT::const_iterator I = Map.find_as(Val);
- return I != Map.end() ? I->second : ValueT();
- }
-
- // Inserts key,value pair into the map if the key isn't already in the map.
- // If the key is already in the map, it returns false and doesn't update the
- // value.
- std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
- std::pair<typename MapT::iterator, bool> map_result=
- Map.insert(std::make_pair(Wrap(KV.first), KV.second));
- return std::make_pair(iterator(map_result.first), map_result.second);
- }
-
- /// insert - Range insertion of pairs.
- template<typename InputIt>
- void insert(InputIt I, InputIt E) {
- for (; I != E; ++I)
- insert(*I);
- }
-
-
- bool erase(const KeyT &Val) {
- typename MapT::iterator I = Map.find_as(Val);
- if (I == Map.end())
- return false;
-
- Map.erase(I);
- return true;
- }
- void erase(iterator I) {
- return Map.erase(I.base());
- }
-
- value_type& FindAndConstruct(const KeyT &Key) {
- return Map.FindAndConstruct(Wrap(Key));
- }
-
- ValueT &operator[](const KeyT &Key) {
- return Map[Wrap(Key)];
- }
-
- /// isPointerIntoBucketsArray - Return true if the specified pointer points
- /// somewhere into the ValueMap's array of buckets (i.e. either to a key or
- /// value in the ValueMap).
- bool isPointerIntoBucketsArray(const void *Ptr) const {
- return Map.isPointerIntoBucketsArray(Ptr);
- }
-
- /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
- /// array. In conjunction with the previous method, this can be used to
- /// determine whether an insertion caused the ValueMap to reallocate.
- const void *getPointerIntoBucketsArray() const {
- return Map.getPointerIntoBucketsArray();
- }
-
-private:
- // Takes a key being looked up in the map and wraps it into a
- // ValueMapCallbackVH, the actual key type of the map. We use a helper
- // function because ValueMapCVH is constructed with a second parameter.
- ValueMapCVH Wrap(KeyT key) const {
- // The only way the resulting CallbackVH could try to modify *this (making
- // the const_cast incorrect) is if it gets inserted into the map. But then
- // this function must have been called from a non-const method, making the
- // const_cast ok.
- return ValueMapCVH(key, const_cast<ValueMap*>(this));
- }
-};
-
-// This CallbackVH updates its ValueMap when the contained Value changes,
-// according to the user's preferences expressed through the Config object.
-template<typename KeyT, typename ValueT, typename Config>
-class ValueMapCallbackVH : public CallbackVH {
- friend class ValueMap<KeyT, ValueT, Config>;
- friend struct DenseMapInfo<ValueMapCallbackVH>;
- typedef ValueMap<KeyT, ValueT, Config> ValueMapT;
- typedef typename llvm::remove_pointer<KeyT>::type KeySansPointerT;
-
- ValueMapT *Map;
-
- ValueMapCallbackVH(KeyT Key, ValueMapT *Map)
- : CallbackVH(const_cast<Value*>(static_cast<const Value*>(Key))),
- Map(Map) {}
-
-public:
- KeyT Unwrap() const { return cast_or_null<KeySansPointerT>(getValPtr()); }
-
- virtual void deleted() {
- // Make a copy that won't get changed even when *this is destroyed.
- ValueMapCallbackVH Copy(*this);
- sys::Mutex *M = Config::getMutex(Copy.Map->Data);
- if (M)
- M->acquire();
- Config::onDelete(Copy.Map->Data, Copy.Unwrap()); // May destroy *this.
- Copy.Map->Map.erase(Copy); // Definitely destroys *this.
- if (M)
- M->release();
- }
- virtual void allUsesReplacedWith(Value *new_key) {
- assert(isa<KeySansPointerT>(new_key) &&
- "Invalid RAUW on key of ValueMap<>");
- // Make a copy that won't get changed even when *this is destroyed.
- ValueMapCallbackVH Copy(*this);
- sys::Mutex *M = Config::getMutex(Copy.Map->Data);
- if (M)
- M->acquire();
-
- KeyT typed_new_key = cast<KeySansPointerT>(new_key);
- // Can destroy *this:
- Config::onRAUW(Copy.Map->Data, Copy.Unwrap(), typed_new_key);
- if (Config::FollowRAUW) {
- typename ValueMapT::MapT::iterator I = Copy.Map->Map.find(Copy);
- // I could == Copy.Map->Map.end() if the onRAUW callback already
- // removed the old mapping.
- if (I != Copy.Map->Map.end()) {
- ValueT Target(I->second);
- Copy.Map->Map.erase(I); // Definitely destroys *this.
- Copy.Map->insert(std::make_pair(typed_new_key, Target));
- }
- }
- if (M)
- M->release();
- }
-};
-
-template<typename KeyT, typename ValueT, typename Config>
-struct DenseMapInfo<ValueMapCallbackVH<KeyT, ValueT, Config> > {
- typedef ValueMapCallbackVH<KeyT, ValueT, Config> VH;
- typedef DenseMapInfo<KeyT> PointerInfo;
-
- static inline VH getEmptyKey() {
- return VH(PointerInfo::getEmptyKey(), NULL);
- }
- static inline VH getTombstoneKey() {
- return VH(PointerInfo::getTombstoneKey(), NULL);
- }
- static unsigned getHashValue(const VH &Val) {
- return PointerInfo::getHashValue(Val.Unwrap());
- }
- static unsigned getHashValue(const KeyT &Val) {
- return PointerInfo::getHashValue(Val);
- }
- static bool isEqual(const VH &LHS, const VH &RHS) {
- return LHS == RHS;
- }
- static bool isEqual(const KeyT &LHS, const VH &RHS) {
- return LHS == RHS.getValPtr();
- }
-};
-
-
-template<typename DenseMapT, typename KeyT>
-class ValueMapIterator :
- public std::iterator<std::forward_iterator_tag,
- std::pair<KeyT, typename DenseMapT::mapped_type>,
- ptrdiff_t> {
- typedef typename DenseMapT::iterator BaseT;
- typedef typename DenseMapT::mapped_type ValueT;
- BaseT I;
-public:
- ValueMapIterator() : I() {}
-
- ValueMapIterator(BaseT I) : I(I) {}
-
- BaseT base() const { return I; }
-
- struct ValueTypeProxy {
- const KeyT first;
- ValueT& second;
- ValueTypeProxy *operator->() { return this; }
- operator std::pair<KeyT, ValueT>() const {
- return std::make_pair(first, second);
- }
- };
-
- ValueTypeProxy operator*() const {
- ValueTypeProxy Result = {I->first.Unwrap(), I->second};
- return Result;
- }
-
- ValueTypeProxy operator->() const {
- return operator*();
- }
-
- bool operator==(const ValueMapIterator &RHS) const {
- return I == RHS.I;
- }
- bool operator!=(const ValueMapIterator &RHS) const {
- return I != RHS.I;
- }
-
- inline ValueMapIterator& operator++() { // Preincrement
- ++I;
- return *this;
- }
- ValueMapIterator operator++(int) { // Postincrement
- ValueMapIterator tmp = *this; ++*this; return tmp;
- }
-};
-
-template<typename DenseMapT, typename KeyT>
-class ValueMapConstIterator :
- public std::iterator<std::forward_iterator_tag,
- std::pair<KeyT, typename DenseMapT::mapped_type>,
- ptrdiff_t> {
- typedef typename DenseMapT::const_iterator BaseT;
- typedef typename DenseMapT::mapped_type ValueT;
- BaseT I;
-public:
- ValueMapConstIterator() : I() {}
- ValueMapConstIterator(BaseT I) : I(I) {}
- ValueMapConstIterator(ValueMapIterator<DenseMapT, KeyT> Other)
- : I(Other.base()) {}
-
- BaseT base() const { return I; }
-
- struct ValueTypeProxy {
- const KeyT first;
- const ValueT& second;
- ValueTypeProxy *operator->() { return this; }
- operator std::pair<KeyT, ValueT>() const {
- return std::make_pair(first, second);
- }
- };
-
- ValueTypeProxy operator*() const {
- ValueTypeProxy Result = {I->first.Unwrap(), I->second};
- return Result;
- }
-
- ValueTypeProxy operator->() const {
- return operator*();
- }
-
- bool operator==(const ValueMapConstIterator &RHS) const {
- return I == RHS.I;
- }
- bool operator!=(const ValueMapConstIterator &RHS) const {
- return I != RHS.I;
- }
-
- inline ValueMapConstIterator& operator++() { // Preincrement
- ++I;
- return *this;
- }
- ValueMapConstIterator operator++(int) { // Postincrement
- ValueMapConstIterator tmp = *this; ++*this; return tmp;
- }
-};
-
-} // end namespace llvm
-
-#endif
diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h
new file mode 100644
index 0000000..4f2f321
--- /dev/null
+++ b/include/llvm/ADT/iterator_range.h
@@ -0,0 +1,45 @@
+//===- iterator_range.h - A range adaptor for iterators ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This provides a very simple, boring adaptor for a begin and end iterator
+/// into a range type. This should be used to build range views that work well
+/// with range based for loops and range based constructors.
+///
+/// Note that code here follows more standards-based coding conventions as it
+/// is mirroring proposed interfaces for standardization.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR_RANGE_H
+#define LLVM_ADT_ITERATOR_RANGE_H
+
+#include <utility>
+
+namespace llvm {
+
+/// \brief A range adaptor for a pair of iterators.
+///
+/// This just wraps two iterators into a range-compatible interface. Nothing
+/// fancy at all.
+template <typename IteratorT>
+class iterator_range {
+ IteratorT begin_iterator, end_iterator;
+
+public:
+ iterator_range() {}
+ iterator_range(IteratorT begin_iterator, IteratorT end_iterator)
+ : begin_iterator(std::move(begin_iterator)),
+ end_iterator(std::move(end_iterator)) {}
+
+ IteratorT begin() const { return begin_iterator; }
+ IteratorT end() const { return end_iterator; }
+};
+}
+
+#endif
diff --git a/include/llvm/ADT/polymorphic_ptr.h b/include/llvm/ADT/polymorphic_ptr.h
deleted file mode 100644
index b8d8d71..0000000
--- a/include/llvm/ADT/polymorphic_ptr.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//===- llvm/ADT/polymorphic_ptr.h - Smart copyable owned ptr ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file provides a polymorphic_ptr class template. See the class comments
-/// for details about this API, its intended use cases, etc.
-///
-/// The primary motivation here is to work around the necessity of copy
-/// semantics in C++98. This is typically used where any actual copies are
-/// incidental or unnecessary. As a consequence, it is expected to cease to be
-/// useful and be removed when we can directly rely on move-only types.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ADT_POLYMORPHIC_PTR_H
-#define LLVM_ADT_POLYMORPHIC_PTR_H
-
-#include "llvm/Support/Compiler.h"
-
-namespace llvm {
-
-/// \brief An owning, copyable polymorphic smart pointer.
-///
-/// This pointer exists to provide copyable owned smart pointer. Rather than
-/// shared ownership semantics, it has unique ownership semantics and deep copy
-/// semantics. It is copyable by requiring that the underlying type exposes
-/// a method which can produce a (heap allocated) clone.
-///
-/// Note that in almost all scenarios use of this could be avoided if we could
-/// build move-only containers of a std::unique_ptr, but until then this
-/// provides an effective way to place polymorphic objects in a container.
-template <typename T> class polymorphic_ptr {
- T *ptr;
-
-public:
- polymorphic_ptr(T *ptr = 0) : ptr(ptr) {}
- polymorphic_ptr(const polymorphic_ptr &arg) : ptr(arg ? arg->clone() : 0) {}
-#if LLVM_HAS_RVALUE_REFERENCES
- polymorphic_ptr(polymorphic_ptr &&arg) : ptr(arg.take()) {}
-#endif
- ~polymorphic_ptr() { delete ptr; }
-
- polymorphic_ptr &operator=(polymorphic_ptr arg) {
- swap(arg);
- return *this;
- }
- polymorphic_ptr &operator=(T *arg) {
- if (arg != ptr) {
- delete ptr;
- ptr = arg;
- }
- return *this;
- }
-
- T &operator*() const { return *ptr; }
- T *operator->() const { return ptr; }
- LLVM_EXPLICIT operator bool() const { return ptr != 0; }
- bool operator!() const { return ptr == 0; }
-
- T *get() const { return ptr; }
-
- T *take() {
- T *tmp = ptr;
- ptr = 0;
- return tmp;
- }
-
- void swap(polymorphic_ptr &arg) {
- T *tmp = ptr;
- ptr = arg.ptr;
- arg.ptr = tmp;
- }
-};
-
-template <typename T>
-void swap(polymorphic_ptr<T> &lhs, polymorphic_ptr<T> &rhs) {
- lhs.swap(rhs);
-}
-
-template <typename T, typename U>
-bool operator==(const polymorphic_ptr<T> &lhs, const polymorphic_ptr<U> &rhs) {
- return lhs.get() == rhs.get();
-}
-
-template <typename T, typename U>
-bool operator!=(const polymorphic_ptr<T> &lhs, const polymorphic_ptr<U> &rhs) {
- return lhs.get() != rhs.get();
-}
-
-template <typename T, typename U>
-bool operator==(const polymorphic_ptr<T> &lhs, U *rhs) {
- return lhs.get() == rhs;
-}
-
-template <typename T, typename U>
-bool operator!=(const polymorphic_ptr<T> &lhs, U *rhs) {
- return lhs.get() != rhs;
-}
-
-template <typename T, typename U>
-bool operator==(T *lhs, const polymorphic_ptr<U> &rhs) {
- return lhs == rhs.get();
-}
-
-template <typename T, typename U>
-bool operator!=(T *lhs, const polymorphic_ptr<U> &rhs) {
- return lhs != rhs.get();
-}
-
-}
-
-#endif