diff options
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r-- | include/llvm/ADT/APInt.h | 64 | ||||
-rw-r--r-- | include/llvm/ADT/APSInt.h | 12 | ||||
-rw-r--r-- | include/llvm/ADT/ArrayRef.h | 14 | ||||
-rw-r--r-- | include/llvm/ADT/DenseMap.h | 13 | ||||
-rw-r--r-- | include/llvm/ADT/ImmutableMap.h | 1 | ||||
-rw-r--r-- | include/llvm/ADT/ImmutableSet.h | 13 | ||||
-rw-r--r-- | include/llvm/ADT/PointerIntPair.h | 3 | ||||
-rw-r--r-- | include/llvm/ADT/PointerUnion.h | 13 | ||||
-rw-r--r-- | include/llvm/ADT/STLExtras.h | 28 | ||||
-rw-r--r-- | include/llvm/ADT/SetVector.h | 2 | ||||
-rw-r--r-- | include/llvm/ADT/SmallPtrSet.h | 2 | ||||
-rw-r--r-- | include/llvm/ADT/SmallVector.h | 4 | ||||
-rw-r--r-- | include/llvm/ADT/StringExtras.h | 43 | ||||
-rw-r--r-- | include/llvm/ADT/StringRef.h | 8 | ||||
-rw-r--r-- | include/llvm/ADT/Triple.h | 13 | ||||
-rw-r--r-- | include/llvm/ADT/ilist.h | 6 | ||||
-rw-r--r-- | include/llvm/ADT/polymorphic_ptr.h | 117 |
17 files changed, 298 insertions, 58 deletions
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 625a6dbfd6..d494ad2535 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -765,7 +765,9 @@ public: return APInt(getBitWidth(), VAL & RHS.VAL); return AndSlowCase(RHS); } - APInt And(const APInt &RHS) const { return this->operator&(RHS); } + APInt LLVM_ATTRIBUTE_UNUSED_RESULT And(const APInt &RHS) const { + return this->operator&(RHS); + } /// \brief Bitwise OR operator. /// @@ -785,7 +787,9 @@ public: /// calling operator|. /// /// \returns An APInt value representing the bitwise OR of *this and RHS. - APInt Or(const APInt &RHS) const { return this->operator|(RHS); } + APInt LLVM_ATTRIBUTE_UNUSED_RESULT Or(const APInt &RHS) const { + return this->operator|(RHS); + } /// \brief Bitwise XOR operator. /// @@ -805,7 +809,9 @@ public: /// through the usage of operator^. /// /// \returns An APInt value representing the bitwise XOR of *this and RHS. - APInt Xor(const APInt &RHS) const { return this->operator^(RHS); } + APInt LLVM_ATTRIBUTE_UNUSED_RESULT Xor(const APInt &RHS) const { + return this->operator^(RHS); + } /// \brief Multiplication operator. /// @@ -837,17 +843,17 @@ public: /// \brief Arithmetic right-shift function. /// /// Arithmetic right-shift this APInt by shiftAmt. - APInt ashr(unsigned shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT ashr(unsigned shiftAmt) const; /// \brief Logical right-shift function. /// /// Logical right-shift this APInt by shiftAmt. - APInt lshr(unsigned shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT lshr(unsigned shiftAmt) const; /// \brief Left-shift function. /// /// Left-shift this APInt by shiftAmt. - APInt shl(unsigned shiftAmt) const { + APInt LLVM_ATTRIBUTE_UNUSED_RESULT shl(unsigned shiftAmt) const { assert(shiftAmt <= BitWidth && "Invalid shift amount"); if (isSingleWord()) { if (shiftAmt >= BitWidth) @@ -858,31 +864,31 @@ public: } /// \brief Rotate left by rotateAmt. - APInt rotl(unsigned rotateAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotl(unsigned rotateAmt) const; /// \brief Rotate right by rotateAmt. - APInt rotr(unsigned rotateAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotr(unsigned rotateAmt) const; /// \brief Arithmetic right-shift function. /// /// Arithmetic right-shift this APInt by shiftAmt. - APInt ashr(const APInt &shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT ashr(const APInt &shiftAmt) const; /// \brief Logical right-shift function. /// /// Logical right-shift this APInt by shiftAmt. - APInt lshr(const APInt &shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT lshr(const APInt &shiftAmt) const; /// \brief Left-shift function. /// /// Left-shift this APInt by shiftAmt. - APInt shl(const APInt &shiftAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT shl(const APInt &shiftAmt) const; /// \brief Rotate left by rotateAmt. - APInt rotl(const APInt &rotateAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotl(const APInt &rotateAmt) const; /// \brief Rotate right by rotateAmt. - APInt rotr(const APInt &rotateAmt) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT rotr(const APInt &rotateAmt) const; /// \brief Unsigned division operation. /// @@ -890,12 +896,12 @@ public: /// RHS are treated as unsigned quantities for purposes of this division. /// /// \returns a new APInt value containing the division result - APInt udiv(const APInt &RHS) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT udiv(const APInt &RHS) const; /// \brief Signed division function for APInt. /// /// Signed divide this APInt by APInt RHS. - APInt sdiv(const APInt &RHS) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sdiv(const APInt &RHS) const; /// \brief Unsigned remainder operation. /// @@ -906,12 +912,12 @@ public: /// is *this. /// /// \returns a new APInt value containing the remainder result - APInt urem(const APInt &RHS) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT urem(const APInt &RHS) const; /// \brief Function for signed remainder operation. /// /// Signed remainder operation on APInt. - APInt srem(const APInt &RHS) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT srem(const APInt &RHS) const; /// \brief Dual division/remainder interface. /// @@ -1145,7 +1151,7 @@ public: /// /// Truncate the APInt to a specified width. It is an error to specify a width /// that is greater than or equal to the current width. - APInt trunc(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(unsigned width) const; /// \brief Sign extend to a new width. /// @@ -1153,38 +1159,38 @@ public: /// bit is set, the fill on the left will be done with 1 bits, otherwise zero. /// It is an error to specify a width that is less than or equal to the /// current width. - APInt sext(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sext(unsigned width) const; /// \brief Zero extend to a new width. /// /// This operation zero extends the APInt to a new width. The high order bits /// are filled with 0 bits. It is an error to specify a width that is less /// than or equal to the current width. - APInt zext(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT zext(unsigned width) const; /// \brief Sign extend or truncate to width /// /// Make this APInt have the bit width given by \p width. The value is sign /// extended, truncated, or left alone to make it that width. - APInt sextOrTrunc(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sextOrTrunc(unsigned width) const; /// \brief Zero extend or truncate to width /// /// Make this APInt have the bit width given by \p width. The value is zero /// extended, truncated, or left alone to make it that width. - APInt zextOrTrunc(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT zextOrTrunc(unsigned width) const; /// \brief Sign extend or truncate to width /// /// Make this APInt have the bit width given by \p width. The value is sign /// extended, or left alone to make it that width. - APInt sextOrSelf(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sextOrSelf(unsigned width) const; /// \brief Zero extend or truncate to width /// /// Make this APInt have the bit width given by \p width. The value is zero /// extended, or left alone to make it that width. - APInt zextOrSelf(unsigned width) const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT zextOrSelf(unsigned width) const; /// @} /// \name Bit Manipulation Operators @@ -1421,7 +1427,7 @@ public: std::string toString(unsigned Radix, bool Signed) const; /// \returns a byte-swapped representation of this APInt Value. - APInt byteSwap() const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT byteSwap() const; /// \brief Converts this APInt to a double value. double roundToDouble(bool isSigned) const; @@ -1464,7 +1470,7 @@ public: /// /// The conversion does not do a translation from double to integer, it just /// re-interprets the bits of the double. - static APInt doubleToBits(double V) { + static APInt LLVM_ATTRIBUTE_UNUSED_RESULT doubleToBits(double V) { union { uint64_t I; double D; @@ -1477,7 +1483,7 @@ public: /// /// The conversion does not do a translation from float to integer, it just /// re-interprets the bits of the float. - static APInt floatToBits(float V) { + static APInt LLVM_ATTRIBUTE_UNUSED_RESULT floatToBits(float V) { union { unsigned I; float F; @@ -1507,12 +1513,12 @@ public: } /// \brief Compute the square root - APInt sqrt() const; + APInt LLVM_ATTRIBUTE_UNUSED_RESULT sqrt() const; /// \brief Get the absolute value; /// /// If *this is < 0 then return -(*this), otherwise *this; - APInt abs() const { + APInt LLVM_ATTRIBUTE_UNUSED_RESULT abs() const { if (isNegative()) return -(*this); return *this; diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h index 11be4c513e..ad035a7c30 100644 --- a/include/llvm/ADT/APSInt.h +++ b/include/llvm/ADT/APSInt.h @@ -68,18 +68,18 @@ public: } using APInt::toString; - APSInt trunc(uint32_t width) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT trunc(uint32_t width) const { return APSInt(APInt::trunc(width), IsUnsigned); } - APSInt extend(uint32_t width) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extend(uint32_t width) const { if (IsUnsigned) return APSInt(zext(width), IsUnsigned); else return APSInt(sext(width), IsUnsigned); } - APSInt extOrTrunc(uint32_t width) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT extOrTrunc(uint32_t width) const { if (IsUnsigned) return APSInt(zextOrTrunc(width), IsUnsigned); else @@ -212,7 +212,7 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast<const APInt&>(*this) & RHS, IsUnsigned); } - APSInt And(const APSInt& RHS) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT And(const APSInt& RHS) const { return this->operator&(RHS); } @@ -220,7 +220,7 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast<const APInt&>(*this) | RHS, IsUnsigned); } - APSInt Or(const APSInt& RHS) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Or(const APSInt& RHS) const { return this->operator|(RHS); } @@ -229,7 +229,7 @@ public: assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!"); return APSInt(static_cast<const APInt&>(*this) ^ RHS, IsUnsigned); } - APSInt Xor(const APSInt& RHS) const { + APSInt LLVM_ATTRIBUTE_UNUSED_RESULT Xor(const APSInt& RHS) const { return this->operator^(RHS); } diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h index d4152ec727..e5562c3683 100644 --- a/include/llvm/ADT/ArrayRef.h +++ b/include/llvm/ADT/ArrayRef.h @@ -80,9 +80,16 @@ namespace llvm { /// Construct an ArrayRef from a C array. template <size_t N> - /*implicit*/ ArrayRef(const T (&Arr)[N]) + /*implicit*/ LLVM_CONSTEXPR ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {} +#if LLVM_HAS_INITIALIZER_LISTS + /// Construct an ArrayRef from a std::initializer_list. + /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec) + : Data(Vec.begin() == Vec.end() ? (T*)0 : Vec.begin()), + Length(Vec.size()) {} +#endif + /// @} /// @name Simple Operations /// @{ @@ -178,6 +185,8 @@ namespace llvm { public: typedef T *iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + /// Construct an empty MutableArrayRef. /*implicit*/ MutableArrayRef() : ArrayRef<T>() {} @@ -212,6 +221,9 @@ namespace llvm { iterator begin() const { return data(); } iterator end() const { return data() + this->size(); } + reverse_iterator rbegin() const { return reverse_iterator(end()); } + reverse_iterator rend() const { return reverse_iterator(begin()); } + /// front - Get the first element. T &front() const { assert(!this->empty()); diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h index d5aa8646b3..ce322cce4e 100644 --- a/include/llvm/ADT/DenseMap.h +++ b/include/llvm/ADT/DenseMap.h @@ -64,7 +64,9 @@ public: return const_iterator(getBucketsEnd(), getBucketsEnd(), true); } - bool empty() const { return getNumEntries() == 0; } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { + return getNumEntries() == 0; + } unsigned size() const { return getNumEntries(); } /// Grow the densemap so that it has at least Size buckets. Does not shrink @@ -436,9 +438,8 @@ private: this->grow(NumBuckets * 2); LookupBucketFor(Key, TheBucket); NumBuckets = getNumBuckets(); - } - if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) { - this->grow(NumBuckets * 2); + } else if (NumBuckets-(NewNumEntries+getNumTombstones()) <= NumBuckets/8) { + this->grow(NumBuckets); LookupBucketFor(Key, TheBucket); } assert(TheBucket); @@ -713,13 +714,13 @@ public: init(NumInitBuckets); } - SmallDenseMap(const SmallDenseMap &other) { + SmallDenseMap(const SmallDenseMap &other) : BaseT() { init(0); copyFrom(other); } #if LLVM_HAS_RVALUE_REFERENCES - SmallDenseMap(SmallDenseMap &&other) { + SmallDenseMap(SmallDenseMap &&other) : BaseT() { init(0); swap(other); } diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h index a667479a4d..8f8fb98770 100644 --- a/include/llvm/ADT/ImmutableMap.h +++ b/include/llvm/ADT/ImmutableMap.h @@ -211,6 +211,7 @@ public: friend class ImmutableMap; public: + typedef ptrdiff_t difference_type; typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type; typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref reference; typedef typename iterator::value_type *pointer; diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h index fbdf066e61..ad349699e2 100644 --- a/include/llvm/ADT/ImmutableSet.h +++ b/include/llvm/ADT/ImmutableSet.h @@ -851,6 +851,18 @@ PROFILE_INTEGER_INFO(unsigned long long) #undef PROFILE_INTEGER_INFO +/// Profile traits for booleans. +template <> +struct ImutProfileInfo<bool> { + typedef const bool value_type; + typedef const bool& value_type_ref; + + static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) { + ID.AddBoolean(X); + } +}; + + /// Generic profile trait for pointer types. We treat pointers as /// references to unique objects. template <typename T> @@ -1060,6 +1072,7 @@ public: friend class ImmutableSet<ValT,ValInfo>; public: + typedef ptrdiff_t difference_type; typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type; typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference; typedef typename iterator::value_type *pointer; diff --git a/include/llvm/ADT/PointerIntPair.h b/include/llvm/ADT/PointerIntPair.h index 0299a83c44..0cfd470003 100644 --- a/include/llvm/ADT/PointerIntPair.h +++ b/include/llvm/ADT/PointerIntPair.h @@ -14,6 +14,7 @@ #ifndef LLVM_ADT_POINTERINTPAIR_H #define LLVM_ADT_POINTERINTPAIR_H +#include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <cassert> @@ -40,7 +41,7 @@ template <typename PointerTy, unsigned IntBits, typename IntType=unsigned, typename PtrTraits = PointerLikeTypeTraits<PointerTy> > class PointerIntPair { intptr_t Value; - enum { + enum LLVM_ENUM_INT_TYPE(uintptr_t) { /// PointerBitMask - The bits that come from the pointer. PointerBitMask = ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1), diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h index c1a6d74412..05d362feab 100644 --- a/include/llvm/ADT/PointerUnion.h +++ b/include/llvm/ADT/PointerUnion.h @@ -72,7 +72,7 @@ namespace llvm { /// printf("%d %d", P.is<int*>(), P.is<float*>()); // prints "1 0" /// X = P.get<int*>(); // ok. /// Y = P.get<float*>(); // runtime assertion failure. - /// Z = P.get<double*>(); // runtime assertion failure (regardless of tag) + /// Z = P.get<double*>(); // compile time failure. /// P = (float*)0; /// Y = P.get<float*>(); // ok. /// X = P.get<int*>(); // runtime assertion failure. @@ -177,10 +177,17 @@ namespace llvm { }; template<typename PT1, typename PT2> - bool operator==(PointerUnion<PT1, PT2> lhs, PointerUnion<PT1, PT2> rhs) { + static bool operator==(PointerUnion<PT1, PT2> lhs, + PointerUnion<PT1, PT2> rhs) { return lhs.getOpaqueValue() == rhs.getOpaqueValue(); } - + + template<typename PT1, typename PT2> + static bool operator!=(PointerUnion<PT1, PT2> lhs, + PointerUnion<PT1, PT2> rhs) { + return lhs.getOpaqueValue() != rhs.getOpaqueValue(); + } + // Teach SmallPtrSet that PointerUnion is "basically a pointer", that has // # low bits available = min(PT1bits,PT2bits)-1. template<typename PT1, typename PT2> diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h index dacda36521..3aa8183353 100644 --- a/include/llvm/ADT/STLExtras.h +++ b/include/llvm/ADT/STLExtras.h @@ -217,6 +217,22 @@ 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 { + template <typename T> bool operator()(const T &lhs, const T &rhs) const { + return lhs.first < rhs.first; + } +}; + +/// \brief Function object to check whether the second component of a std::pair +/// compares less than the second component of another std::pair. +struct less_second { + template <typename T> bool operator()(const T &lhs, const T &rhs) const { + return lhs.second < rhs.second; + } +}; + //===----------------------------------------------------------------------===// // Extra additions for arrays //===----------------------------------------------------------------------===// @@ -277,12 +293,16 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) { get_array_pod_sort_comparator(*Start)); } -template<class IteratorTy> -inline void array_pod_sort(IteratorTy Start, IteratorTy End, - int (*Compare)(const void*, const void*)) { +template <class IteratorTy> +inline void array_pod_sort( + IteratorTy Start, IteratorTy End, + int (*Compare)( + const typename std::iterator_traits<IteratorTy>::value_type *, + const typename std::iterator_traits<IteratorTy>::value_type *)) { // Don't dereference start iterator of empty sequence. if (Start == End) return; - qsort(&*Start, End-Start, sizeof(*Start), Compare); + qsort(&*Start, End - Start, sizeof(*Start), + reinterpret_cast<int (*)(const void *, const void *)>(Compare)); } //===----------------------------------------------------------------------===// diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h index d2f7286c25..5eda37c675 100644 --- a/include/llvm/ADT/SetVector.h +++ b/include/llvm/ADT/SetVector.h @@ -170,7 +170,7 @@ public: vector_.pop_back(); } - T pop_back_val() { + T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() { T Ret = back(); pop_back(); return Ret; diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index 8c7304197f..bd0d8838ef 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -71,7 +71,7 @@ protected: ~SmallPtrSetImpl(); public: - bool empty() const { return size() == 0; } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return size() == 0; } unsigned size() const { return NumElements; } void clear() { diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h index 7ba0a714bf..505aa8d8ae 100644 --- a/include/llvm/ADT/SmallVector.h +++ b/include/llvm/ADT/SmallVector.h @@ -53,7 +53,7 @@ public: return size_t((char*)CapacityX - (char*)BeginX); } - bool empty() const { return BeginX == EndX; } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { return BeginX == EndX; } }; template <typename T, unsigned N> struct SmallVectorStorage; @@ -427,7 +427,7 @@ public: this->grow(N); } - T pop_back_val() { + T LLVM_ATTRIBUTE_UNUSED_RESULT pop_back_val() { #if LLVM_HAS_RVALUE_REFERENCES T Result = ::std::move(this->back()); #else diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h index d2887c5c2c..56dbb5b806 100644 --- a/include/llvm/ADT/StringExtras.h +++ b/include/llvm/ADT/StringExtras.h @@ -14,6 +14,7 @@ #ifndef LLVM_ADT_STRINGEXTRAS_H #define LLVM_ADT_STRINGEXTRAS_H +#include <iterator> #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" @@ -159,6 +160,48 @@ static inline StringRef getOrdinalSuffix(unsigned Val) { } } +template <typename IteratorT> +inline std::string join_impl(IteratorT Begin, IteratorT End, + StringRef Separator, std::input_iterator_tag) { + std::string S; + if (Begin == End) + return S; + + S += (*Begin); + while (++Begin != End) { + S += Separator; + S += (*Begin); + } + return S; +} + +template <typename IteratorT> +inline std::string join_impl(IteratorT Begin, IteratorT End, + StringRef Separator, std::forward_iterator_tag) { + std::string S; + if (Begin == End) + return S; + + size_t Len = (std::distance(Begin, End) - 1) * Separator.size(); + for (IteratorT I = Begin; I != End; ++I) + Len += (*Begin).size(); + S.reserve(Len); + S += (*Begin); + while (++Begin != End) { + S += Separator; + S += (*Begin); + } + return S; +} + +/// Joins the strings in the range [Begin, End), adding Separator between +/// the elements. +template <typename IteratorT> +inline std::string join(IteratorT Begin, IteratorT End, StringRef Separator) { + typedef typename std::iterator_traits<IteratorT>::iterator_category tag; + return join_impl(Begin, End, Separator, tag()); +} + } // End llvm namespace #endif diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h index 3e1e24c1ea..ec0c2849f3 100644 --- a/include/llvm/ADT/StringRef.h +++ b/include/llvm/ADT/StringRef.h @@ -175,7 +175,7 @@ namespace llvm { /// transform one of the given strings into the other. If zero, /// the strings are identical. unsigned edit_distance(StringRef Other, bool AllowReplacements = true, - unsigned MaxEditDistance = 0); + unsigned MaxEditDistance = 0) const; /// str - Get the contents as an std::string. std::string str() const { @@ -210,12 +210,18 @@ namespace llvm { compareMemory(Data, Prefix.Data, Prefix.Length) == 0; } + /// Check if this string starts with the given \p Prefix, ignoring case. + bool startswith_lower(StringRef Prefix) const; + /// Check if this string ends with the given \p Suffix. bool endswith(StringRef Suffix) const { return Length >= Suffix.Length && compareMemory(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0; } + /// Check if this string ends with the given \p Suffix, ignoring case. + bool endswith_lower(StringRef Suffix) const; + /// @} /// @name String Searching /// @{ diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h index 8d968e8fa3..84e0b29d1f 100644 --- a/include/llvm/ADT/Triple.h +++ b/include/llvm/ADT/Triple.h @@ -14,6 +14,7 @@ // Some system headers or GCC predefined macros conflict with identifiers in // this file. Undefine them here. +#undef NetBSD #undef mips #undef sparc @@ -318,7 +319,12 @@ public: return getOS() == Triple::Cygwin || getOS() == Triple::MinGW32; } - /// isOSWindows - Is this a "Windows" OS. + /// \brief Is this a "Windows" OS targeting a "MSVCRT.dll" environment. + bool isOSMSVCRT() const { + return getOS() == Triple::Win32 || getOS() == Triple::MinGW32; + } + + /// \brief Tests whether the OS is Windows. bool isOSWindows() const { return getOS() == Triple::Win32 || isOSCygMing(); } @@ -328,6 +334,11 @@ public: return getOS() == Triple::NaCl; } + /// \brief Tests whether the OS is Linux. + bool isOSLinux() const { + return getOS() == Triple::Linux; + } + /// \brief Tests whether the OS uses the ELF binary format. bool isOSBinFormatELF() const { return !isOSDarwin() && !isOSWindows(); diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index 71dab2ef55..6aeaa91f1b 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -382,7 +382,9 @@ public: // Miscellaneous inspection routines. size_type max_size() const { return size_type(-1); } - bool empty() const { return Head == 0 || Head == getTail(); } + bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const { + return Head == 0 || Head == getTail(); + } // Front and back accessor functions... reference front() { @@ -534,7 +536,7 @@ public: // Functionality derived from other functions defined above... // - size_type size() const { + size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const { if (Head == 0) return 0; // Don't require construction of sentinel if empty. return std::distance(begin(), end()); } diff --git a/include/llvm/ADT/polymorphic_ptr.h b/include/llvm/ADT/polymorphic_ptr.h new file mode 100644 index 0000000000..b8d8d71238 --- /dev/null +++ b/include/llvm/ADT/polymorphic_ptr.h @@ -0,0 +1,117 @@ +//===- 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 |