aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/ADT
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r--include/llvm/ADT/APInt.h64
-rw-r--r--include/llvm/ADT/APSInt.h12
-rw-r--r--include/llvm/ADT/ArrayRef.h14
-rw-r--r--include/llvm/ADT/DenseMap.h13
-rw-r--r--include/llvm/ADT/ImmutableMap.h1
-rw-r--r--include/llvm/ADT/ImmutableSet.h13
-rw-r--r--include/llvm/ADT/PointerIntPair.h3
-rw-r--r--include/llvm/ADT/PointerUnion.h13
-rw-r--r--include/llvm/ADT/STLExtras.h28
-rw-r--r--include/llvm/ADT/SetVector.h2
-rw-r--r--include/llvm/ADT/SmallPtrSet.h2
-rw-r--r--include/llvm/ADT/SmallVector.h4
-rw-r--r--include/llvm/ADT/StringExtras.h43
-rw-r--r--include/llvm/ADT/StringRef.h8
-rw-r--r--include/llvm/ADT/Triple.h13
-rw-r--r--include/llvm/ADT/ilist.h6
-rw-r--r--include/llvm/ADT/polymorphic_ptr.h117
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