diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
commit | 044eb2f6afba375a914ac9d8024f8f5142bb912e (patch) | |
tree | 1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /include/llvm/ADT | |
parent | eb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff) |
Notes
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r-- | include/llvm/ADT/APFloat.h | 15 | ||||
-rw-r--r-- | include/llvm/ADT/APInt.h | 4 | ||||
-rw-r--r-- | include/llvm/ADT/ArrayRef.h | 2 | ||||
-rw-r--r-- | include/llvm/ADT/BitVector.h | 2 | ||||
-rw-r--r-- | include/llvm/ADT/DenseMap.h | 134 | ||||
-rw-r--r-- | include/llvm/ADT/EquivalenceClasses.h | 10 | ||||
-rw-r--r-- | include/llvm/ADT/FoldingSet.h | 44 | ||||
-rw-r--r-- | include/llvm/ADT/MapVector.h | 7 | ||||
-rw-r--r-- | include/llvm/ADT/Optional.h | 64 | ||||
-rw-r--r-- | include/llvm/ADT/PointerEmbeddedInt.h | 5 | ||||
-rw-r--r-- | include/llvm/ADT/PointerIntPair.h | 34 | ||||
-rw-r--r-- | include/llvm/ADT/PointerSumType.h | 50 | ||||
-rw-r--r-- | include/llvm/ADT/PointerUnion.h | 88 | ||||
-rw-r--r-- | include/llvm/ADT/STLExtras.h | 298 | ||||
-rw-r--r-- | include/llvm/ADT/SmallPtrSet.h | 45 | ||||
-rw-r--r-- | include/llvm/ADT/SmallVector.h | 7 | ||||
-rw-r--r-- | include/llvm/ADT/StringExtras.h | 62 | ||||
-rw-r--r-- | include/llvm/ADT/StringMap.h | 4 | ||||
-rw-r--r-- | include/llvm/ADT/TinyPtrVector.h | 1 | ||||
-rw-r--r-- | include/llvm/ADT/Triple.h | 50 | ||||
-rw-r--r-- | include/llvm/ADT/Twine.h | 54 | ||||
-rw-r--r-- | include/llvm/ADT/iterator.h | 8 |
22 files changed, 586 insertions, 402 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 9c5e392c48087..6c0b6ae78ae32 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -1119,6 +1119,21 @@ public: llvm_unreachable("Unexpected semantics"); } + /// We don't rely on operator== working on double values, as + /// it returns true for things that are clearly not equal, like -0.0 and 0.0. + /// As such, this method can be used to do an exact bit-for-bit comparison of + /// two floating point values. + /// + /// We leave the version with the double argument here because it's just so + /// convenient to write "2.0" and the like. Without this function we'd + /// have to duplicate its logic everywhere it's called. + bool isExactlyValue(double V) const { + bool ignored; + APFloat Tmp(V); + Tmp.convert(getSemantics(), APFloat::rmNearestTiesToEven, &ignored); + return bitwiseIsEqual(Tmp); + } + unsigned int convertToHexString(char *DST, unsigned int HexDigits, bool UpperCase, roundingMode RM) const { APFLOAT_DISPATCH_ON_SEMANTICS( diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index a1cce6e5fe170..c81363cc16b7d 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -1724,13 +1724,13 @@ public: /// @{ /// \returns the floor log base 2 of this APInt. - unsigned logBase2() const { return BitWidth - 1 - countLeadingZeros(); } + unsigned logBase2() const { return getActiveBits() - 1; } /// \returns the ceil log base 2 of this APInt. unsigned ceilLogBase2() const { APInt temp(*this); --temp; - return BitWidth - temp.countLeadingZeros(); + return temp.getActiveBits(); } /// \returns the nearest log base 2 of this APInt. Ties round up. diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index 925ebafc3feda..5f7a769ddac44 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -294,7 +294,7 @@ namespace llvm { using reverse_iterator = std::reverse_iterator<iterator>; /// Construct an empty MutableArrayRef. - /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} + /*implicit*/ MutableArrayRef() = default; /// Construct an empty MutableArrayRef from None. /*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {} diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index e68ef5f53d106..99147fec4d4c7 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -911,7 +911,7 @@ public: size_t getBitCapacity() const { return Bits.size() * BITWORD_SIZE; } }; -static inline size_t capacity_in_bytes(const BitVector &X) { +inline size_t capacity_in_bytes(const BitVector &X) { return X.getMemorySize(); } diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index b311e69ec9d37..ba60b7972a8fc 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -19,6 +19,7 @@ #include "llvm/Support/AlignOf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" +#include "llvm/Support/ReverseIteration.h" #include "llvm/Support/type_traits.h" #include <algorithm> #include <cassert> @@ -67,18 +68,26 @@ public: DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>; inline iterator begin() { - // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets(). - return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this); + // When the map is empty, avoid the overhead of advancing/retreating past + // empty buckets. + if (empty()) + return end(); + if (shouldReverseIterate<KeyT>()) + return makeIterator(getBucketsEnd() - 1, getBuckets(), *this); + return makeIterator(getBuckets(), getBucketsEnd(), *this); } inline iterator end() { - return iterator(getBucketsEnd(), getBucketsEnd(), *this, true); + return makeIterator(getBucketsEnd(), getBucketsEnd(), *this, true); } inline const_iterator begin() const { - return empty() ? end() - : const_iterator(getBuckets(), getBucketsEnd(), *this); + if (empty()) + return end(); + if (shouldReverseIterate<KeyT>()) + return makeConstIterator(getBucketsEnd() - 1, getBuckets(), *this); + return makeConstIterator(getBuckets(), getBucketsEnd(), *this); } inline const_iterator end() const { - return const_iterator(getBucketsEnd(), getBucketsEnd(), *this, true); + return makeConstIterator(getBucketsEnd(), getBucketsEnd(), *this, true); } LLVM_NODISCARD bool empty() const { @@ -107,17 +116,23 @@ public: } const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey(); - unsigned NumEntries = getNumEntries(); - for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { - if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) { - if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { - P->getSecond().~ValueT(); - --NumEntries; - } + if (isPodLike<KeyT>::value && isPodLike<ValueT>::value) { + // Use a simpler loop when these are trivial types. + for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) P->getFirst() = EmptyKey; + } else { + unsigned NumEntries = getNumEntries(); + for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) { + if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) { + if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) { + P->getSecond().~ValueT(); + --NumEntries; + } + P->getFirst() = EmptyKey; + } } + assert(NumEntries == 0 && "Node count imbalance!"); } - assert(NumEntries == 0 && "Node count imbalance!"); setNumEntries(0); setNumTombstones(0); } @@ -131,13 +146,13 @@ public: iterator find(const_arg_type_t<KeyT> Val) { BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return iterator(TheBucket, getBucketsEnd(), *this, true); + return makeIterator(TheBucket, getBucketsEnd(), *this, true); return end(); } const_iterator find(const_arg_type_t<KeyT> Val) const { const BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return const_iterator(TheBucket, getBucketsEnd(), *this, true); + return makeConstIterator(TheBucket, getBucketsEnd(), *this, true); return end(); } @@ -150,14 +165,14 @@ public: iterator find_as(const LookupKeyT &Val) { BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return iterator(TheBucket, getBucketsEnd(), *this, true); + return makeIterator(TheBucket, getBucketsEnd(), *this, true); return end(); } template<class LookupKeyT> const_iterator find_as(const LookupKeyT &Val) const { const BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return const_iterator(TheBucket, getBucketsEnd(), *this, true); + return makeConstIterator(TheBucket, getBucketsEnd(), *this, true); return end(); } @@ -191,14 +206,16 @@ public: std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&... Args) { BucketT *TheBucket; if (LookupBucketFor(Key, TheBucket)) - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - false); // Already in map. + return std::make_pair( + makeIterator(TheBucket, getBucketsEnd(), *this, true), + false); // Already in map. // Otherwise, insert the new element. TheBucket = InsertIntoBucket(TheBucket, std::move(Key), std::forward<Ts>(Args)...); - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - true); + return std::make_pair( + makeIterator(TheBucket, getBucketsEnd(), *this, true), + true); } // Inserts key,value pair into the map if the key isn't already in the map. @@ -208,13 +225,15 @@ public: std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&... Args) { BucketT *TheBucket; if (LookupBucketFor(Key, TheBucket)) - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - false); // Already in map. + return std::make_pair( + makeIterator(TheBucket, getBucketsEnd(), *this, true), + false); // Already in map. // Otherwise, insert the new element. TheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(Args)...); - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - true); + return std::make_pair( + makeIterator(TheBucket, getBucketsEnd(), *this, true), + true); } /// Alternate version of insert() which allows a different, and possibly @@ -227,14 +246,16 @@ public: const LookupKeyT &Val) { BucketT *TheBucket; if (LookupBucketFor(Val, TheBucket)) - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - false); // Already in map. + return std::make_pair( + makeIterator(TheBucket, getBucketsEnd(), *this, true), + false); // Already in map. // Otherwise, insert the new element. TheBucket = InsertIntoBucketWithLookup(TheBucket, std::move(KV.first), std::move(KV.second), Val); - return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true), - true); + return std::make_pair( + makeIterator(TheBucket, getBucketsEnd(), *this, true), + true); } /// insert - Range insertion of pairs. @@ -405,6 +426,26 @@ protected: } private: + iterator makeIterator(BucketT *P, BucketT *E, + DebugEpochBase &Epoch, + bool NoAdvance=false) { + if (shouldReverseIterate<KeyT>()) { + BucketT *B = P == getBucketsEnd() ? getBuckets() : P + 1; + return iterator(B, E, Epoch, NoAdvance); + } + return iterator(P, E, Epoch, NoAdvance); + } + + const_iterator makeConstIterator(const BucketT *P, const BucketT *E, + const DebugEpochBase &Epoch, + const bool NoAdvance=false) const { + if (shouldReverseIterate<KeyT>()) { + const BucketT *B = P == getBucketsEnd() ? getBuckets() : P + 1; + return const_iterator(B, E, Epoch, NoAdvance); + } + return const_iterator(P, E, Epoch, NoAdvance); + } + unsigned getNumEntries() const { return static_cast<const DerivedT *>(this)->getNumEntries(); } @@ -1089,7 +1130,13 @@ public: bool NoAdvance = false) : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) { assert(isHandleInSync() && "invalid construction!"); - if (!NoAdvance) AdvancePastEmptyBuckets(); + + if (NoAdvance) return; + if (shouldReverseIterate<KeyT>()) { + RetreatPastEmptyBuckets(); + return; + } + AdvancePastEmptyBuckets(); } // Converting ctor from non-const iterators to const iterators. SFINAE'd out @@ -1103,10 +1150,14 @@ public: reference operator*() const { assert(isHandleInSync() && "invalid iterator access!"); + if (shouldReverseIterate<KeyT>()) + return Ptr[-1]; return *Ptr; } pointer operator->() const { assert(isHandleInSync() && "invalid iterator access!"); + if (shouldReverseIterate<KeyT>()) + return &(Ptr[-1]); return Ptr; } @@ -1127,6 +1178,11 @@ public: inline DenseMapIterator& operator++() { // Preincrement assert(isHandleInSync() && "invalid iterator access!"); + if (shouldReverseIterate<KeyT>()) { + --Ptr; + RetreatPastEmptyBuckets(); + return *this; + } ++Ptr; AdvancePastEmptyBuckets(); return *this; @@ -1138,6 +1194,7 @@ public: private: void AdvancePastEmptyBuckets() { + assert(Ptr <= End); const KeyT Empty = KeyInfoT::getEmptyKey(); const KeyT Tombstone = KeyInfoT::getTombstoneKey(); @@ -1145,11 +1202,20 @@ private: KeyInfoT::isEqual(Ptr->getFirst(), Tombstone))) ++Ptr; } + + void RetreatPastEmptyBuckets() { + assert(Ptr >= End); + const KeyT Empty = KeyInfoT::getEmptyKey(); + const KeyT Tombstone = KeyInfoT::getTombstoneKey(); + + while (Ptr != End && (KeyInfoT::isEqual(Ptr[-1].getFirst(), Empty) || + KeyInfoT::isEqual(Ptr[-1].getFirst(), Tombstone))) + --Ptr; + } }; -template<typename KeyT, typename ValueT, typename KeyInfoT> -static inline size_t -capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) { +template <typename KeyT, typename ValueT, typename KeyInfoT> +inline size_t capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) { return X.getMemorySize(); } diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h index af293d4c1422a..e3f48433c69fd 100644 --- a/include/llvm/ADT/EquivalenceClasses.h +++ b/include/llvm/ADT/EquivalenceClasses.h @@ -239,6 +239,16 @@ public: return L1; } + // isEquivalent - Return true if V1 is equivalent to V2. This can happen if + // V1 is equal to V2 or if they belong to one equivalence class. + bool isEquivalent(const ElemTy &V1, const ElemTy &V2) const { + // Fast path: any element is equivalent to itself. + if (V1 == V2) + return true; + auto It = findLeader(V1); + return It != member_end() && It == findLeader(V2); + } + class member_iterator : public std::iterator<std::forward_iterator_tag, const ElemTy, ptrdiff_t> { friend class EquivalenceClasses; diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h index c5987a947e182..e363e69d032aa 100644 --- a/include/llvm/ADT/FoldingSet.h +++ b/include/llvm/ADT/FoldingSet.h @@ -1,4 +1,4 @@ -//===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- C++ -*-===// +//===- llvm/ADT/FoldingSet.h - Uniquing Hash Set ----------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -115,11 +115,9 @@ class FoldingSetBase { protected: /// Buckets - Array of bucket chains. - /// void **Buckets; /// NumBuckets - Length of the Buckets array. Always a power of 2. - /// unsigned NumBuckets; /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes @@ -135,14 +133,13 @@ public: //===--------------------------------------------------------------------===// /// Node - This class is used to maintain the singly linked bucket list in /// a folding set. - /// class Node { private: // NextInFoldingSetBucket - next link in the bucket list. - void *NextInFoldingSetBucket; + void *NextInFoldingSetBucket = nullptr; public: - Node() : NextInFoldingSetBucket(nullptr) {} + Node() = default; // Accessors void *getNextInBucket() const { return NextInFoldingSetBucket; } @@ -221,7 +218,6 @@ protected: /// DefaultFoldingSetTrait - This class provides default implementations /// for FoldingSetTrait implementations. -/// template<typename T> struct DefaultFoldingSetTrait { static void Profile(const T &X, FoldingSetNodeID &ID) { X.Profile(ID); @@ -307,7 +303,6 @@ public: /// FoldingSetNodeID - This class is used to gather all the unique data bits of /// a node. When all the bits are gathered this class is used to produce a /// hash value for the node. -/// class FoldingSetNodeID { /// Bits - Vector of all the data bits that make the node unique. /// Use a SmallVector to avoid a heap allocation in the common case. @@ -320,7 +315,6 @@ public: : Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {} /// Add* - Add various data types to Bit data. - /// void AddPointer(const void *Ptr); void AddInteger(signed I); void AddInteger(unsigned I); @@ -344,7 +338,6 @@ public: unsigned ComputeHash() const; /// operator== - Used to compare two nodes to each other. - /// bool operator==(const FoldingSetNodeID &RHS) const; bool operator==(const FoldingSetNodeIDRef RHS) const; @@ -363,7 +356,7 @@ public: }; // Convenience type to hide the implementation of the folding set. -typedef FoldingSetBase::Node FoldingSetNode; +using FoldingSetNode = FoldingSetBase::Node; template<class T> class FoldingSetIterator; template<class T> class FoldingSetBucketIterator; @@ -415,15 +408,17 @@ protected: ~FoldingSetImpl() = default; public: - typedef FoldingSetIterator<T> iterator; + using iterator = FoldingSetIterator<T>; + iterator begin() { return iterator(Buckets); } iterator end() { return iterator(Buckets+NumBuckets); } - typedef FoldingSetIterator<const T> const_iterator; + using const_iterator = FoldingSetIterator<const T>; + const_iterator begin() const { return const_iterator(Buckets); } const_iterator end() const { return const_iterator(Buckets+NumBuckets); } - typedef FoldingSetBucketIterator<T> bucket_iterator; + using bucket_iterator = FoldingSetBucketIterator<T>; bucket_iterator bucket_begin(unsigned hash) { return bucket_iterator(Buckets + (hash & (NumBuckets-1))); @@ -503,9 +498,7 @@ template <class T> class FoldingSet final : public FoldingSetImpl<T> { } public: - explicit FoldingSet(unsigned Log2InitSize = 6) - : Super(Log2InitSize) {} - + explicit FoldingSet(unsigned Log2InitSize = 6) : Super(Log2InitSize) {} FoldingSet(FoldingSet &&Arg) = default; FoldingSet &operator=(FoldingSet &&RHS) = default; }; @@ -552,8 +545,7 @@ class ContextualFoldingSet final : public FoldingSetImpl<T> { public: explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6) - : Super(Log2InitSize), Context(Context) - {} + : Super(Log2InitSize), Context(Context) {} Ctx getContext() const { return Context; } }; @@ -569,15 +561,15 @@ class FoldingSetVector { VectorT Vector; public: - explicit FoldingSetVector(unsigned Log2InitSize = 6) - : Set(Log2InitSize) { - } + explicit FoldingSetVector(unsigned Log2InitSize = 6) : Set(Log2InitSize) {} + + using iterator = pointee_iterator<typename VectorT::iterator>; - typedef pointee_iterator<typename VectorT::iterator> iterator; iterator begin() { return Vector.begin(); } iterator end() { return Vector.end(); } - typedef pointee_iterator<typename VectorT::const_iterator> const_iterator; + using const_iterator = pointee_iterator<typename VectorT::const_iterator>; + const_iterator begin() const { return Vector.begin(); } const_iterator end() const { return Vector.end(); } @@ -667,15 +659,13 @@ public: /// FoldingSetBucketIteratorImpl - This is the common bucket iterator support /// shared by all folding sets, which knows how to walk a particular bucket /// of a folding set hash table. - class FoldingSetBucketIteratorImpl { protected: void *Ptr; explicit FoldingSetBucketIteratorImpl(void **Bucket); - FoldingSetBucketIteratorImpl(void **Bucket, bool) - : Ptr(Bucket) {} + FoldingSetBucketIteratorImpl(void **Bucket, bool) : Ptr(Bucket) {} void advance() { void *Probe = static_cast<FoldingSetNode*>(Ptr)->getNextInBucket(); diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h index 26a555ee1d3bd..3d78f4b203c87 100644 --- a/include/llvm/ADT/MapVector.h +++ b/include/llvm/ADT/MapVector.h @@ -56,6 +56,13 @@ public: size_type size() const { return Vector.size(); } + /// Grow the MapVector so that it can contain at least \p NumEntries items + /// before resizing again. + void reserve(size_type NumEntries) { + Map.reserve(NumEntries); + Vector.reserve(NumEntries); + } + iterator begin() { return Vector.begin(); } const_iterator begin() const { return Vector.begin(); } iterator end() { return Vector.end(); } diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h index b782d9da17ac4..2811d5c1e21ba 100644 --- a/include/llvm/ADT/Optional.h +++ b/include/llvm/ADT/Optional.h @@ -27,8 +27,7 @@ namespace llvm { -template<typename T> -class Optional { +template <typename T> class Optional { AlignedCharArrayUnion<T> storage; bool hasVal = false; @@ -38,18 +37,14 @@ public: Optional(NoneType) {} explicit Optional() {} - Optional(const T &y) : hasVal(true) { - new (storage.buffer) T(y); - } + Optional(const T &y) : hasVal(true) { new (storage.buffer) T(y); } Optional(const Optional &O) : hasVal(O.hasVal) { if (hasVal) new (storage.buffer) T(*O); } - Optional(T &&y) : hasVal(true) { - new (storage.buffer) T(std::forward<T>(y)); - } + Optional(T &&y) : hasVal(true) { new (storage.buffer) T(std::forward<T>(y)); } Optional(Optional<T> &&O) : hasVal(O) { if (O) { @@ -58,9 +53,7 @@ public: } } - ~Optional() { - reset(); - } + ~Optional() { reset(); } Optional &operator=(T &&y) { if (hasVal) @@ -83,14 +76,13 @@ public: } /// Create a new object by constructing it in place with the given arguments. - template<typename ...ArgTypes> - void emplace(ArgTypes &&...Args) { + template <typename... ArgTypes> void emplace(ArgTypes &&... Args) { reset(); hasVal = true; new (storage.buffer) T(std::forward<ArgTypes>(Args)...); } - static inline Optional create(const T* y) { + static inline Optional create(const T *y) { return y ? Optional(*y) : Optional(); } @@ -124,17 +116,35 @@ public: } } - const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); } - T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); } - const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } - T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } + const T *getPointer() const { + assert(hasVal); + return reinterpret_cast<const T *>(storage.buffer); + } + T *getPointer() { + assert(hasVal); + return reinterpret_cast<T *>(storage.buffer); + } + const T &getValue() const LLVM_LVALUE_FUNCTION { + assert(hasVal); + return *getPointer(); + } + T &getValue() LLVM_LVALUE_FUNCTION { + assert(hasVal); + return *getPointer(); + } explicit operator bool() const { return hasVal; } bool hasValue() const { return hasVal; } - const T* operator->() const { return getPointer(); } - T* operator->() { return getPointer(); } - const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } - T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); } + const T *operator->() const { return getPointer(); } + T *operator->() { return getPointer(); } + const T &operator*() const LLVM_LVALUE_FUNCTION { + assert(hasVal); + return *getPointer(); + } + T &operator*() LLVM_LVALUE_FUNCTION { + assert(hasVal); + return *getPointer(); + } template <typename U> constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION { @@ -142,8 +152,14 @@ public: } #if LLVM_HAS_RVALUE_REFERENCE_THIS - T&& getValue() && { assert(hasVal); return std::move(*getPointer()); } - T&& operator*() && { assert(hasVal); return std::move(*getPointer()); } + T &&getValue() && { + assert(hasVal); + return std::move(*getPointer()); + } + T &&operator*() && { + assert(hasVal); + return std::move(*getPointer()); + } template <typename U> T getValueOr(U &&value) && { diff --git a/include/llvm/ADT/PointerEmbeddedInt.h b/include/llvm/ADT/PointerEmbeddedInt.h index 34323b5b8af49..ab4e1048a5bc9 100644 --- a/include/llvm/ADT/PointerEmbeddedInt.h +++ b/include/llvm/ADT/PointerEmbeddedInt.h @@ -52,7 +52,7 @@ class PointerEmbeddedInt { explicit RawValueTag() = default; }; - friend class PointerLikeTypeTraits<PointerEmbeddedInt>; + friend struct PointerLikeTypeTraits<PointerEmbeddedInt>; explicit PointerEmbeddedInt(uintptr_t Value, RawValueTag) : Value(Value) {} @@ -80,10 +80,9 @@ public: // Provide pointer like traits to support use with pointer unions and sum // types. template <typename IntT, int Bits> -class PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> { +struct PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> { using T = PointerEmbeddedInt<IntT, Bits>; -public: static inline void *getAsVoidPointer(const T &P) { return reinterpret_cast<void *>(P.Value); } diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 83fbf127e6dac..884d05155bffa 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -14,15 +14,14 @@ #ifndef LLVM_ADT_POINTERINTPAIR_H #define LLVM_ADT_POINTERINTPAIR_H -#include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <cassert> +#include <cstdint> #include <limits> namespace llvm { template <typename T> struct DenseMapInfo; - template <typename PointerT, unsigned IntBits, typename PtrTraits> struct PointerIntPairInfo; @@ -39,25 +38,24 @@ struct PointerIntPairInfo; /// for something else. For example, this allows: /// PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool> /// ... and the two bools will land in different bits. -/// template <typename PointerTy, unsigned IntBits, typename IntType = unsigned, typename PtrTraits = PointerLikeTypeTraits<PointerTy>, typename Info = PointerIntPairInfo<PointerTy, IntBits, PtrTraits>> class PointerIntPair { - intptr_t Value; + intptr_t Value = 0; public: - PointerIntPair() : Value(0) {} + constexpr PointerIntPair() = default; + PointerIntPair(PointerTy PtrVal, IntType IntVal) { setPointerAndInt(PtrVal, IntVal); } + explicit PointerIntPair(PointerTy PtrVal) { initWithPointer(PtrVal); } PointerTy getPointer() const { return Info::getPointer(Value); } - IntType getInt() const { - return (IntType)Info::getInt(Value); - } + IntType getInt() const { return (IntType)Info::getInt(Value); } void setPointer(PointerTy PtrVal) { Value = Info::updatePointer(Value, PtrVal); @@ -88,6 +86,7 @@ public: } void *getOpaqueValue() const { return reinterpret_cast<void *>(Value); } + void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val); } @@ -108,14 +107,18 @@ public: bool operator==(const PointerIntPair &RHS) const { return Value == RHS.Value; } + bool operator!=(const PointerIntPair &RHS) const { return Value != RHS.Value; } + bool operator<(const PointerIntPair &RHS) const { return Value < RHS.Value; } bool operator>(const PointerIntPair &RHS) const { return Value > RHS.Value; } + bool operator<=(const PointerIntPair &RHS) const { return Value <= RHS.Value; } + bool operator>=(const PointerIntPair &RHS) const { return Value >= RHS.Value; } @@ -180,44 +183,51 @@ struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType>> { // Provide specialization of DenseMapInfo for PointerIntPair. template <typename PointerTy, unsigned IntBits, typename IntType> struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>> { - typedef PointerIntPair<PointerTy, IntBits, IntType> Ty; + using Ty = PointerIntPair<PointerTy, IntBits, IntType>; + static Ty getEmptyKey() { uintptr_t Val = static_cast<uintptr_t>(-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::getFromOpaqueValue(reinterpret_cast<void *>(Val)); } + static unsigned getHashValue(Ty V) { uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue()); return unsigned(IV) ^ unsigned(IV >> 9); } + static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; } }; // Teach SmallPtrSet that PointerIntPair is "basically a pointer". template <typename PointerTy, unsigned IntBits, typename IntType, typename PtrTraits> -class PointerLikeTypeTraits< +struct PointerLikeTypeTraits< PointerIntPair<PointerTy, IntBits, IntType, PtrTraits>> { -public: static inline void * getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) { return P.getOpaqueValue(); } + static inline PointerIntPair<PointerTy, IntBits, IntType> getFromVoidPointer(void *P) { return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P); } + static inline PointerIntPair<PointerTy, IntBits, IntType> getFromVoidPointer(const void *P) { return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P); } + enum { NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits }; }; } // end namespace llvm -#endif + +#endif // LLVM_ADT_POINTERINTPAIR_H diff --git a/include/llvm/ADT/PointerSumType.h b/include/llvm/ADT/PointerSumType.h index 062544eedf84b..e37957160d981 100644 --- a/include/llvm/ADT/PointerSumType.h +++ b/include/llvm/ADT/PointerSumType.h @@ -11,8 +11,10 @@ #define LLVM_ADT_POINTERSUMTYPE_H #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" +#include <cassert> +#include <cstdint> +#include <type_traits> namespace llvm { @@ -24,16 +26,15 @@ template <uintptr_t N, typename PointerArgT, typename TraitsArgT = PointerLikeTypeTraits<PointerArgT>> struct PointerSumTypeMember { enum { Tag = N }; - typedef PointerArgT PointerT; - typedef TraitsArgT TraitsT; + using PointerT = PointerArgT; + using TraitsT = TraitsArgT; }; namespace detail { -template <typename TagT, typename... MemberTs> -struct PointerSumTypeHelper; +template <typename TagT, typename... MemberTs> struct PointerSumTypeHelper; -} +} // end namespace detail /// A sum type over pointer-like types. /// @@ -60,12 +61,12 @@ struct PointerSumTypeHelper; /// There is no support for constructing or accessing with a dynamic tag as /// that would fundamentally violate the type safety provided by the sum type. template <typename TagT, typename... MemberTs> class PointerSumType { - uintptr_t Value; + uintptr_t Value = 0; - typedef detail::PointerSumTypeHelper<TagT, MemberTs...> HelperT; + using HelperT = detail::PointerSumTypeHelper<TagT, MemberTs...>; public: - PointerSumType() : Value(0) {} + constexpr PointerSumType() = default; /// A typed constructor for a specific tagged member of the sum type. template <TagT N> @@ -128,14 +129,14 @@ struct PointerSumTypeHelper : MemberTs... { template <TagT N> static void LookupOverload(...); template <TagT N> struct Lookup { // Compute a particular member type by resolving the lookup helper ovorload. - typedef decltype(LookupOverload<N>( - static_cast<PointerSumTypeHelper *>(nullptr))) MemberT; + using MemberT = decltype( + LookupOverload<N>(static_cast<PointerSumTypeHelper *>(nullptr))); /// The Nth member's pointer type. - typedef typename MemberT::PointerT PointerT; + using PointerT = typename MemberT::PointerT; /// The Nth member's traits type. - typedef typename MemberT::TraitsT TraitsT; + using TraitsT = typename MemberT::TraitsT; }; // Next we need to compute the number of bits available for the discriminant @@ -171,35 +172,36 @@ struct PointerSumTypeHelper : MemberTs... { "Each member must pass the checker."); }; -} +} // end namespace detail // Teach DenseMap how to use PointerSumTypes as keys. template <typename TagT, typename... MemberTs> struct DenseMapInfo<PointerSumType<TagT, MemberTs...>> { - typedef PointerSumType<TagT, MemberTs...> SumType; - - typedef detail::PointerSumTypeHelper<TagT, MemberTs...> HelperT; + using SumType = PointerSumType<TagT, MemberTs...>; + using HelperT = detail::PointerSumTypeHelper<TagT, MemberTs...>; enum { SomeTag = HelperT::MinTag }; - typedef typename HelperT::template Lookup<HelperT::MinTag>::PointerT - SomePointerT; - typedef DenseMapInfo<SomePointerT> SomePointerInfo; + using SomePointerT = + typename HelperT::template Lookup<HelperT::MinTag>::PointerT; + using SomePointerInfo = DenseMapInfo<SomePointerT>; static inline SumType getEmptyKey() { return SumType::create<SomeTag>(SomePointerInfo::getEmptyKey()); } + static inline SumType getTombstoneKey() { - return SumType::create<SomeTag>( - SomePointerInfo::getTombstoneKey()); + return SumType::create<SomeTag>(SomePointerInfo::getTombstoneKey()); } + static unsigned getHashValue(const SumType &Arg) { uintptr_t OpaqueValue = Arg.getOpaqueValue(); return DenseMapInfo<uintptr_t>::getHashValue(OpaqueValue); } + static bool isEqual(const SumType &LHS, const SumType &RHS) { return LHS == RHS; } }; -} +} // end namespace llvm -#endif +#endif // LLVM_ADT_POINTERSUMTYPE_H diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index aeab641f5715a..4276859e9254c 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -25,7 +25,7 @@ namespace llvm { template <typename T> struct PointerUnionTypeSelectorReturn { - typedef T Return; + using Return = T; }; /// Get a type based on whether two types are the same or not. @@ -33,25 +33,25 @@ template <typename T> struct PointerUnionTypeSelectorReturn { /// For: /// /// \code -/// typedef typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return Ret; +/// using Ret = typename PointerUnionTypeSelector<T1, T2, EQ, NE>::Return; /// \endcode /// /// Ret will be EQ type if T1 is same as T2 or NE type otherwise. template <typename T1, typename T2, typename RET_EQ, typename RET_NE> struct PointerUnionTypeSelector { - typedef typename PointerUnionTypeSelectorReturn<RET_NE>::Return Return; + using Return = typename PointerUnionTypeSelectorReturn<RET_NE>::Return; }; template <typename T, typename RET_EQ, typename RET_NE> struct PointerUnionTypeSelector<T, T, RET_EQ, RET_NE> { - typedef typename PointerUnionTypeSelectorReturn<RET_EQ>::Return Return; + using Return = typename PointerUnionTypeSelectorReturn<RET_EQ>::Return; }; template <typename T1, typename T2, typename RET_EQ, typename RET_NE> struct PointerUnionTypeSelectorReturn< PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>> { - typedef - typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return Return; + using Return = + typename PointerUnionTypeSelector<T1, T2, RET_EQ, RET_NE>::Return; }; /// Provide PointerLikeTypeTraits for void* that is used by PointerUnion @@ -86,8 +86,8 @@ public: /// X = P.get<int*>(); // runtime assertion failure. template <typename PT1, typename PT2> class PointerUnion { public: - typedef PointerIntPair<void *, 1, bool, PointerUnionUIntTraits<PT1, PT2>> - ValTy; + using ValTy = + PointerIntPair<void *, 1, bool, PointerUnionUIntTraits<PT1, PT2>>; private: ValTy Val; @@ -102,7 +102,6 @@ private: public: PointerUnion() = default; - PointerUnion(PT1 V) : Val(const_cast<void *>( PointerLikeTypeTraits<PT1>::getAsVoidPointer(V))) {} @@ -117,14 +116,15 @@ public: // we recursively strip off low bits if we have a nested PointerUnion. return !PointerLikeTypeTraits<PT1>::getFromVoidPointer(Val.getPointer()); } + explicit operator bool() const { return !isNull(); } /// Test if the Union currently holds the type matching T. template <typename T> int is() const { - typedef typename ::llvm::PointerUnionTypeSelector< - PT1, T, IsPT1, ::llvm::PointerUnionTypeSelector< - PT2, T, IsPT2, UNION_DOESNT_CONTAIN_TYPE<T>>>::Return - Ty; + using Ty = typename ::llvm::PointerUnionTypeSelector< + PT1, T, IsPT1, + ::llvm::PointerUnionTypeSelector<PT2, T, IsPT2, + UNION_DOESNT_CONTAIN_TYPE<T>>>::Return; int TyNo = Ty::Num; return static_cast<int>(Val.getInt()) == TyNo; } @@ -158,7 +158,8 @@ public: assert( get<PT1>() == Val.getPointer() && "Can't get the address because PointerLikeTypeTraits changes the ptr"); - return const_cast<PT1 *>(reinterpret_cast<const PT1 *>(Val.getAddrOfPointer())); + return const_cast<PT1 *>( + reinterpret_cast<const PT1 *>(Val.getAddrOfPointer())); } /// Assignment from nullptr which just clears the union. @@ -207,8 +208,7 @@ bool operator<(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) { // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has // # low bits available = min(PT1bits,PT2bits)-1. template <typename PT1, typename PT2> -class PointerLikeTypeTraits<PointerUnion<PT1, PT2>> { -public: +struct PointerLikeTypeTraits<PointerUnion<PT1, PT2>> { static inline void *getAsVoidPointer(const PointerUnion<PT1, PT2> &P) { return P.getOpaqueValue(); } @@ -228,19 +228,22 @@ public: /// for usage. template <typename PT1, typename PT2, typename PT3> class PointerUnion3 { public: - typedef PointerUnion<PT1, PT2> InnerUnion; - typedef PointerUnion<InnerUnion, PT3> ValTy; + using InnerUnion = PointerUnion<PT1, PT2>; + using ValTy = PointerUnion<InnerUnion, PT3>; private: ValTy Val; struct IsInnerUnion { ValTy Val; + IsInnerUnion(ValTy val) : Val(val) {} + template <typename T> int is() const { return Val.template is<InnerUnion>() && Val.template get<InnerUnion>().template is<T>(); } + template <typename T> T get() const { return Val.template get<InnerUnion>().template get<T>(); } @@ -248,14 +251,15 @@ private: struct IsPT3 { ValTy Val; + IsPT3(ValTy val) : Val(val) {} + template <typename T> int is() const { return Val.template is<T>(); } template <typename T> T get() const { return Val.template get<T>(); } }; public: PointerUnion3() = default; - PointerUnion3(PT1 V) { Val = InnerUnion(V); } PointerUnion3(PT2 V) { Val = InnerUnion(V); } PointerUnion3(PT3 V) { Val = V; } @@ -268,10 +272,9 @@ public: /// Test if the Union currently holds the type matching T. template <typename T> int is() const { // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3. - typedef typename ::llvm::PointerUnionTypeSelector< + using Ty = typename ::llvm::PointerUnionTypeSelector< PT1, T, IsInnerUnion, - ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return - Ty; + ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return; return Ty(Val).template is<T>(); } @@ -281,10 +284,9 @@ public: template <typename T> T get() const { assert(is<T>() && "Invalid accessor called"); // If T is PT1/PT2 choose IsInnerUnion otherwise choose IsPT3. - typedef typename ::llvm::PointerUnionTypeSelector< + using Ty = typename ::llvm::PointerUnionTypeSelector< PT1, T, IsInnerUnion, - ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return - Ty; + ::llvm::PointerUnionTypeSelector<PT2, T, IsInnerUnion, IsPT3>>::Return; return Ty(Val).template get<T>(); } @@ -328,8 +330,7 @@ public: // Teach SmallPtrSet that PointerUnion3 is "basically a pointer", that has // # low bits available = min(PT1bits,PT2bits,PT2bits)-2. template <typename PT1, typename PT2, typename PT3> -class PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3>> { -public: +struct PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3>> { static inline void *getAsVoidPointer(const PointerUnion3<PT1, PT2, PT3> &P) { return P.getOpaqueValue(); } @@ -350,16 +351,15 @@ public: template <typename PT1, typename PT2, typename PT3, typename PT4> class PointerUnion4 { public: - typedef PointerUnion<PT1, PT2> InnerUnion1; - typedef PointerUnion<PT3, PT4> InnerUnion2; - typedef PointerUnion<InnerUnion1, InnerUnion2> ValTy; + using InnerUnion1 = PointerUnion<PT1, PT2>; + using InnerUnion2 = PointerUnion<PT3, PT4>; + using ValTy = PointerUnion<InnerUnion1, InnerUnion2>; private: ValTy Val; public: PointerUnion4() = default; - PointerUnion4(PT1 V) { Val = InnerUnion1(V); } PointerUnion4(PT2 V) { Val = InnerUnion1(V); } PointerUnion4(PT3 V) { Val = InnerUnion2(V); } @@ -373,9 +373,10 @@ public: /// Test if the Union currently holds the type matching T. template <typename T> int is() const { // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2. - typedef typename ::llvm::PointerUnionTypeSelector< - PT1, T, InnerUnion1, ::llvm::PointerUnionTypeSelector< - PT2, T, InnerUnion1, InnerUnion2>>::Return Ty; + using Ty = typename ::llvm::PointerUnionTypeSelector< + PT1, T, InnerUnion1, + ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, + InnerUnion2>>::Return; return Val.template is<Ty>() && Val.template get<Ty>().template is<T>(); } @@ -385,9 +386,10 @@ public: template <typename T> T get() const { assert(is<T>() && "Invalid accessor called"); // If T is PT1/PT2 choose InnerUnion1 otherwise choose InnerUnion2. - typedef typename ::llvm::PointerUnionTypeSelector< - PT1, T, InnerUnion1, ::llvm::PointerUnionTypeSelector< - PT2, T, InnerUnion1, InnerUnion2>>::Return Ty; + using Ty = typename ::llvm::PointerUnionTypeSelector< + PT1, T, InnerUnion1, + ::llvm::PointerUnionTypeSelector<PT2, T, InnerUnion1, + InnerUnion2>>::Return; return Val.template get<Ty>().template get<T>(); } @@ -435,8 +437,7 @@ public: // Teach SmallPtrSet that PointerUnion4 is "basically a pointer", that has // # low bits available = min(PT1bits,PT2bits,PT2bits)-2. template <typename PT1, typename PT2, typename PT3, typename PT4> -class PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4>> { -public: +struct PointerLikeTypeTraits<PointerUnion4<PT1, PT2, PT3, PT4>> { static inline void * getAsVoidPointer(const PointerUnion4<PT1, PT2, PT3, PT4> &P) { return P.getOpaqueValue(); @@ -455,18 +456,21 @@ public: // Teach DenseMap how to use PointerUnions as keys. template <typename T, typename U> struct DenseMapInfo<PointerUnion<T, U>> { - typedef PointerUnion<T, U> Pair; - typedef DenseMapInfo<T> FirstInfo; - typedef DenseMapInfo<U> SecondInfo; + using Pair = PointerUnion<T, U>; + using FirstInfo = DenseMapInfo<T>; + using SecondInfo = DenseMapInfo<U>; static inline Pair getEmptyKey() { return Pair(FirstInfo::getEmptyKey()); } + static inline Pair getTombstoneKey() { return Pair(FirstInfo::getTombstoneKey()); } + static unsigned getHashValue(const Pair &PairVal) { intptr_t key = (intptr_t)PairVal.getOpaqueValue(); return DenseMapInfo<intptr_t>::getHashValue(key); } + static bool isEqual(const Pair &LHS, const Pair &RHS) { return LHS.template is<T>() == RHS.template is<T>() && (LHS.template is<T>() ? FirstInfo::isEqual(LHS.template get<T>(), diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index 83f289c42a23a..bcd992b4a7163 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -17,23 +17,24 @@ #ifndef LLVM_ADT_STLEXTRAS_H #define LLVM_ADT_STLEXTRAS_H -#include <algorithm> // for std::all_of +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/ErrorHandling.h" +#include <algorithm> #include <cassert> -#include <cstddef> // for std::size_t -#include <cstdlib> // for qsort +#include <cstddef> +#include <cstdint> +#include <cstdlib> #include <functional> +#include <initializer_list> #include <iterator> #include <limits> #include <memory> #include <tuple> -#include <utility> // for std::pair - -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/iterator.h" -#include "llvm/ADT/iterator_range.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/ErrorHandling.h" +#include <type_traits> +#include <utility> namespace llvm { @@ -50,14 +51,15 @@ template <typename RangeT> using ValueOfRange = typename std::remove_reference<decltype( *std::begin(std::declval<RangeT &>()))>::type; -} // End detail namespace +} // end namespace detail //===----------------------------------------------------------------------===// // Extra additions to <functional> //===----------------------------------------------------------------------===// -template<class Ty> -struct identity : public std::unary_function<Ty, Ty> { +template <class Ty> struct identity { + using argument_type = Ty; + Ty &operator()(Ty &self) const { return self; } @@ -66,15 +68,13 @@ struct identity : public std::unary_function<Ty, Ty> { } }; -template<class Ty> -struct less_ptr : public std::binary_function<Ty, Ty, bool> { +template <class Ty> struct less_ptr { bool operator()(const Ty* left, const Ty* right) const { return *left < *right; } }; -template<class Ty> -struct greater_ptr : public std::binary_function<Ty, Ty, bool> { +template <class Ty> struct greater_ptr { bool operator()(const Ty* left, const Ty* right) const { return *right < *left; } @@ -90,7 +90,7 @@ template<typename Fn> class function_ref; template<typename Ret, typename ...Params> class function_ref<Ret(Params...)> { - Ret (*callback)(intptr_t callable, Params ...params); + Ret (*callback)(intptr_t callable, Params ...params) = nullptr; intptr_t callable; template<typename Callable> @@ -100,7 +100,7 @@ class function_ref<Ret(Params...)> { } public: - function_ref() : callback(nullptr) {} + function_ref() = default; template <typename Callable> function_ref(Callable &&callable, @@ -109,6 +109,7 @@ public: function_ref>::value>::type * = nullptr) : callback(callback_fn<typename std::remove_reference<Callable>::type>), callable(reinterpret_cast<intptr_t>(&callable)) {} + Ret operator()(Params ...params) const { return callback(callable, std::forward<Params>(params)...); } @@ -120,114 +121,95 @@ public: // delete on something. It is used like this: // // for_each(V.begin(), B.end(), deleter<Interval>); -// template <class T> inline void deleter(T *Ptr) { delete Ptr; } - - //===----------------------------------------------------------------------===// // Extra additions to <iterator> //===----------------------------------------------------------------------===// -// mapped_iterator - This is a simple iterator adapter that causes a function to -// be applied whenever operator* is invoked on the iterator. -// -template <class RootIt, class UnaryFunc> -class mapped_iterator { - RootIt current; - UnaryFunc Fn; -public: - typedef typename std::iterator_traits<RootIt>::iterator_category - iterator_category; - typedef typename std::iterator_traits<RootIt>::difference_type - difference_type; - typedef decltype(std::declval<UnaryFunc>()(*std::declval<RootIt>())) - value_type; +namespace adl_detail { + +using std::begin; - typedef void pointer; - //typedef typename UnaryFunc::result_type *pointer; - typedef void reference; // Can't modify value returned by fn +template <typename ContainerTy> +auto adl_begin(ContainerTy &&container) + -> decltype(begin(std::forward<ContainerTy>(container))) { + return begin(std::forward<ContainerTy>(container)); +} - typedef RootIt iterator_type; +using std::end; - inline const RootIt &getCurrent() const { return current; } - inline const UnaryFunc &getFunc() const { return Fn; } +template <typename ContainerTy> +auto adl_end(ContainerTy &&container) + -> decltype(end(std::forward<ContainerTy>(container))) { + return end(std::forward<ContainerTy>(container)); +} - inline explicit mapped_iterator(const RootIt &I, UnaryFunc F) - : current(I), Fn(F) {} +using std::swap; - inline value_type operator*() const { // All this work to do this - return Fn(*current); // little change - } +template <typename T> +void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval<T>(), + std::declval<T>()))) { + swap(std::forward<T>(lhs), std::forward<T>(rhs)); +} - mapped_iterator &operator++() { - ++current; - return *this; - } - mapped_iterator &operator--() { - --current; - return *this; - } - mapped_iterator operator++(int) { - mapped_iterator __tmp = *this; - ++current; - return __tmp; - } - mapped_iterator operator--(int) { - mapped_iterator __tmp = *this; - --current; - return __tmp; - } - mapped_iterator operator+(difference_type n) const { - return mapped_iterator(current + n, Fn); - } - mapped_iterator &operator+=(difference_type n) { - current += n; - return *this; - } - mapped_iterator operator-(difference_type n) const { - return mapped_iterator(current - n, Fn); - } - mapped_iterator &operator-=(difference_type n) { - current -= n; - return *this; - } - reference operator[](difference_type n) const { return *(*this + n); } +} // end namespace adl_detail - bool operator!=(const mapped_iterator &X) const { return !operator==(X); } - bool operator==(const mapped_iterator &X) const { - return current == X.current; - } - bool operator<(const mapped_iterator &X) const { return current < X.current; } +template <typename ContainerTy> +auto adl_begin(ContainerTy &&container) + -> decltype(adl_detail::adl_begin(std::forward<ContainerTy>(container))) { + return adl_detail::adl_begin(std::forward<ContainerTy>(container)); +} - difference_type operator-(const mapped_iterator &X) const { - return current - X.current; - } -}; +template <typename ContainerTy> +auto adl_end(ContainerTy &&container) + -> decltype(adl_detail::adl_end(std::forward<ContainerTy>(container))) { + return adl_detail::adl_end(std::forward<ContainerTy>(container)); +} -template <class Iterator, class Func> -inline mapped_iterator<Iterator, Func> -operator+(typename mapped_iterator<Iterator, Func>::difference_type N, - const mapped_iterator<Iterator, Func> &X) { - return mapped_iterator<Iterator, Func>(X.getCurrent() - N, X.getFunc()); +template <typename T> +void adl_swap(T &&lhs, T &&rhs) noexcept( + noexcept(adl_detail::adl_swap(std::declval<T>(), std::declval<T>()))) { + adl_detail::adl_swap(std::forward<T>(lhs), std::forward<T>(rhs)); } +// mapped_iterator - This is a simple iterator adapter that causes a function to +// be applied whenever operator* is invoked on the iterator. + +template <typename ItTy, typename FuncTy, + typename FuncReturnTy = + decltype(std::declval<FuncTy>()(*std::declval<ItTy>()))> +class mapped_iterator + : public iterator_adaptor_base< + mapped_iterator<ItTy, FuncTy>, ItTy, + typename std::iterator_traits<ItTy>::iterator_category, + typename std::remove_reference<FuncReturnTy>::type> { +public: + mapped_iterator(ItTy U, FuncTy F) + : mapped_iterator::iterator_adaptor_base(std::move(U)), F(std::move(F)) {} + + ItTy getCurrent() { return this->I; } + + FuncReturnTy operator*() { return F(*this->I); } + +private: + FuncTy F; +}; // map_iterator - Provide a convenient way to create mapped_iterators, just like // make_pair is useful for creating pairs... -// template <class ItTy, class FuncTy> -inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) { - return mapped_iterator<ItTy, FuncTy>(I, F); +inline mapped_iterator<ItTy, FuncTy> map_iterator(ItTy I, FuncTy F) { + return mapped_iterator<ItTy, FuncTy>(std::move(I), std::move(F)); } /// Helper to determine if type T has a member called rbegin(). template <typename Ty> class has_rbegin_impl { - typedef char yes[1]; - typedef char no[2]; + using yes = char[1]; + using no = char[2]; template <typename Inner> static yes& test(Inner *I, decltype(I->rbegin()) * = nullptr); @@ -365,12 +347,13 @@ template <size_t... I> struct index_sequence; template <class... Ts> struct index_sequence_for; namespace detail { + using std::declval; // We have to alias this since inlining the actual type at the usage site // in the parameter list of iterator_facade_base<> below ICEs MSVC 2017. template<typename... Iters> struct ZipTupleType { - typedef std::tuple<decltype(*declval<Iters>())...> type; + using type = std::tuple<decltype(*declval<Iters>())...>; }; template <typename ZipType, typename... Iters> @@ -456,11 +439,11 @@ class zip_shortest : public zip_common<zip_shortest<Iters...>, Iters...> { public: using Base = zip_common<zip_shortest<Iters...>, Iters...>; + zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {} + bool operator==(const zip_shortest<Iters...> &other) const { return !test(other, index_sequence_for<Iters...>{}); } - - zip_shortest(Iters &&... ts) : Base(std::forward<Iters>(ts)...) {} }; template <template <typename...> class ItType, typename... Args> class zippy { @@ -483,11 +466,13 @@ private: } public: + zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {} + iterator begin() const { return begin_impl(index_sequence_for<Args...>{}); } iterator end() const { return end_impl(index_sequence_for<Args...>{}); } - zippy(Args &&... ts_) : ts(std::forward<Args>(ts_)...) {} }; -} // End detail namespace + +} // end namespace detail /// zip iterator for two or more iteratable types. template <typename T, typename U, typename... Args> @@ -520,7 +505,7 @@ template <typename ValueT, typename... IterTs> class concat_iterator : public iterator_facade_base<concat_iterator<ValueT, IterTs...>, std::forward_iterator_tag, ValueT> { - typedef typename concat_iterator::iterator_facade_base BaseT; + using BaseT = typename concat_iterator::iterator_facade_base; /// We store both the current and end iterators for each concatenated /// sequence in a tuple of pairs. @@ -597,6 +582,7 @@ public: : IterPairs({std::begin(Ranges), std::end(Ranges)}...) {} using BaseT::operator++; + concat_iterator &operator++() { increment(index_sequence_for<IterTs...>()); return *this; @@ -610,6 +596,7 @@ public: }; namespace detail { + /// Helper to store a sequence of ranges being concatenated and access them. /// /// This is designed to facilitate providing actual storage when temporaries @@ -617,9 +604,9 @@ namespace detail { /// based for loops. template <typename ValueT, typename... RangeTs> class concat_range { public: - typedef concat_iterator<ValueT, - decltype(std::begin(std::declval<RangeTs &>()))...> - iterator; + using iterator = + concat_iterator<ValueT, + decltype(std::begin(std::declval<RangeTs &>()))...>; private: std::tuple<RangeTs...> Ranges; @@ -633,12 +620,14 @@ private: } public: - iterator begin() { return begin_impl(index_sequence_for<RangeTs...>{}); } - iterator end() { return end_impl(index_sequence_for<RangeTs...>{}); } concat_range(RangeTs &&... Ranges) : Ranges(std::forward<RangeTs>(Ranges)...) {} + + iterator begin() { return begin_impl(index_sequence_for<RangeTs...>{}); } + iterator end() { return end_impl(index_sequence_for<RangeTs...>{}); } }; -} + +} // end namespace detail /// Concatenated range across two or more ranges. /// @@ -675,7 +664,7 @@ struct less_second { /// \brief Represents a compile-time sequence of integers. template <class T, T... I> struct integer_sequence { - typedef T value_type; + using value_type = T; static constexpr size_t size() { return sizeof...(I); } }; @@ -752,7 +741,6 @@ inline int (*get_array_pod_sort_comparator(const T &)) return array_pod_sort_comparator<T>; } - /// array_pod_sort - This sorts an array with the specified start and end /// extent. This is just like std::sort, except that it calls qsort instead of /// using an inlined template. qsort is slightly slower than std::sort, but @@ -812,96 +800,109 @@ void DeleteContainerSeconds(Container &C) { C.clear(); } +/// Provide wrappers to std::for_each which take ranges instead of having to +/// pass begin/end explicitly. +template <typename R, typename UnaryPredicate> +UnaryPredicate for_each(R &&Range, UnaryPredicate P) { + return std::for_each(adl_begin(Range), adl_end(Range), P); +} + /// Provide wrappers to std::all_of which take ranges instead of having to pass /// begin/end explicitly. template <typename R, typename UnaryPredicate> bool all_of(R &&Range, UnaryPredicate P) { - return std::all_of(std::begin(Range), std::end(Range), P); + return std::all_of(adl_begin(Range), adl_end(Range), P); } /// Provide wrappers to std::any_of which take ranges instead of having to pass /// begin/end explicitly. template <typename R, typename UnaryPredicate> bool any_of(R &&Range, UnaryPredicate P) { - return std::any_of(std::begin(Range), std::end(Range), P); + return std::any_of(adl_begin(Range), adl_end(Range), P); } /// Provide wrappers to std::none_of which take ranges instead of having to pass /// begin/end explicitly. template <typename R, typename UnaryPredicate> bool none_of(R &&Range, UnaryPredicate P) { - return std::none_of(std::begin(Range), std::end(Range), P); + return std::none_of(adl_begin(Range), adl_end(Range), P); } /// Provide wrappers to std::find which take ranges instead of having to pass /// begin/end explicitly. template <typename R, typename T> -auto find(R &&Range, const T &Val) -> decltype(std::begin(Range)) { - return std::find(std::begin(Range), std::end(Range), Val); +auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range)) { + return std::find(adl_begin(Range), adl_end(Range), Val); } /// Provide wrappers to std::find_if which take ranges instead of having to pass /// begin/end explicitly. template <typename R, typename UnaryPredicate> -auto find_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range)) { - return std::find_if(std::begin(Range), std::end(Range), P); +auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) { + return std::find_if(adl_begin(Range), adl_end(Range), P); } template <typename R, typename UnaryPredicate> -auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range)) { - return std::find_if_not(std::begin(Range), std::end(Range), P); +auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) { + return std::find_if_not(adl_begin(Range), adl_end(Range), P); } /// Provide wrappers to std::remove_if which take ranges instead of having to /// pass begin/end explicitly. template <typename R, typename UnaryPredicate> -auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range)) { - return std::remove_if(std::begin(Range), std::end(Range), P); +auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) { + return std::remove_if(adl_begin(Range), adl_end(Range), P); } /// Provide wrappers to std::copy_if which take ranges instead of having to /// pass begin/end explicitly. template <typename R, typename OutputIt, typename UnaryPredicate> OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) { - return std::copy_if(std::begin(Range), std::end(Range), Out, P); + return std::copy_if(adl_begin(Range), adl_end(Range), Out, P); } /// Wrapper function around std::find to detect if an element exists /// in a container. template <typename R, typename E> bool is_contained(R &&Range, const E &Element) { - return std::find(std::begin(Range), std::end(Range), Element) != - std::end(Range); + return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range); } /// Wrapper function around std::count to count the number of times an element /// \p Element occurs in the given range \p Range. template <typename R, typename E> -auto count(R &&Range, const E &Element) -> typename std::iterator_traits< - decltype(std::begin(Range))>::difference_type { - return std::count(std::begin(Range), std::end(Range), Element); +auto count(R &&Range, const E &Element) -> + typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type { + return std::count(adl_begin(Range), adl_end(Range), Element); } /// Wrapper function around std::count_if to count the number of times an /// element satisfying a given predicate occurs in a range. template <typename R, typename UnaryPredicate> -auto count_if(R &&Range, UnaryPredicate P) -> typename std::iterator_traits< - decltype(std::begin(Range))>::difference_type { - return std::count_if(std::begin(Range), std::end(Range), P); +auto count_if(R &&Range, UnaryPredicate P) -> + typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type { + return std::count_if(adl_begin(Range), adl_end(Range), P); } /// Wrapper function around std::transform to apply a function to a range and /// store the result elsewhere. template <typename R, typename OutputIt, typename UnaryPredicate> OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) { - return std::transform(std::begin(Range), std::end(Range), d_first, P); + return std::transform(adl_begin(Range), adl_end(Range), d_first, P); } /// Provide wrappers to std::partition which take ranges instead of having to /// pass begin/end explicitly. template <typename R, typename UnaryPredicate> -auto partition(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range)) { - return std::partition(std::begin(Range), std::end(Range), P); +auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) { + return std::partition(adl_begin(Range), adl_end(Range), P); +} + +/// Provide wrappers to std::lower_bound which take ranges instead of having to +/// pass begin/end explicitly. +template <typename R, typename ForwardIt> +auto lower_bound(R &&Range, ForwardIt I) -> decltype(adl_begin(Range)) { + return std::lower_bound(adl_begin(Range), adl_end(Range), I); } /// \brief Given a range of type R, iterate the entire range and return a @@ -910,7 +911,7 @@ auto partition(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range)) { template <unsigned Size, typename R> SmallVector<typename std::remove_const<detail::ValueOfRange<R>>::type, Size> to_vector(R &&Range) { - return {std::begin(Range), std::end(Range)}; + return {adl_begin(Range), adl_end(Range)}; } /// Provide a container algorithm similar to C++ Library Fundamentals v2's @@ -995,6 +996,7 @@ struct equal { /// operands. template <typename T> struct deref { T func; + // Could be further improved to cope with non-derivable functors and // non-binary functors (should be a variadic template member function // operator()). @@ -1007,12 +1009,13 @@ template <typename T> struct deref { }; namespace detail { + template <typename R> class enumerator_iter; template <typename R> struct result_pair { friend class enumerator_iter<R>; - result_pair() : Index(-1) {} + result_pair() = default; result_pair(std::size_t Index, IterOfRange<R> Iter) : Index(Index), Iter(Iter) {} @@ -1027,7 +1030,7 @@ template <typename R> struct result_pair { ValueOfRange<R> &value() { return *Iter; } private: - std::size_t Index; + std::size_t Index = std::numeric_limits<std::size_t>::max(); IterOfRange<R> Iter; }; @@ -1042,7 +1045,7 @@ class enumerator_iter public: explicit enumerator_iter(IterOfRange<R> EndIter) - : Result(std::numeric_limits<size_t>::max(), EndIter) { } + : Result(std::numeric_limits<size_t>::max(), EndIter) {} enumerator_iter(std::size_t Index, IterOfRange<R> Iter) : Result(Index, Iter) {} @@ -1080,6 +1083,7 @@ public: enumerator_iter<R> begin() { return enumerator_iter<R>(0, std::begin(TheRange)); } + enumerator_iter<R> end() { return enumerator_iter<R>(std::end(TheRange)); } @@ -1087,7 +1091,8 @@ public: private: R TheRange; }; -} + +} // end namespace detail /// Given an input range, returns a new range whose values are are pair (A,B) /// such that A is the 0-based index of the item in the sequence, and B is @@ -1109,12 +1114,14 @@ template <typename R> detail::enumerator<R> enumerate(R &&TheRange) { } namespace detail { + template <typename F, typename Tuple, std::size_t... I> auto apply_tuple_impl(F &&f, Tuple &&t, index_sequence<I...>) -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...)) { return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...); } -} + +} // end namespace detail /// Given an input tuple (a1, a2, ..., an), pass the arguments of the /// tuple variadically to f as if by calling f(a1, a2, ..., an) and @@ -1130,6 +1137,7 @@ auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl( return detail::apply_tuple_impl(std::forward<F>(f), std::forward<Tuple>(t), Indices{}); } -} // End llvm namespace -#endif +} // end namespace llvm + +#endif // LLVM_ADT_STLEXTRAS_H diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 4e8a2490ee3c5..78ea613af693b 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -15,8 +15,8 @@ #ifndef LLVM_ADT_SMALLPTRSET_H #define LLVM_ADT_SMALLPTRSET_H +#include "llvm/ADT/EpochTracker.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm/Support/ReverseIteration.h" #include "llvm/Support/type_traits.h" #include <cassert> @@ -47,7 +47,7 @@ namespace llvm { /// (-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 SmallPtrSetImplBase { +class SmallPtrSetImplBase : public DebugEpochBase { friend class SmallPtrSetIteratorImpl; protected: @@ -93,6 +93,7 @@ public: size_type size() const { return NumNonEmpty - NumTombstones; } void clear() { + incrementEpoch(); // If the capacity of the array is huge, and the # elements used is small, // shrink the array. if (!isSmall()) { @@ -139,12 +140,14 @@ protected: if (LastTombstone != nullptr) { *LastTombstone = Ptr; --NumTombstones; + incrementEpoch(); return std::make_pair(LastTombstone, true); } // Nope, there isn't. If we stay small, just 'pushback' now. if (NumNonEmpty < CurArraySize) { SmallArray[NumNonEmpty++] = Ptr; + incrementEpoch(); return std::make_pair(SmallArray + (NumNonEmpty - 1), true); } // Otherwise, hit the big set case, which will call grow. @@ -224,12 +227,10 @@ protected: public: explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E) : Bucket(BP), End(E) { -#if LLVM_ENABLE_ABI_BREAKING_CHECKS - if (ReverseIterate<bool>::value) { + if (shouldReverseIterate()) { RetreatIfNotValid(); return; } -#endif AdvanceIfNotValid(); } @@ -251,7 +252,6 @@ protected: *Bucket == SmallPtrSetImplBase::getTombstoneMarker())) ++Bucket; } -#if LLVM_ENABLE_ABI_BREAKING_CHECKS void RetreatIfNotValid() { assert(Bucket >= End); while (Bucket != End && @@ -260,12 +260,12 @@ protected: --Bucket; } } -#endif }; /// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet. -template<typename PtrTy> -class SmallPtrSetIterator : public SmallPtrSetIteratorImpl { +template <typename PtrTy> +class SmallPtrSetIterator : public SmallPtrSetIteratorImpl, + DebugEpochBase::HandleBase { using PtrTraits = PointerLikeTypeTraits<PtrTy>; public: @@ -275,30 +275,29 @@ public: using difference_type = std::ptrdiff_t; using iterator_category = std::forward_iterator_tag; - explicit SmallPtrSetIterator(const void *const *BP, const void *const *E) - : SmallPtrSetIteratorImpl(BP, E) {} + explicit SmallPtrSetIterator(const void *const *BP, const void *const *E, + const DebugEpochBase &Epoch) + : SmallPtrSetIteratorImpl(BP, E), DebugEpochBase::HandleBase(&Epoch) {} // Most methods provided by baseclass. const PtrTy operator*() const { -#if LLVM_ENABLE_ABI_BREAKING_CHECKS - if (ReverseIterate<bool>::value) { + assert(isHandleInSync() && "invalid iterator access!"); + if (shouldReverseIterate()) { assert(Bucket > End); return PtrTraits::getFromVoidPointer(const_cast<void *>(Bucket[-1])); } -#endif assert(Bucket < End); return PtrTraits::getFromVoidPointer(const_cast<void*>(*Bucket)); } inline SmallPtrSetIterator& operator++() { // Preincrement -#if LLVM_ENABLE_ABI_BREAKING_CHECKS - if (ReverseIterate<bool>::value) { + assert(isHandleInSync() && "invalid iterator access!"); + if (shouldReverseIterate()) { --Bucket; RetreatIfNotValid(); return *this; } -#endif ++Bucket; AdvanceIfNotValid(); return *this; @@ -396,10 +395,8 @@ public: } iterator begin() const { -#if LLVM_ENABLE_ABI_BREAKING_CHECKS - if (ReverseIterate<bool>::value) + if (shouldReverseIterate()) return makeIterator(EndPointer() - 1); -#endif return makeIterator(CurArray); } iterator end() const { return makeIterator(EndPointer()); } @@ -407,11 +404,9 @@ public: private: /// Create an iterator that dereferences to same place as the given pointer. iterator makeIterator(const void *const *P) const { -#if LLVM_ENABLE_ABI_BREAKING_CHECKS - if (ReverseIterate<bool>::value) - return iterator(P == EndPointer() ? CurArray : P + 1, CurArray); -#endif - return iterator(P, EndPointer()); + if (shouldReverseIterate()) + return iterator(P == EndPointer() ? CurArray : P + 1, CurArray, *this); + return iterator(P, EndPointer(), *this); } }; diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index bf2a62f43affc..a9ac98d1ad4c9 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -19,6 +19,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/type_traits.h" +#include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <cassert> #include <cstddef> @@ -238,6 +239,8 @@ void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) { if (NewCapacity < MinSize) NewCapacity = MinSize; T *NewElts = static_cast<T*>(malloc(NewCapacity*sizeof(T))); + if (NewElts == nullptr) + report_bad_alloc_error("Allocation of SmallVector element failed."); // Move the elements over. this->uninitialized_move(this->begin(), this->end(), NewElts); @@ -924,8 +927,8 @@ public: } }; -template<typename T, unsigned N> -static inline size_t capacity_in_bytes(const SmallVector<T, N> &X) { +template <typename T, unsigned N> +inline size_t capacity_in_bytes(const SmallVector<T, N> &X) { return X.capacity_in_bytes(); } diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index cc32bf43f29c8..60652f8c55c5a 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -17,6 +17,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -33,33 +34,65 @@ class raw_ostream; /// hexdigit - Return the hexadecimal character for the /// given number \p X (which should be less than 16). -static inline char hexdigit(unsigned X, bool LowerCase = false) { +inline char hexdigit(unsigned X, bool LowerCase = false) { const char HexChar = LowerCase ? 'a' : 'A'; 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"); -} +inline StringRef toStringRef(bool B) { return StringRef(B ? "true" : "false"); } /// Construct a string ref from an array ref of unsigned chars. -static inline StringRef toStringRef(ArrayRef<uint8_t> Input) { +inline StringRef toStringRef(ArrayRef<uint8_t> Input) { return StringRef(reinterpret_cast<const char *>(Input.begin()), Input.size()); } +/// Construct a string ref from an array ref of unsigned chars. +inline ArrayRef<uint8_t> arrayRefFromStringRef(StringRef Input) { + return {Input.bytes_begin(), Input.bytes_end()}; +} + /// Interpret the given character \p C as a hexadecimal digit and return its /// value. /// /// If \p C is not a valid hex digit, -1U is returned. -static inline unsigned hexDigitValue(char C) { +inline unsigned hexDigitValue(char C) { if (C >= '0' && C <= '9') return C-'0'; if (C >= 'a' && C <= 'f') return C-'a'+10U; if (C >= 'A' && C <= 'F') return C-'A'+10U; return -1U; } -static inline std::string utohexstr(uint64_t X, bool LowerCase = false) { +/// Checks if character \p C is one of the 10 decimal digits. +inline bool isDigit(char C) { return C >= '0' && C <= '9'; } + +/// Checks if character \p C is a hexadecimal numeric character. +inline bool isHexDigit(char C) { return hexDigitValue(C) != -1U; } + +/// Checks if character \p C is a valid letter as classified by "C" locale. +inline bool isAlpha(char C) { + return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z'); +} + +/// Checks whether character \p C is either a decimal digit or an uppercase or +/// lowercase letter as classified by "C" locale. +inline bool isAlnum(char C) { return isAlpha(C) || isDigit(C); } + +/// Returns the corresponding lowercase character if \p x is uppercase. +inline char toLower(char x) { + if (x >= 'A' && x <= 'Z') + return x - 'A' + 'a'; + return x; +} + +/// Returns the corresponding uppercase character if \p x is lowercase. +inline char toUpper(char x) { + if (x >= 'a' && x <= 'z') + return x - 'a' + 'A'; + return x; +} + +inline std::string utohexstr(uint64_t X, bool LowerCase = false) { char Buffer[17]; char *BufPtr = std::end(Buffer); @@ -94,7 +127,7 @@ inline std::string toHex(ArrayRef<uint8_t> Input) { return toHex(toStringRef(Input)); } -static inline uint8_t hexFromNibbles(char MSB, char LSB) { +inline uint8_t hexFromNibbles(char MSB, char LSB) { unsigned U1 = hexDigitValue(MSB); unsigned U2 = hexDigitValue(LSB); assert(U1 != -1U && U2 != -1U); @@ -104,7 +137,7 @@ static inline uint8_t hexFromNibbles(char MSB, char LSB) { /// Convert hexadecimal string \p Input to its binary representation. /// The return string is half the size of \p Input. -static inline std::string fromHex(StringRef Input) { +inline std::string fromHex(StringRef Input) { if (Input.empty()) return std::string(); @@ -157,7 +190,7 @@ inline bool to_float(const Twine &T, long double &Num) { return detail::to_float(T, Num, strtold); } -static inline std::string utostr(uint64_t X, bool isNeg = false) { +inline std::string utostr(uint64_t X, bool isNeg = false) { char Buffer[21]; char *BufPtr = std::end(Buffer); @@ -172,7 +205,7 @@ static inline std::string utostr(uint64_t X, bool isNeg = false) { return std::string(BufPtr, std::end(Buffer)); } -static inline std::string itostr(int64_t X) { +inline std::string itostr(int64_t X) { if (X < 0) return utostr(static_cast<uint64_t>(-X), true); else @@ -206,14 +239,14 @@ void SplitString(StringRef Source, // FIXME: Investigate whether a modified bernstein hash function performs // better: http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx // X*33+c -> X*33^c -static inline unsigned HashString(StringRef Str, unsigned Result = 0) { +inline unsigned HashString(StringRef Str, unsigned Result = 0) { for (StringRef::size_type i = 0, e = Str.size(); i != e; ++i) Result = Result * 33 + (unsigned char)Str[i]; return Result; } /// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th). -static inline StringRef getOrdinalSuffix(unsigned Val) { +inline StringRef getOrdinalSuffix(unsigned Val) { // It is critically important that we do this perfectly for // user-written sequences with over 100 elements. switch (Val % 100) { @@ -235,6 +268,9 @@ static inline StringRef getOrdinalSuffix(unsigned Val) { /// it if it is not printable or if it is an escape char. void PrintEscapedString(StringRef Name, raw_ostream &Out); +/// printLowerCase - Print each character as lowercase if it is uppercase. +void printLowerCase(StringRef String, raw_ostream &Out); + namespace detail { template <typename IteratorT> diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h index d573148665a1a..6c2830b44914f 100644 --- a/include/llvm/ADT/StringMap.h +++ b/include/llvm/ADT/StringMap.h @@ -19,6 +19,7 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <cassert> #include <cstdint> @@ -165,6 +166,9 @@ public: StringMapEntry *NewItem = static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment)); + if (NewItem == nullptr) + report_bad_alloc_error("Allocation of StringMap entry failed."); + // Construct the value. new (NewItem) StringMapEntry(KeyLength, std::forward<InitTy>(InitVals)...); diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h index 79740713f75b0..73573d65e2b39 100644 --- a/include/llvm/ADT/TinyPtrVector.h +++ b/include/llvm/ADT/TinyPtrVector.h @@ -97,6 +97,7 @@ public: if (RHS.Val.template is<EltTy>()) { V->clear(); V->push_back(RHS.front()); + RHS.Val = (EltTy)nullptr; return *this; } delete V; diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index cd560658ca4ec..74fc8eb8ccbfd 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -50,6 +50,7 @@ public: armeb, // ARM (big endian): armeb aarch64, // AArch64 (little endian): aarch64 aarch64_be, // AArch64 (big endian): aarch64_be + arc, // ARC: Synopsys ARC avr, // AVR: Atmel AVR microcontroller bpfel, // eBPF or extended BPF or 64-bit BPF (little endian) bpfeb, // eBPF or extended BPF or 64-bit BPF (big endian) @@ -100,6 +101,7 @@ public: enum SubArchType { NoSubArch, + ARMSubArch_v8_3a, ARMSubArch_v8_2a, ARMSubArch_v8_1a, ARMSubArch_v8, @@ -167,7 +169,6 @@ public: RTEMS, NaCl, // Native Client CNK, // BG/P Compute-Node Kernel - Bitrig, AIX, CUDA, // NVIDIA CUDA NVCL, // NVIDIA OpenCL @@ -178,12 +179,14 @@ public: WatchOS, // Apple watchOS Mesa3D, Contiki, - LastOSType = Contiki + AMDPAL, // AMD PAL Runtime + LastOSType = AMDPAL }; enum EnvironmentType { UnknownEnvironment, GNU, + GNUABIN32, GNUABI64, GNUEABI, GNUEABIHF, @@ -202,7 +205,8 @@ public: AMDOpenCL, CoreCLR, OpenCL, - LastEnvironmentType = OpenCL + Simulator, // Simulator variants of other systems, e.g., Apple's iOS + LastEnvironmentType = Simulator }; enum ObjectFormatType { UnknownObjectFormat, @@ -467,6 +471,10 @@ public: return isMacOSX() || isiOS() || isWatchOS(); } + bool isSimulatorEnvironment() const { + return getEnvironment() == Triple::Simulator; + } + bool isOSNetBSD() const { return getOS() == Triple::NetBSD; } @@ -489,25 +497,28 @@ public: return getOS() == Triple::Solaris; } - bool isOSBitrig() const { - return getOS() == Triple::Bitrig; - } - bool isOSIAMCU() const { return getOS() == Triple::ELFIAMCU; } + bool isOSUnknown() const { return getOS() == Triple::UnknownOS; } + bool isGNUEnvironment() const { EnvironmentType Env = getEnvironment(); - return Env == Triple::GNU || Env == Triple::GNUABI64 || - Env == Triple::GNUEABI || Env == Triple::GNUEABIHF || - Env == Triple::GNUX32; + return Env == Triple::GNU || Env == Triple::GNUABIN32 || + Env == Triple::GNUABI64 || Env == Triple::GNUEABI || + Env == Triple::GNUEABIHF || Env == Triple::GNUX32; } bool isOSContiki() const { return getOS() == Triple::Contiki; } + /// Tests whether the OS is Haiku. + bool isOSHaiku() const { + return getOS() == Triple::Haiku; + } + /// Checks if the environment could be MSVC. bool isWindowsMSVCEnvironment() const { return getOS() == Triple::Win32 && @@ -634,8 +645,25 @@ public: return getArch() == Triple::nvptx || getArch() == Triple::nvptx64; } + /// Tests whether the target is Thumb (little and big endian). + bool isThumb() const { + return getArch() == Triple::thumb || getArch() == Triple::thumbeb; + } + + /// Tests whether the target is ARM (little and big endian). + bool isARM() const { + return getArch() == Triple::arm || getArch() == Triple::armeb; + } + + /// Tests whether the target is AArch64 (little and big endian). + bool isAArch64() const { + return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be; + } + /// Tests wether the target supports comdat - bool supportsCOMDAT() const { return !isOSBinFormatMachO(); } + bool supportsCOMDAT() const { + return !isOSBinFormatMachO() && !isOSBinFormatWasm(); + } /// @} /// @name Mutators diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h index f5f00dcfafe5f..b60fd09813988 100644 --- a/include/llvm/ADT/Twine.h +++ b/include/llvm/ADT/Twine.h @@ -1,4 +1,4 @@ -//===-- Twine.h - Fast Temporary String Concatenation -----------*- C++ -*-===// +//===- Twine.h - Fast Temporary String Concatenation ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -155,17 +155,19 @@ namespace llvm { /// LHS - The prefix in the concatenation, which may be uninitialized for /// Null or Empty kinds. Child LHS; + /// RHS - The suffix in the concatenation, which may be uninitialized for /// Null or Empty kinds. Child RHS; + /// LHSKind - The NodeKind of the left hand side, \see getLHSKind(). - NodeKind LHSKind; + NodeKind LHSKind = EmptyKind; + /// RHSKind - The NodeKind of the right hand side, \see getRHSKind(). - NodeKind RHSKind; + NodeKind RHSKind = EmptyKind; /// Construct a nullary twine; the kind must be NullKind or EmptyKind. - explicit Twine(NodeKind Kind) - : LHSKind(Kind), RHSKind(EmptyKind) { + explicit Twine(NodeKind Kind) : LHSKind(Kind) { assert(isNullary() && "Invalid kind!"); } @@ -252,7 +254,7 @@ namespace llvm { /// @{ /// Construct from an empty string. - /*implicit*/ Twine() : LHSKind(EmptyKind), RHSKind(EmptyKind) { + /*implicit*/ Twine() { assert(isValid() && "Invalid twine!"); } @@ -263,8 +265,7 @@ namespace llvm { /// We take care here to optimize "" into the empty twine -- this will be /// optimized out for string constants. This allows Twine arguments have /// default "" values, without introducing unnecessary string constants. - /*implicit*/ Twine(const char *Str) - : RHSKind(EmptyKind) { + /*implicit*/ Twine(const char *Str) { if (Str[0] != '\0') { LHS.cString = Str; LHSKind = CStringKind; @@ -275,84 +276,73 @@ namespace llvm { } /// Construct from an std::string. - /*implicit*/ Twine(const std::string &Str) - : LHSKind(StdStringKind), RHSKind(EmptyKind) { + /*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) { LHS.stdString = &Str; assert(isValid() && "Invalid twine!"); } /// Construct from a StringRef. - /*implicit*/ Twine(const StringRef &Str) - : LHSKind(StringRefKind), RHSKind(EmptyKind) { + /*implicit*/ Twine(const StringRef &Str) : LHSKind(StringRefKind) { LHS.stringRef = &Str; assert(isValid() && "Invalid twine!"); } /// Construct from a SmallString. /*implicit*/ Twine(const SmallVectorImpl<char> &Str) - : LHSKind(SmallStringKind), RHSKind(EmptyKind) { + : LHSKind(SmallStringKind) { LHS.smallString = &Str; assert(isValid() && "Invalid twine!"); } /// Construct from a formatv_object_base. /*implicit*/ Twine(const formatv_object_base &Fmt) - : LHSKind(FormatvObjectKind), RHSKind(EmptyKind) { + : LHSKind(FormatvObjectKind) { LHS.formatvObject = &Fmt; assert(isValid() && "Invalid twine!"); } /// Construct from a char. - explicit Twine(char Val) - : LHSKind(CharKind), RHSKind(EmptyKind) { + explicit Twine(char Val) : LHSKind(CharKind) { LHS.character = Val; } /// Construct from a signed char. - explicit Twine(signed char Val) - : LHSKind(CharKind), RHSKind(EmptyKind) { + explicit Twine(signed char Val) : LHSKind(CharKind) { LHS.character = static_cast<char>(Val); } /// Construct from an unsigned char. - explicit Twine(unsigned char Val) - : LHSKind(CharKind), RHSKind(EmptyKind) { + explicit Twine(unsigned char Val) : LHSKind(CharKind) { LHS.character = static_cast<char>(Val); } /// Construct a twine to print \p Val as an unsigned decimal integer. - explicit Twine(unsigned Val) - : LHSKind(DecUIKind), RHSKind(EmptyKind) { + explicit Twine(unsigned Val) : LHSKind(DecUIKind) { LHS.decUI = Val; } /// Construct a twine to print \p Val as a signed decimal integer. - explicit Twine(int Val) - : LHSKind(DecIKind), RHSKind(EmptyKind) { + explicit Twine(int Val) : LHSKind(DecIKind) { LHS.decI = Val; } /// Construct a twine to print \p Val as an unsigned decimal integer. - explicit Twine(const unsigned long &Val) - : LHSKind(DecULKind), RHSKind(EmptyKind) { + explicit Twine(const unsigned long &Val) : LHSKind(DecULKind) { LHS.decUL = &Val; } /// Construct a twine to print \p Val as a signed decimal integer. - explicit Twine(const long &Val) - : LHSKind(DecLKind), RHSKind(EmptyKind) { + explicit Twine(const long &Val) : LHSKind(DecLKind) { LHS.decL = &Val; } /// Construct a twine to print \p Val as an unsigned decimal integer. - explicit Twine(const unsigned long long &Val) - : LHSKind(DecULLKind), RHSKind(EmptyKind) { + explicit Twine(const unsigned long long &Val) : LHSKind(DecULLKind) { LHS.decULL = &Val; } /// Construct a twine to print \p Val as a signed decimal integer. - explicit Twine(const long long &Val) - : LHSKind(DecLLKind), RHSKind(EmptyKind) { + explicit Twine(const long long &Val) : LHSKind(DecLLKind) { LHS.decLL = &Val; } diff --git a/include/llvm/ADT/iterator.h b/include/llvm/ADT/iterator.h index 15720a67c047b..711f8f2216209 100644 --- a/include/llvm/ADT/iterator.h +++ b/include/llvm/ADT/iterator.h @@ -70,10 +70,10 @@ class iterator_facade_base ReferenceT> { protected: enum { - IsRandomAccess = - std::is_base_of<std::random_access_iterator_tag, IteratorCategoryT>::value, - IsBidirectional = - std::is_base_of<std::bidirectional_iterator_tag, IteratorCategoryT>::value, + IsRandomAccess = std::is_base_of<std::random_access_iterator_tag, + IteratorCategoryT>::value, + IsBidirectional = std::is_base_of<std::bidirectional_iterator_tag, + IteratorCategoryT>::value, }; /// A proxy object for computing a reference via indirecting a copy of an |