aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/ADT
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 10:51:19 +0000
commiteb11fae6d08f479c0799db45860a98af528fa6e7 (patch)
tree44d492a50c8c1a7eb8e2d17ea3360ec4d066f042 /include/llvm/ADT
parentb8a2042aa938069e862750553db0e4d82d25822c (diff)
downloadsrc-eb11fae6d08f479c0799db45860a98af528fa6e7.tar.gz
src-eb11fae6d08f479c0799db45860a98af528fa6e7.zip
Vendor import of llvm trunk r338150:vendor/llvm/llvm-trunk-r338150
Notes
Notes: svn path=/vendor/llvm/dist/; revision=336809 svn path=/vendor/llvm/llvm-trunk-r338150/; revision=336814; tag=vendor/llvm/llvm-trunk-r338150
Diffstat (limited to 'include/llvm/ADT')
-rw-r--r--include/llvm/ADT/APFloat.h2
-rw-r--r--include/llvm/ADT/APInt.h352
-rw-r--r--include/llvm/ADT/APSInt.h6
-rw-r--r--include/llvm/ADT/Any.h150
-rw-r--r--include/llvm/ADT/ArrayRef.h30
-rw-r--r--include/llvm/ADT/BitVector.h11
-rw-r--r--include/llvm/ADT/CachedHashString.h1
-rw-r--r--include/llvm/ADT/DenseMapInfo.h7
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h2
-rw-r--r--include/llvm/ADT/EpochTracker.h13
-rw-r--r--include/llvm/ADT/FunctionExtras.h293
-rw-r--r--include/llvm/ADT/GraphTraits.h20
-rw-r--r--include/llvm/ADT/Hashing.h62
-rw-r--r--include/llvm/ADT/ImmutableList.h4
-rw-r--r--include/llvm/ADT/ImmutableMap.h5
-rw-r--r--include/llvm/ADT/ImmutableSet.h4
-rw-r--r--include/llvm/ADT/MapVector.h32
-rw-r--r--include/llvm/ADT/None.h2
-rw-r--r--include/llvm/ADT/Optional.h176
-rw-r--r--include/llvm/ADT/PackedVector.h2
-rw-r--r--include/llvm/ADT/PointerUnion.h6
-rw-r--r--include/llvm/ADT/SCCIterator.h10
-rw-r--r--include/llvm/ADT/STLExtras.h215
-rw-r--r--include/llvm/ADT/ScopeExit.h16
-rw-r--r--include/llvm/ADT/SetVector.h56
-rw-r--r--include/llvm/ADT/SmallPtrSet.h2
-rw-r--r--include/llvm/ADT/SmallSet.h118
-rw-r--r--include/llvm/ADT/SmallVector.h241
-rw-r--r--include/llvm/ADT/SparseMultiSet.h2
-rw-r--r--include/llvm/ADT/SparseSet.h3
-rw-r--r--include/llvm/ADT/Statistic.h59
-rw-r--r--include/llvm/ADT/StringExtras.h55
-rw-r--r--include/llvm/ADT/StringMap.h24
-rw-r--r--include/llvm/ADT/StringRef.h42
-rw-r--r--include/llvm/ADT/StringSwitch.h188
-rw-r--r--include/llvm/ADT/TinyPtrVector.h6
-rw-r--r--include/llvm/ADT/Triple.h30
-rw-r--r--include/llvm/ADT/UniqueVector.h8
-rw-r--r--include/llvm/ADT/VariadicFunction.h2
-rw-r--r--include/llvm/ADT/edit_distance.h2
-rw-r--r--include/llvm/ADT/ilist.h25
-rw-r--r--include/llvm/ADT/ilist_node.h8
-rw-r--r--include/llvm/ADT/ilist_node_options.h1
-rw-r--r--include/llvm/ADT/iterator.h10
-rw-r--r--include/llvm/ADT/iterator_range.h11
45 files changed, 1564 insertions, 750 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 6c0b6ae78ae3..5c59af4c04ba 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -1215,7 +1215,7 @@ inline APFloat abs(APFloat X) {
return X;
}
-/// \brief Returns the negated value of the argument.
+/// Returns the negated value of the argument.
inline APFloat neg(APFloat X) {
X.changeSign();
return X;
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index c81363cc16b7..6bf6b22fb010 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// \brief This file implements a class to represent arbitrary precision
+/// This file implements a class to represent arbitrary precision
/// integral constant values and operations on them.
///
//===----------------------------------------------------------------------===//
@@ -40,7 +40,7 @@ inline APInt operator-(APInt);
// APInt Class
//===----------------------------------------------------------------------===//
-/// \brief Class for arbitrary precision integers.
+/// Class for arbitrary precision integers.
///
/// APInt is a functional replacement for common case unsigned integer type like
/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width
@@ -78,6 +78,12 @@ public:
APINT_BITS_PER_WORD = APINT_WORD_SIZE * CHAR_BIT
};
+ enum class Rounding {
+ DOWN,
+ TOWARD_ZERO,
+ UP,
+ };
+
static const WordType WORD_MAX = ~WordType(0);
private:
@@ -94,7 +100,7 @@ private:
friend class APSInt;
- /// \brief Fast internal constructor
+ /// Fast internal constructor
///
/// This constructor is used only internally for speed of construction of
/// temporaries. It is unsafe for general use so it is not public.
@@ -102,19 +108,19 @@ private:
U.pVal = val;
}
- /// \brief Determine if this APInt just has one word to store value.
+ /// Determine if this APInt just has one word to store value.
///
/// \returns true if the number of bits <= 64, false otherwise.
bool isSingleWord() const { return BitWidth <= APINT_BITS_PER_WORD; }
- /// \brief Determine which word a bit is in.
+ /// Determine which word a bit is in.
///
/// \returns the word position for the specified bit position.
static unsigned whichWord(unsigned bitPosition) {
return bitPosition / APINT_BITS_PER_WORD;
}
- /// \brief Determine which bit in a word a bit is in.
+ /// Determine which bit in a word a bit is in.
///
/// \returns the bit position in a word for the specified bit position
/// in the APInt.
@@ -122,7 +128,7 @@ private:
return bitPosition % APINT_BITS_PER_WORD;
}
- /// \brief Get a single bit mask.
+ /// Get a single bit mask.
///
/// \returns a uint64_t with only bit at "whichBit(bitPosition)" set
/// This method generates and returns a uint64_t (word) mask for a single
@@ -132,7 +138,7 @@ private:
return 1ULL << whichBit(bitPosition);
}
- /// \brief Clear unused high order bits
+ /// Clear unused high order bits
///
/// This method is used internally to clear the top "N" bits in the high order
/// word that are not used by the APInt. This is needed after the most
@@ -151,7 +157,7 @@ private:
return *this;
}
- /// \brief Get the word corresponding to a bit position
+ /// Get the word corresponding to a bit position
/// \returns the corresponding word for the specified bit position.
uint64_t getWord(unsigned bitPosition) const {
return isSingleWord() ? U.VAL : U.pVal[whichWord(bitPosition)];
@@ -162,7 +168,7 @@ private:
/// value of any bits upon return. Caller should populate the bits after.
void reallocate(unsigned NewBitWidth);
- /// \brief Convert a char array into an APInt
+ /// Convert a char array into an APInt
///
/// \param radix 2, 8, 10, 16, or 36
/// Converts a string into a number. The string must be non-empty
@@ -176,7 +182,7 @@ private:
/// result to hold the input.
void fromString(unsigned numBits, StringRef str, uint8_t radix);
- /// \brief An internal division function for dividing APInts.
+ /// An internal division function for dividing APInts.
///
/// This is used by the toString method to divide by the radix. It simply
/// provides a more convenient form of divide for internal use since KnuthDiv
@@ -258,7 +264,7 @@ public:
/// \name Constructors
/// @{
- /// \brief Create a new APInt of numBits width, initialized as val.
+ /// Create a new APInt of numBits width, initialized as val.
///
/// If isSigned is true then val is treated as if it were a signed value
/// (i.e. as an int64_t) and the appropriate sign extension to the bit width
@@ -279,7 +285,7 @@ public:
}
}
- /// \brief Construct an APInt of numBits width, initialized as bigVal[].
+ /// Construct an APInt of numBits width, initialized as bigVal[].
///
/// Note that bigVal.size() can be smaller or larger than the corresponding
/// bit width but any extraneous bits will be dropped.
@@ -297,7 +303,7 @@ public:
/// constructor.
APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
- /// \brief Construct an APInt from a string representation.
+ /// Construct an APInt from a string representation.
///
/// This constructor interprets the string \p str in the given radix. The
/// interpretation stops when the first character that is not suitable for the
@@ -311,7 +317,7 @@ public:
APInt(unsigned numBits, StringRef str, uint8_t radix);
/// Simply makes *this a copy of that.
- /// @brief Copy Constructor.
+ /// Copy Constructor.
APInt(const APInt &that) : BitWidth(that.BitWidth) {
if (isSingleWord())
U.VAL = that.U.VAL;
@@ -319,26 +325,26 @@ public:
initSlowCase(that);
}
- /// \brief Move Constructor.
+ /// Move Constructor.
APInt(APInt &&that) : BitWidth(that.BitWidth) {
memcpy(&U, &that.U, sizeof(U));
that.BitWidth = 0;
}
- /// \brief Destructor.
+ /// Destructor.
~APInt() {
if (needsCleanup())
delete[] U.pVal;
}
- /// \brief Default constructor that creates an uninteresting APInt
+ /// Default constructor that creates an uninteresting APInt
/// representing a 1-bit zero value.
///
/// This is useful for object deserialization (pair this with the static
/// method Read).
explicit APInt() : BitWidth(1) { U.VAL = 0; }
- /// \brief Returns whether this instance allocated memory.
+ /// Returns whether this instance allocated memory.
bool needsCleanup() const { return !isSingleWord(); }
/// Used to insert APInt objects, or objects that contain APInt objects, into
@@ -349,33 +355,33 @@ public:
/// \name Value Tests
/// @{
- /// \brief Determine sign of this APInt.
+ /// Determine sign of this APInt.
///
/// This tests the high bit of this APInt to determine if it is set.
///
/// \returns true if this APInt is negative, false otherwise
bool isNegative() const { return (*this)[BitWidth - 1]; }
- /// \brief Determine if this APInt Value is non-negative (>= 0)
+ /// Determine if this APInt Value is non-negative (>= 0)
///
/// This tests the high bit of the APInt to determine if it is unset.
bool isNonNegative() const { return !isNegative(); }
- /// \brief Determine if sign bit of this APInt is set.
+ /// Determine if sign bit of this APInt is set.
///
/// This tests the high bit of this APInt to determine if it is set.
///
/// \returns true if this APInt has its sign bit set, false otherwise.
bool isSignBitSet() const { return (*this)[BitWidth-1]; }
- /// \brief Determine if sign bit of this APInt is clear.
+ /// Determine if sign bit of this APInt is clear.
///
/// This tests the high bit of this APInt to determine if it is clear.
///
/// \returns true if this APInt has its sign bit clear, false otherwise.
bool isSignBitClear() const { return !isSignBitSet(); }
- /// \brief Determine if this APInt Value is positive.
+ /// Determine if this APInt Value is positive.
///
/// This tests if the value of this APInt is positive (> 0). Note
/// that 0 is not a positive value.
@@ -383,7 +389,7 @@ public:
/// \returns true if this APInt is positive.
bool isStrictlyPositive() const { return isNonNegative() && !isNullValue(); }
- /// \brief Determine if all bits are set
+ /// Determine if all bits are set
///
/// This checks to see if the value has all bits of the APInt are set or not.
bool isAllOnesValue() const {
@@ -392,13 +398,13 @@ public:
return countTrailingOnesSlowCase() == BitWidth;
}
- /// \brief Determine if all bits are clear
+ /// Determine if all bits are clear
///
/// This checks to see if the value has all bits of the APInt are clear or
/// not.
bool isNullValue() const { return !*this; }
- /// \brief Determine if this is a value of 1.
+ /// Determine if this is a value of 1.
///
/// This checks to see if the value of this APInt is one.
bool isOneValue() const {
@@ -407,13 +413,13 @@ public:
return countLeadingZerosSlowCase() == BitWidth - 1;
}
- /// \brief Determine if this is the largest unsigned value.
+ /// Determine if this is the largest unsigned value.
///
/// This checks to see if the value of this APInt is the maximum unsigned
/// value for the APInt's bit width.
bool isMaxValue() const { return isAllOnesValue(); }
- /// \brief Determine if this is the largest signed value.
+ /// Determine if this is the largest signed value.
///
/// This checks to see if the value of this APInt is the maximum signed
/// value for the APInt's bit width.
@@ -423,13 +429,13 @@ public:
return !isNegative() && countTrailingOnesSlowCase() == BitWidth - 1;
}
- /// \brief Determine if this is the smallest unsigned value.
+ /// Determine if this is the smallest unsigned value.
///
/// This checks to see if the value of this APInt is the minimum unsigned
/// value for the APInt's bit width.
bool isMinValue() const { return isNullValue(); }
- /// \brief Determine if this is the smallest signed value.
+ /// Determine if this is the smallest signed value.
///
/// This checks to see if the value of this APInt is the minimum signed
/// value for the APInt's bit width.
@@ -439,19 +445,19 @@ public:
return isNegative() && countTrailingZerosSlowCase() == BitWidth - 1;
}
- /// \brief Check if this APInt has an N-bits unsigned integer value.
+ /// Check if this APInt has an N-bits unsigned integer value.
bool isIntN(unsigned N) const {
assert(N && "N == 0 ???");
return getActiveBits() <= N;
}
- /// \brief Check if this APInt has an N-bits signed integer value.
+ /// Check if this APInt has an N-bits signed integer value.
bool isSignedIntN(unsigned N) const {
assert(N && "N == 0 ???");
return getMinSignedBits() <= N;
}
- /// \brief Check if this APInt's value is a power of two greater than zero.
+ /// Check if this APInt's value is a power of two greater than zero.
///
/// \returns true if the argument APInt value is a power of two > 0.
bool isPowerOf2() const {
@@ -460,12 +466,12 @@ public:
return countPopulationSlowCase() == 1;
}
- /// \brief Check if the APInt's value is returned by getSignMask.
+ /// Check if the APInt's value is returned by getSignMask.
///
/// \returns true if this is the value returned by getSignMask.
bool isSignMask() const { return isMinSignedValue(); }
- /// \brief Convert APInt to a boolean value.
+ /// Convert APInt to a boolean value.
///
/// This converts the APInt to a boolean value as a test against zero.
bool getBoolValue() const { return !!*this; }
@@ -476,7 +482,7 @@ public:
return ugt(Limit) ? Limit : getZExtValue();
}
- /// \brief Check if the APInt consists of a repeated bit pattern.
+ /// Check if the APInt consists of a repeated bit pattern.
///
/// e.g. 0x01010101 satisfies isSplat(8).
/// \param SplatSizeInBits The size of the pattern in bits. Must divide bit
@@ -505,7 +511,7 @@ public:
return (Ones > 0) && ((Ones + countLeadingZerosSlowCase()) == BitWidth);
}
- /// \brief Return true if this APInt value contains a sequence of ones with
+ /// Return true if this APInt value contains a sequence of ones with
/// the remainder zero.
bool isShiftedMask() const {
if (isSingleWord())
@@ -519,29 +525,29 @@ public:
/// \name Value Generators
/// @{
- /// \brief Gets maximum unsigned value of APInt for specific bit width.
+ /// Gets maximum unsigned value of APInt for specific bit width.
static APInt getMaxValue(unsigned numBits) {
return getAllOnesValue(numBits);
}
- /// \brief Gets maximum signed value of APInt for a specific bit width.
+ /// Gets maximum signed value of APInt for a specific bit width.
static APInt getSignedMaxValue(unsigned numBits) {
APInt API = getAllOnesValue(numBits);
API.clearBit(numBits - 1);
return API;
}
- /// \brief Gets minimum unsigned value of APInt for a specific bit width.
+ /// Gets minimum unsigned value of APInt for a specific bit width.
static APInt getMinValue(unsigned numBits) { return APInt(numBits, 0); }
- /// \brief Gets minimum signed value of APInt for a specific bit width.
+ /// Gets minimum signed value of APInt for a specific bit width.
static APInt getSignedMinValue(unsigned numBits) {
APInt API(numBits, 0);
API.setBit(numBits - 1);
return API;
}
- /// \brief Get the SignMask for a specific bit width.
+ /// Get the SignMask for a specific bit width.
///
/// This is just a wrapper function of getSignedMinValue(), and it helps code
/// readability when we want to get a SignMask.
@@ -549,19 +555,19 @@ public:
return getSignedMinValue(BitWidth);
}
- /// \brief Get the all-ones value.
+ /// Get the all-ones value.
///
/// \returns the all-ones value for an APInt of the specified bit-width.
static APInt getAllOnesValue(unsigned numBits) {
return APInt(numBits, WORD_MAX, true);
}
- /// \brief Get the '0' value.
+ /// Get the '0' value.
///
/// \returns the '0' value for an APInt of the specified bit-width.
static APInt getNullValue(unsigned numBits) { return APInt(numBits, 0); }
- /// \brief Compute an APInt containing numBits highbits from this APInt.
+ /// Compute an APInt containing numBits highbits from this APInt.
///
/// Get an APInt with the same BitWidth as this APInt, just zero mask
/// the low bits and right shift to the least significant bit.
@@ -569,7 +575,7 @@ public:
/// \returns the high "numBits" bits of this APInt.
APInt getHiBits(unsigned numBits) const;
- /// \brief Compute an APInt containing numBits lowbits from this APInt.
+ /// Compute an APInt containing numBits lowbits from this APInt.
///
/// Get an APInt with the same BitWidth as this APInt, just zero mask
/// the high bits.
@@ -577,14 +583,14 @@ public:
/// \returns the low "numBits" bits of this APInt.
APInt getLoBits(unsigned numBits) const;
- /// \brief Return an APInt with exactly one bit set in the result.
+ /// Return an APInt with exactly one bit set in the result.
static APInt getOneBitSet(unsigned numBits, unsigned BitNo) {
APInt Res(numBits, 0);
Res.setBit(BitNo);
return Res;
}
- /// \brief Get a value with a block of bits set.
+ /// Get a value with a block of bits set.
///
/// Constructs an APInt value that has a contiguous range of bits set. The
/// bits from loBit (inclusive) to hiBit (exclusive) will be set. All other
@@ -603,7 +609,7 @@ public:
return Res;
}
- /// \brief Get a value with upper bits starting at loBit set.
+ /// Get a value with upper bits starting at loBit set.
///
/// Constructs an APInt value that has a contiguous range of bits set. The
/// bits from loBit (inclusive) to numBits (exclusive) will be set. All other
@@ -620,7 +626,7 @@ public:
return Res;
}
- /// \brief Get a value with high bits set
+ /// Get a value with high bits set
///
/// Constructs an APInt value that has the top hiBitsSet bits set.
///
@@ -632,7 +638,7 @@ public:
return Res;
}
- /// \brief Get a value with low bits set
+ /// Get a value with low bits set
///
/// Constructs an APInt value that has the bottom loBitsSet bits set.
///
@@ -644,10 +650,10 @@ public:
return Res;
}
- /// \brief Return a value containing V broadcasted over NewLen bits.
+ /// Return a value containing V broadcasted over NewLen bits.
static APInt getSplat(unsigned NewLen, const APInt &V);
- /// \brief Determine if two APInts have the same value, after zero-extending
+ /// Determine if two APInts have the same value, after zero-extending
/// one of them (if needed!) to ensure that the bit-widths match.
static bool isSameValue(const APInt &I1, const APInt &I2) {
if (I1.getBitWidth() == I2.getBitWidth())
@@ -659,7 +665,7 @@ public:
return I1.zext(I2.getBitWidth()) == I2;
}
- /// \brief Overload to compute a hash_code for an APInt value.
+ /// Overload to compute a hash_code for an APInt value.
friend hash_code hash_value(const APInt &Arg);
/// This function returns a pointer to the internal storage of the APInt.
@@ -675,7 +681,7 @@ public:
/// \name Unary Operators
/// @{
- /// \brief Postfix increment operator.
+ /// Postfix increment operator.
///
/// Increments *this by 1.
///
@@ -686,12 +692,12 @@ public:
return API;
}
- /// \brief Prefix increment operator.
+ /// Prefix increment operator.
///
/// \returns *this incremented by one
APInt &operator++();
- /// \brief Postfix decrement operator.
+ /// Postfix decrement operator.
///
/// Decrements *this by 1.
///
@@ -702,12 +708,12 @@ public:
return API;
}
- /// \brief Prefix decrement operator.
+ /// Prefix decrement operator.
///
/// \returns *this decremented by one.
APInt &operator--();
- /// \brief Logical negation operator.
+ /// Logical negation operator.
///
/// Performs logical negation operation on this APInt.
///
@@ -722,7 +728,7 @@ public:
/// \name Assignment Operators
/// @{
- /// \brief Copy assignment operator.
+ /// Copy assignment operator.
///
/// \returns *this after assignment of RHS.
APInt &operator=(const APInt &RHS) {
@@ -737,8 +743,13 @@ public:
return *this;
}
- /// @brief Move assignment operator.
+ /// Move assignment operator.
APInt &operator=(APInt &&that) {
+#ifdef _MSC_VER
+ // The MSVC std::shuffle implementation still does self-assignment.
+ if (this == &that)
+ return *this;
+#endif
assert(this != &that && "Self-move not supported");
if (!isSingleWord())
delete[] U.pVal;
@@ -753,7 +764,7 @@ public:
return *this;
}
- /// \brief Assignment operator.
+ /// Assignment operator.
///
/// The RHS value is assigned to *this. If the significant bits in RHS exceed
/// the bit width, the excess bits are truncated. If the bit width is larger
@@ -771,7 +782,7 @@ public:
return *this;
}
- /// \brief Bitwise AND assignment operator.
+ /// Bitwise AND assignment operator.
///
/// Performs a bitwise AND operation on this APInt and RHS. The result is
/// assigned to *this.
@@ -786,7 +797,7 @@ public:
return *this;
}
- /// \brief Bitwise AND assignment operator.
+ /// Bitwise AND assignment operator.
///
/// Performs a bitwise AND operation on this APInt and RHS. RHS is
/// logically zero-extended or truncated to match the bit-width of
@@ -801,7 +812,7 @@ public:
return *this;
}
- /// \brief Bitwise OR assignment operator.
+ /// Bitwise OR assignment operator.
///
/// Performs a bitwise OR operation on this APInt and RHS. The result is
/// assigned *this;
@@ -816,7 +827,7 @@ public:
return *this;
}
- /// \brief Bitwise OR assignment operator.
+ /// Bitwise OR assignment operator.
///
/// Performs a bitwise OR operation on this APInt and RHS. RHS is
/// logically zero-extended or truncated to match the bit-width of
@@ -831,7 +842,7 @@ public:
return *this;
}
- /// \brief Bitwise XOR assignment operator.
+ /// Bitwise XOR assignment operator.
///
/// Performs a bitwise XOR operation on this APInt and RHS. The result is
/// assigned to *this.
@@ -846,7 +857,7 @@ public:
return *this;
}
- /// \brief Bitwise XOR assignment operator.
+ /// Bitwise XOR assignment operator.
///
/// Performs a bitwise XOR operation on this APInt and RHS. RHS is
/// logically zero-extended or truncated to match the bit-width of
@@ -861,7 +872,7 @@ public:
return *this;
}
- /// \brief Multiplication assignment operator.
+ /// Multiplication assignment operator.
///
/// Multiplies this APInt by RHS and assigns the result to *this.
///
@@ -869,7 +880,7 @@ public:
APInt &operator*=(const APInt &RHS);
APInt &operator*=(uint64_t RHS);
- /// \brief Addition assignment operator.
+ /// Addition assignment operator.
///
/// Adds RHS to *this and assigns the result to *this.
///
@@ -877,7 +888,7 @@ public:
APInt &operator+=(const APInt &RHS);
APInt &operator+=(uint64_t RHS);
- /// \brief Subtraction assignment operator.
+ /// Subtraction assignment operator.
///
/// Subtracts RHS from *this and assigns the result to *this.
///
@@ -885,7 +896,7 @@ public:
APInt &operator-=(const APInt &RHS);
APInt &operator-=(uint64_t RHS);
- /// \brief Left-shift assignment function.
+ /// Left-shift assignment function.
///
/// Shifts *this left by shiftAmt and assigns the result to *this.
///
@@ -903,7 +914,7 @@ public:
return *this;
}
- /// \brief Left-shift assignment function.
+ /// Left-shift assignment function.
///
/// Shifts *this left by shiftAmt and assigns the result to *this.
///
@@ -914,22 +925,22 @@ public:
/// \name Binary Operators
/// @{
- /// \brief Multiplication operator.
+ /// Multiplication operator.
///
/// Multiplies this APInt by RHS and returns the result.
APInt operator*(const APInt &RHS) const;
- /// \brief Left logical shift operator.
+ /// Left logical shift operator.
///
/// Shifts this APInt left by \p Bits and returns the result.
APInt operator<<(unsigned Bits) const { return shl(Bits); }
- /// \brief Left logical shift operator.
+ /// Left logical shift operator.
///
/// Shifts this APInt left by \p Bits and returns the result.
APInt operator<<(const APInt &Bits) const { return shl(Bits); }
- /// \brief Arithmetic right-shift function.
+ /// Arithmetic right-shift function.
///
/// Arithmetic right-shift this APInt by shiftAmt.
APInt ashr(unsigned ShiftAmt) const {
@@ -953,7 +964,7 @@ public:
ashrSlowCase(ShiftAmt);
}
- /// \brief Logical right-shift function.
+ /// Logical right-shift function.
///
/// Logical right-shift this APInt by shiftAmt.
APInt lshr(unsigned shiftAmt) const {
@@ -975,7 +986,7 @@ public:
lshrSlowCase(ShiftAmt);
}
- /// \brief Left-shift function.
+ /// Left-shift function.
///
/// Left-shift this APInt by shiftAmt.
APInt shl(unsigned shiftAmt) const {
@@ -984,13 +995,13 @@ public:
return R;
}
- /// \brief Rotate left by rotateAmt.
+ /// Rotate left by rotateAmt.
APInt rotl(unsigned rotateAmt) const;
- /// \brief Rotate right by rotateAmt.
+ /// Rotate right by rotateAmt.
APInt rotr(unsigned rotateAmt) const;
- /// \brief Arithmetic right-shift function.
+ /// Arithmetic right-shift function.
///
/// Arithmetic right-shift this APInt by shiftAmt.
APInt ashr(const APInt &ShiftAmt) const {
@@ -1002,7 +1013,7 @@ public:
/// Arithmetic right-shift this APInt by shiftAmt in place.
void ashrInPlace(const APInt &shiftAmt);
- /// \brief Logical right-shift function.
+ /// Logical right-shift function.
///
/// Logical right-shift this APInt by shiftAmt.
APInt lshr(const APInt &ShiftAmt) const {
@@ -1014,7 +1025,7 @@ public:
/// Logical right-shift this APInt by ShiftAmt in place.
void lshrInPlace(const APInt &ShiftAmt);
- /// \brief Left-shift function.
+ /// Left-shift function.
///
/// Left-shift this APInt by shiftAmt.
APInt shl(const APInt &ShiftAmt) const {
@@ -1023,28 +1034,31 @@ public:
return R;
}
- /// \brief Rotate left by rotateAmt.
+ /// Rotate left by rotateAmt.
APInt rotl(const APInt &rotateAmt) const;
- /// \brief Rotate right by rotateAmt.
+ /// Rotate right by rotateAmt.
APInt rotr(const APInt &rotateAmt) const;
- /// \brief Unsigned division operation.
+ /// Unsigned division operation.
///
/// Perform an unsigned divide operation on this APInt by RHS. Both this and
/// RHS are treated as unsigned quantities for purposes of this division.
///
- /// \returns a new APInt value containing the division result
+ /// \returns a new APInt value containing the division result, rounded towards
+ /// zero.
APInt udiv(const APInt &RHS) const;
APInt udiv(uint64_t RHS) const;
- /// \brief Signed division function for APInt.
+ /// Signed division function for APInt.
///
/// Signed divide this APInt by APInt RHS.
+ ///
+ /// The result is rounded towards zero.
APInt sdiv(const APInt &RHS) const;
APInt sdiv(int64_t RHS) const;
- /// \brief Unsigned remainder operation.
+ /// Unsigned remainder operation.
///
/// Perform an unsigned remainder operation on this APInt with RHS being the
/// divisor. Both this and RHS are treated as unsigned quantities for purposes
@@ -1056,13 +1070,13 @@ public:
APInt urem(const APInt &RHS) const;
uint64_t urem(uint64_t RHS) const;
- /// \brief Function for signed remainder operation.
+ /// Function for signed remainder operation.
///
/// Signed remainder operation on APInt.
APInt srem(const APInt &RHS) const;
int64_t srem(int64_t RHS) const;
- /// \brief Dual division/remainder interface.
+ /// Dual division/remainder interface.
///
/// Sometimes it is convenient to divide two APInt values and obtain both the
/// quotient and remainder. This function does both operations in the same
@@ -1090,7 +1104,7 @@ public:
APInt sshl_ov(const APInt &Amt, bool &Overflow) const;
APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
- /// \brief Array-indexing support.
+ /// Array-indexing support.
///
/// \returns the bit value at bitPosition
bool operator[](unsigned bitPosition) const {
@@ -1102,7 +1116,7 @@ public:
/// \name Comparison Operators
/// @{
- /// \brief Equality operator.
+ /// Equality operator.
///
/// Compares this APInt with RHS for the validity of the equality
/// relationship.
@@ -1113,7 +1127,7 @@ public:
return EqualSlowCase(RHS);
}
- /// \brief Equality operator.
+ /// Equality operator.
///
/// Compares this APInt with a uint64_t for the validity of the equality
/// relationship.
@@ -1123,7 +1137,7 @@ public:
return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() == Val;
}
- /// \brief Equality comparison.
+ /// Equality comparison.
///
/// Compares this APInt with RHS for the validity of the equality
/// relationship.
@@ -1131,7 +1145,7 @@ public:
/// \returns true if *this == Val
bool eq(const APInt &RHS) const { return (*this) == RHS; }
- /// \brief Inequality operator.
+ /// Inequality operator.
///
/// Compares this APInt with RHS for the validity of the inequality
/// relationship.
@@ -1139,7 +1153,7 @@ public:
/// \returns true if *this != Val
bool operator!=(const APInt &RHS) const { return !((*this) == RHS); }
- /// \brief Inequality operator.
+ /// Inequality operator.
///
/// Compares this APInt with a uint64_t for the validity of the inequality
/// relationship.
@@ -1147,7 +1161,7 @@ public:
/// \returns true if *this != Val
bool operator!=(uint64_t Val) const { return !((*this) == Val); }
- /// \brief Inequality comparison
+ /// Inequality comparison
///
/// Compares this APInt with RHS for the validity of the inequality
/// relationship.
@@ -1155,7 +1169,7 @@ public:
/// \returns true if *this != Val
bool ne(const APInt &RHS) const { return !((*this) == RHS); }
- /// \brief Unsigned less than comparison
+ /// Unsigned less than comparison
///
/// Regards both *this and RHS as unsigned quantities and compares them for
/// the validity of the less-than relationship.
@@ -1163,7 +1177,7 @@ public:
/// \returns true if *this < RHS when both are considered unsigned.
bool ult(const APInt &RHS) const { return compare(RHS) < 0; }
- /// \brief Unsigned less than comparison
+ /// Unsigned less than comparison
///
/// Regards both *this as an unsigned quantity and compares it with RHS for
/// the validity of the less-than relationship.
@@ -1174,7 +1188,7 @@ public:
return (isSingleWord() || getActiveBits() <= 64) && getZExtValue() < RHS;
}
- /// \brief Signed less than comparison
+ /// Signed less than comparison
///
/// Regards both *this and RHS as signed quantities and compares them for
/// validity of the less-than relationship.
@@ -1182,7 +1196,7 @@ public:
/// \returns true if *this < RHS when both are considered signed.
bool slt(const APInt &RHS) const { return compareSigned(RHS) < 0; }
- /// \brief Signed less than comparison
+ /// Signed less than comparison
///
/// Regards both *this as a signed quantity and compares it with RHS for
/// the validity of the less-than relationship.
@@ -1193,7 +1207,7 @@ public:
: getSExtValue() < RHS;
}
- /// \brief Unsigned less or equal comparison
+ /// Unsigned less or equal comparison
///
/// Regards both *this and RHS as unsigned quantities and compares them for
/// validity of the less-or-equal relationship.
@@ -1201,7 +1215,7 @@ public:
/// \returns true if *this <= RHS when both are considered unsigned.
bool ule(const APInt &RHS) const { return compare(RHS) <= 0; }
- /// \brief Unsigned less or equal comparison
+ /// Unsigned less or equal comparison
///
/// Regards both *this as an unsigned quantity and compares it with RHS for
/// the validity of the less-or-equal relationship.
@@ -1209,7 +1223,7 @@ public:
/// \returns true if *this <= RHS when considered unsigned.
bool ule(uint64_t RHS) const { return !ugt(RHS); }
- /// \brief Signed less or equal comparison
+ /// Signed less or equal comparison
///
/// Regards both *this and RHS as signed quantities and compares them for
/// validity of the less-or-equal relationship.
@@ -1217,7 +1231,7 @@ public:
/// \returns true if *this <= RHS when both are considered signed.
bool sle(const APInt &RHS) const { return compareSigned(RHS) <= 0; }
- /// \brief Signed less or equal comparison
+ /// Signed less or equal comparison
///
/// Regards both *this as a signed quantity and compares it with RHS for the
/// validity of the less-or-equal relationship.
@@ -1225,7 +1239,7 @@ public:
/// \returns true if *this <= RHS when considered signed.
bool sle(uint64_t RHS) const { return !sgt(RHS); }
- /// \brief Unsigned greather than comparison
+ /// Unsigned greather than comparison
///
/// Regards both *this and RHS as unsigned quantities and compares them for
/// the validity of the greater-than relationship.
@@ -1233,7 +1247,7 @@ public:
/// \returns true if *this > RHS when both are considered unsigned.
bool ugt(const APInt &RHS) const { return !ule(RHS); }
- /// \brief Unsigned greater than comparison
+ /// Unsigned greater than comparison
///
/// Regards both *this as an unsigned quantity and compares it with RHS for
/// the validity of the greater-than relationship.
@@ -1244,7 +1258,7 @@ public:
return (!isSingleWord() && getActiveBits() > 64) || getZExtValue() > RHS;
}
- /// \brief Signed greather than comparison
+ /// Signed greather than comparison
///
/// Regards both *this and RHS as signed quantities and compares them for the
/// validity of the greater-than relationship.
@@ -1252,7 +1266,7 @@ public:
/// \returns true if *this > RHS when both are considered signed.
bool sgt(const APInt &RHS) const { return !sle(RHS); }
- /// \brief Signed greater than comparison
+ /// Signed greater than comparison
///
/// Regards both *this as a signed quantity and compares it with RHS for
/// the validity of the greater-than relationship.
@@ -1263,7 +1277,7 @@ public:
: getSExtValue() > RHS;
}
- /// \brief Unsigned greater or equal comparison
+ /// Unsigned greater or equal comparison
///
/// Regards both *this and RHS as unsigned quantities and compares them for
/// validity of the greater-or-equal relationship.
@@ -1271,7 +1285,7 @@ public:
/// \returns true if *this >= RHS when both are considered unsigned.
bool uge(const APInt &RHS) const { return !ult(RHS); }
- /// \brief Unsigned greater or equal comparison
+ /// Unsigned greater or equal comparison
///
/// Regards both *this as an unsigned quantity and compares it with RHS for
/// the validity of the greater-or-equal relationship.
@@ -1279,7 +1293,7 @@ public:
/// \returns true if *this >= RHS when considered unsigned.
bool uge(uint64_t RHS) const { return !ult(RHS); }
- /// \brief Signed greather or equal comparison
+ /// Signed greater or equal comparison
///
/// Regards both *this and RHS as signed quantities and compares them for
/// validity of the greater-or-equal relationship.
@@ -1287,7 +1301,7 @@ public:
/// \returns true if *this >= RHS when both are considered signed.
bool sge(const APInt &RHS) const { return !slt(RHS); }
- /// \brief Signed greater or equal comparison
+ /// Signed greater or equal comparison
///
/// Regards both *this as a signed quantity and compares it with RHS for
/// the validity of the greater-or-equal relationship.
@@ -1316,13 +1330,13 @@ public:
/// \name Resizing Operators
/// @{
- /// \brief Truncate to new width.
+ /// Truncate to new width.
///
/// 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;
- /// \brief Sign extend to a new width.
+ /// Sign extend to a new width.
///
/// This operation sign extends the APInt to a new width. If the high order
/// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
@@ -1330,32 +1344,32 @@ public:
/// current width.
APInt sext(unsigned width) const;
- /// \brief Zero extend to a new width.
+ /// 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;
- /// \brief Sign extend or truncate to width
+ /// 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;
- /// \brief Zero extend or truncate to width
+ /// 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;
- /// \brief Sign extend or truncate to width
+ /// 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;
- /// \brief Zero extend or truncate to width
+ /// 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.
@@ -1365,7 +1379,7 @@ public:
/// \name Bit Manipulation Operators
/// @{
- /// \brief Set every bit to 1.
+ /// Set every bit to 1.
void setAllBits() {
if (isSingleWord())
U.VAL = WORD_MAX;
@@ -1376,7 +1390,7 @@ public:
clearUnusedBits();
}
- /// \brief Set a given bit to 1.
+ /// Set a given bit to 1.
///
/// Set the given bit to 1 whose position is given as "bitPosition".
void setBit(unsigned BitPosition) {
@@ -1427,7 +1441,7 @@ public:
return setBits(BitWidth - hiBits, BitWidth);
}
- /// \brief Set every bit to 0.
+ /// Set every bit to 0.
void clearAllBits() {
if (isSingleWord())
U.VAL = 0;
@@ -1435,7 +1449,7 @@ public:
memset(U.pVal, 0, getNumWords() * APINT_WORD_SIZE);
}
- /// \brief Set a given bit to 0.
+ /// Set a given bit to 0.
///
/// Set the given bit to 0 whose position is given as "bitPosition".
void clearBit(unsigned BitPosition) {
@@ -1452,7 +1466,7 @@ public:
clearBit(BitWidth - 1);
}
- /// \brief Toggle every bit to its opposite value.
+ /// Toggle every bit to its opposite value.
void flipAllBits() {
if (isSingleWord()) {
U.VAL ^= WORD_MAX;
@@ -1462,7 +1476,7 @@ public:
}
}
- /// \brief Toggles a given bit to its opposite value.
+ /// Toggles a given bit to its opposite value.
///
/// Toggle a given bit to its opposite value whose position is given
/// as "bitPosition".
@@ -1484,17 +1498,17 @@ public:
/// \name Value Characterization Functions
/// @{
- /// \brief Return the number of bits in the APInt.
+ /// Return the number of bits in the APInt.
unsigned getBitWidth() const { return BitWidth; }
- /// \brief Get the number of words.
+ /// Get the number of words.
///
/// Here one word's bitwidth equals to that of uint64_t.
///
/// \returns the number of words to hold the integer value of this APInt.
unsigned getNumWords() const { return getNumWords(BitWidth); }
- /// \brief Get the number of words.
+ /// Get the number of words.
///
/// *NOTE* Here one word's bitwidth equals to that of uint64_t.
///
@@ -1504,14 +1518,14 @@ public:
return ((uint64_t)BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
}
- /// \brief Compute the number of active bits in the value
+ /// Compute the number of active bits in the value
///
/// This function returns the number of active bits which is defined as the
/// bit width minus the number of leading zeros. This is used in several
/// computations to see how "wide" the value is.
unsigned getActiveBits() const { return BitWidth - countLeadingZeros(); }
- /// \brief Compute the number of active words in the value of this APInt.
+ /// Compute the number of active words in the value of this APInt.
///
/// This is used in conjunction with getActiveData to extract the raw value of
/// the APInt.
@@ -1520,7 +1534,7 @@ public:
return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1;
}
- /// \brief Get the minimum bit size for this signed APInt
+ /// Get the minimum bit size for this signed APInt
///
/// Computes the minimum bit width for this APInt while considering it to be a
/// signed (and probably negative) value. If the value is not negative, this
@@ -1534,7 +1548,7 @@ public:
return getActiveBits() + 1;
}
- /// \brief Get zero extended value
+ /// Get zero extended value
///
/// This method attempts to return the value of this APInt as a zero extended
/// uint64_t. The bitwidth must be <= 64 or the value must fit within a
@@ -1546,7 +1560,7 @@ public:
return U.pVal[0];
}
- /// \brief Get sign extended value
+ /// Get sign extended value
///
/// This method attempts to return the value of this APInt as a sign extended
/// int64_t. The bit width must be <= 64 or the value must fit within an
@@ -1558,13 +1572,13 @@ public:
return int64_t(U.pVal[0]);
}
- /// \brief Get bits required for string value.
+ /// Get bits required for string value.
///
/// This method determines how many bits are required to hold the APInt
/// equivalent of the string given by \p str.
static unsigned getBitsNeeded(StringRef str, uint8_t radix);
- /// \brief The APInt version of the countLeadingZeros functions in
+ /// The APInt version of the countLeadingZeros functions in
/// MathExtras.h.
///
/// It counts the number of zeros from the most significant bit to the first
@@ -1580,7 +1594,7 @@ public:
return countLeadingZerosSlowCase();
}
- /// \brief Count the number of leading one bits.
+ /// Count the number of leading one bits.
///
/// This function is an APInt version of the countLeadingOnes
/// functions in MathExtras.h. It counts the number of ones from the most
@@ -1600,7 +1614,7 @@ public:
return isNegative() ? countLeadingOnes() : countLeadingZeros();
}
- /// \brief Count the number of trailing zero bits.
+ /// Count the number of trailing zero bits.
///
/// This function is an APInt version of the countTrailingZeros
/// functions in MathExtras.h. It counts the number of zeros from the least
@@ -1614,7 +1628,7 @@ public:
return countTrailingZerosSlowCase();
}
- /// \brief Count the number of trailing one bits.
+ /// Count the number of trailing one bits.
///
/// This function is an APInt version of the countTrailingOnes
/// functions in MathExtras.h. It counts the number of ones from the least
@@ -1628,7 +1642,7 @@ public:
return countTrailingOnesSlowCase();
}
- /// \brief Count the number of bits set.
+ /// Count the number of bits set.
///
/// This function is an APInt version of the countPopulation functions
/// in MathExtras.h. It counts the number of 1 bits in the APInt value.
@@ -1662,7 +1676,7 @@ public:
toString(Str, Radix, true, false);
}
- /// \brief Return the APInt as a std::string.
+ /// Return the APInt as a std::string.
///
/// Note that this is an inefficient method. It is better to pass in a
/// SmallVector/SmallString to the methods above to avoid thrashing the heap
@@ -1676,16 +1690,16 @@ public:
/// Value.
APInt reverseBits() const;
- /// \brief Converts this APInt to a double value.
+ /// Converts this APInt to a double value.
double roundToDouble(bool isSigned) const;
- /// \brief Converts this unsigned APInt to a double value.
+ /// Converts this unsigned APInt to a double value.
double roundToDouble() const { return roundToDouble(false); }
- /// \brief Converts this signed APInt to a double value.
+ /// Converts this signed APInt to a double value.
double signedRoundToDouble() const { return roundToDouble(true); }
- /// \brief Converts APInt bits to a double
+ /// Converts APInt bits to a double
///
/// The conversion does not do a translation from integer to double, it just
/// re-interprets the bits as a double. Note that it is valid to do this on
@@ -1694,7 +1708,7 @@ public:
return BitsToDouble(getWord(0));
}
- /// \brief Converts APInt bits to a double
+ /// Converts APInt bits to a double
///
/// The conversion does not do a translation from integer to float, it just
/// re-interprets the bits as a float. Note that it is valid to do this on
@@ -1703,7 +1717,7 @@ public:
return BitsToFloat(getWord(0));
}
- /// \brief Converts a double to APInt bits.
+ /// Converts a double to APInt bits.
///
/// The conversion does not do a translation from double to integer, it just
/// re-interprets the bits of the double.
@@ -1711,7 +1725,7 @@ public:
return APInt(sizeof(double) * CHAR_BIT, DoubleToBits(V));
}
- /// \brief Converts a float to APInt bits.
+ /// Converts a float to APInt bits.
///
/// The conversion does not do a translation from float to integer, it just
/// re-interprets the bits of the float.
@@ -1770,10 +1784,10 @@ public:
return logBase2();
}
- /// \brief Compute the square root
+ /// Compute the square root
APInt sqrt() const;
- /// \brief Get the absolute value;
+ /// Get the absolute value;
///
/// If *this is < 0 then return -(*this), otherwise *this;
APInt abs() const {
@@ -1924,7 +1938,7 @@ public:
/// Set the least significant BITS and clear the rest.
static void tcSetLeastSignificantBits(WordType *, unsigned, unsigned bits);
- /// \brief debug method
+ /// debug method
void dump() const;
/// @}
@@ -1947,7 +1961,7 @@ inline bool operator==(uint64_t V1, const APInt &V2) { return V2 == V1; }
inline bool operator!=(uint64_t V1, const APInt &V2) { return V2 != V1; }
-/// \brief Unary bitwise complement operator.
+/// Unary bitwise complement operator.
///
/// \returns an APInt that is the bitwise complement of \p v.
inline APInt operator~(APInt v) {
@@ -2080,27 +2094,27 @@ inline APInt operator*(uint64_t LHS, APInt b) {
namespace APIntOps {
-/// \brief Determine the smaller of two APInts considered to be signed.
+/// Determine the smaller of two APInts considered to be signed.
inline const APInt &smin(const APInt &A, const APInt &B) {
return A.slt(B) ? A : B;
}
-/// \brief Determine the larger of two APInts considered to be signed.
+/// Determine the larger of two APInts considered to be signed.
inline const APInt &smax(const APInt &A, const APInt &B) {
return A.sgt(B) ? A : B;
}
-/// \brief Determine the smaller of two APInts considered to be signed.
+/// Determine the smaller of two APInts considered to be signed.
inline const APInt &umin(const APInt &A, const APInt &B) {
return A.ult(B) ? A : B;
}
-/// \brief Determine the larger of two APInts considered to be unsigned.
+/// Determine the larger of two APInts considered to be unsigned.
inline const APInt &umax(const APInt &A, const APInt &B) {
return A.ugt(B) ? A : B;
}
-/// \brief Compute GCD of two unsigned APInt values.
+/// Compute GCD of two unsigned APInt values.
///
/// This function returns the greatest common divisor of the two APInt values
/// using Stein's algorithm.
@@ -2108,44 +2122,50 @@ inline const APInt &umax(const APInt &A, const APInt &B) {
/// \returns the greatest common divisor of A and B.
APInt GreatestCommonDivisor(APInt A, APInt B);
-/// \brief Converts the given APInt to a double value.
+/// Converts the given APInt to a double value.
///
/// Treats the APInt as an unsigned value for conversion purposes.
inline double RoundAPIntToDouble(const APInt &APIVal) {
return APIVal.roundToDouble();
}
-/// \brief Converts the given APInt to a double value.
+/// Converts the given APInt to a double value.
///
/// Treats the APInt as a signed value for conversion purposes.
inline double RoundSignedAPIntToDouble(const APInt &APIVal) {
return APIVal.signedRoundToDouble();
}
-/// \brief Converts the given APInt to a float vlalue.
+/// Converts the given APInt to a float vlalue.
inline float RoundAPIntToFloat(const APInt &APIVal) {
return float(RoundAPIntToDouble(APIVal));
}
-/// \brief Converts the given APInt to a float value.
+/// Converts the given APInt to a float value.
///
/// Treast the APInt as a signed value for conversion purposes.
inline float RoundSignedAPIntToFloat(const APInt &APIVal) {
return float(APIVal.signedRoundToDouble());
}
-/// \brief Converts the given double value into a APInt.
+/// Converts the given double value into a APInt.
///
/// This function convert a double value to an APInt value.
APInt RoundDoubleToAPInt(double Double, unsigned width);
-/// \brief Converts a float value into a APInt.
+/// Converts a float value into a APInt.
///
/// Converts a float value into an APInt value.
inline APInt RoundFloatToAPInt(float Float, unsigned width) {
return RoundDoubleToAPInt(double(Float), width);
}
+/// Return A unsign-divided by B, rounded by the given rounding mode.
+APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
+
+/// Return A sign-divided by B, rounded by the given rounding mode.
+APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
+
} // End of APIntOps namespace
// See friend declaration above. This additional declaration is required in
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index dabbf3314bd0..7ee2c4c62fce 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -72,7 +72,7 @@ public:
}
using APInt::toString;
- /// \brief Get the correctly-extended \c int64_t value.
+ /// Get the correctly-extended \c int64_t value.
int64_t getExtValue() const {
assert(getMinSignedBits() <= 64 && "Too many bits for int64_t");
return isSigned() ? getSExtValue() : getZExtValue();
@@ -279,13 +279,13 @@ public:
: APInt::getSignedMinValue(numBits), Unsigned);
}
- /// \brief Determine if two APSInts have the same value, zero- or
+ /// Determine if two APSInts have the same value, zero- or
/// sign-extending as needed.
static bool isSameValue(const APSInt &I1, const APSInt &I2) {
return !compareValues(I1, I2);
}
- /// \brief Compare underlying values of two numbers.
+ /// Compare underlying values of two numbers.
static int compareValues(const APSInt &I1, const APSInt &I2) {
if (I1.getBitWidth() == I2.getBitWidth() && I1.isSigned() == I2.isSigned())
return I1.IsUnsigned ? I1.compare(I2) : I1.compareSigned(I2);
diff --git a/include/llvm/ADT/Any.h b/include/llvm/ADT/Any.h
new file mode 100644
index 000000000000..c64c39987542
--- /dev/null
+++ b/include/llvm/ADT/Any.h
@@ -0,0 +1,150 @@
+//===- Any.h - Generic type erased holder of any type -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides Any, a non-template class modeled in the spirit of
+// std::any. The idea is to provide a type-safe replacement for C's void*.
+// It can hold a value of any copy-constructible copy-assignable type
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ANY_H
+#define LLVM_ADT_ANY_H
+
+#include "llvm/ADT/STLExtras.h"
+
+#include <cassert>
+#include <memory>
+#include <type_traits>
+
+namespace llvm {
+
+class Any {
+ template <typename T> struct TypeId { static const char Id; };
+
+ struct StorageBase {
+ virtual ~StorageBase() = default;
+ virtual std::unique_ptr<StorageBase> clone() const = 0;
+ virtual const void *id() const = 0;
+ };
+
+ template <typename T> struct StorageImpl : public StorageBase {
+ explicit StorageImpl(const T &Value) : Value(Value) {}
+
+ explicit StorageImpl(T &&Value) : Value(std::move(Value)) {}
+
+ std::unique_ptr<StorageBase> clone() const override {
+ return llvm::make_unique<StorageImpl<T>>(Value);
+ }
+
+ const void *id() const override { return &TypeId<T>::Id; }
+
+ T Value;
+
+ private:
+ StorageImpl &operator=(const StorageImpl &Other) = delete;
+ StorageImpl(const StorageImpl &Other) = delete;
+ };
+
+public:
+ Any() = default;
+
+ Any(const Any &Other)
+ : Storage(Other.Storage ? Other.Storage->clone() : nullptr) {}
+
+ // When T is Any or T is not copy-constructible we need to explicitly disable
+ // the forwarding constructor so that the copy constructor gets selected
+ // instead.
+ template <
+ typename T,
+ typename std::enable_if<
+ llvm::conjunction<
+ llvm::negation<std::is_same<typename std::decay<T>::type, Any>>,
+ std::is_copy_constructible<typename std::decay<T>::type>>::value,
+ int>::type = 0>
+ Any(T &&Value) {
+ using U = typename std::decay<T>::type;
+ Storage = llvm::make_unique<StorageImpl<U>>(std::forward<T>(Value));
+ }
+
+ Any(Any &&Other) : Storage(std::move(Other.Storage)) {}
+
+ Any &swap(Any &Other) {
+ std::swap(Storage, Other.Storage);
+ return *this;
+ }
+
+ Any &operator=(Any Other) {
+ Storage = std::move(Other.Storage);
+ return *this;
+ }
+
+ bool hasValue() const { return !!Storage; }
+
+ void reset() { Storage.reset(); }
+
+private:
+ template <class T> friend T any_cast(const Any &Value);
+ template <class T> friend T any_cast(Any &Value);
+ template <class T> friend T any_cast(Any &&Value);
+ template <class T> friend const T *any_cast(const Any *Value);
+ template <class T> friend T *any_cast(Any *Value);
+ template <typename T> friend bool any_isa(const Any &Value);
+
+ std::unique_ptr<StorageBase> Storage;
+};
+
+template <typename T> const char Any::TypeId<T>::Id = 0;
+
+
+template <typename T> bool any_isa(const Any &Value) {
+ if (!Value.Storage)
+ return false;
+ using U =
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+ return Value.Storage->id() == &Any::TypeId<U>::Id;
+}
+
+template <class T> T any_cast(const Any &Value) {
+ using U =
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+ return static_cast<T>(*any_cast<U>(&Value));
+}
+
+template <class T> T any_cast(Any &Value) {
+ using U =
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+ return static_cast<T>(*any_cast<U>(&Value));
+}
+
+template <class T> T any_cast(Any &&Value) {
+ using U =
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+ return static_cast<T>(std::move(*any_cast<U>(&Value)));
+}
+
+template <class T> const T *any_cast(const Any *Value) {
+ using U =
+ typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+ assert(Value && any_isa<T>(*Value) && "Bad any cast!");
+ if (!Value || !any_isa<U>(*Value))
+ return nullptr;
+ return &static_cast<Any::StorageImpl<U> &>(*Value->Storage).Value;
+}
+
+template <class T> T *any_cast(Any *Value) {
+ using U = typename std::decay<T>::type;
+ assert(Value && any_isa<U>(*Value) && "Bad any cast!");
+ if (!Value || !any_isa<U>(*Value))
+ return nullptr;
+ return &static_cast<Any::StorageImpl<U> &>(*Value->Storage).Value;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_ANY_H
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index 5f7a769ddac4..9cb25b09c6cb 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -184,51 +184,51 @@ namespace llvm {
/// slice(n) - Chop off the first N elements of the array.
ArrayRef<T> slice(size_t N) const { return slice(N, size() - N); }
- /// \brief Drop the first \p N elements of the array.
+ /// Drop the first \p N elements of the array.
ArrayRef<T> drop_front(size_t N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return slice(N, size() - N);
}
- /// \brief Drop the last \p N elements of the array.
+ /// Drop the last \p N elements of the array.
ArrayRef<T> drop_back(size_t N = 1) const {
assert(size() >= N && "Dropping more elements than exist");
return slice(0, size() - N);
}
- /// \brief Return a copy of *this with the first N elements satisfying the
+ /// Return a copy of *this with the first N elements satisfying the
/// given predicate removed.
template <class PredicateT> ArrayRef<T> drop_while(PredicateT Pred) const {
return ArrayRef<T>(find_if_not(*this, Pred), end());
}
- /// \brief Return a copy of *this with the first N elements not satisfying
+ /// Return a copy of *this with the first N elements not satisfying
/// the given predicate removed.
template <class PredicateT> ArrayRef<T> drop_until(PredicateT Pred) const {
return ArrayRef<T>(find_if(*this, Pred), end());
}
- /// \brief Return a copy of *this with only the first \p N elements.
+ /// Return a copy of *this with only the first \p N elements.
ArrayRef<T> take_front(size_t N = 1) const {
if (N >= size())
return *this;
return drop_back(size() - N);
}
- /// \brief Return a copy of *this with only the last \p N elements.
+ /// Return a copy of *this with only the last \p N elements.
ArrayRef<T> take_back(size_t N = 1) const {
if (N >= size())
return *this;
return drop_front(size() - N);
}
- /// \brief Return the first N elements of this Array that satisfy the given
+ /// Return the first N elements of this Array that satisfy the given
/// predicate.
template <class PredicateT> ArrayRef<T> take_while(PredicateT Pred) const {
return ArrayRef<T>(begin(), find_if_not(*this, Pred));
}
- /// \brief Return the first N elements of this Array that don't satisfy the
+ /// Return the first N elements of this Array that don't satisfy the
/// given predicate.
template <class PredicateT> ArrayRef<T> take_until(PredicateT Pred) const {
return ArrayRef<T>(begin(), find_if(*this, Pred));
@@ -358,7 +358,7 @@ namespace llvm {
return slice(N, this->size() - N);
}
- /// \brief Drop the first \p N elements of the array.
+ /// Drop the first \p N elements of the array.
MutableArrayRef<T> drop_front(size_t N = 1) const {
assert(this->size() >= N && "Dropping more elements than exist");
return slice(N, this->size() - N);
@@ -369,42 +369,42 @@ namespace llvm {
return slice(0, this->size() - N);
}
- /// \brief Return a copy of *this with the first N elements satisfying the
+ /// Return a copy of *this with the first N elements satisfying the
/// given predicate removed.
template <class PredicateT>
MutableArrayRef<T> drop_while(PredicateT Pred) const {
return MutableArrayRef<T>(find_if_not(*this, Pred), end());
}
- /// \brief Return a copy of *this with the first N elements not satisfying
+ /// Return a copy of *this with the first N elements not satisfying
/// the given predicate removed.
template <class PredicateT>
MutableArrayRef<T> drop_until(PredicateT Pred) const {
return MutableArrayRef<T>(find_if(*this, Pred), end());
}
- /// \brief Return a copy of *this with only the first \p N elements.
+ /// Return a copy of *this with only the first \p N elements.
MutableArrayRef<T> take_front(size_t N = 1) const {
if (N >= this->size())
return *this;
return drop_back(this->size() - N);
}
- /// \brief Return a copy of *this with only the last \p N elements.
+ /// Return a copy of *this with only the last \p N elements.
MutableArrayRef<T> take_back(size_t N = 1) const {
if (N >= this->size())
return *this;
return drop_front(this->size() - N);
}
- /// \brief Return the first N elements of this Array that satisfy the given
+ /// Return the first N elements of this Array that satisfy the given
/// predicate.
template <class PredicateT>
MutableArrayRef<T> take_while(PredicateT Pred) const {
return MutableArrayRef<T>(begin(), find_if_not(*this, Pred));
}
- /// \brief Return the first N elements of this Array that don't satisfy the
+ /// Return the first N elements of this Array that don't satisfy the
/// given predicate.
template <class PredicateT>
MutableArrayRef<T> take_until(PredicateT Pred) const {
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 99147fec4d4c..438c7d84c581 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -779,7 +779,7 @@ public:
}
private:
- /// \brief Perform a logical left shift of \p Count words by moving everything
+ /// Perform a logical left shift of \p Count words by moving everything
/// \p Count words to the right in memory.
///
/// While confusing, words are stored from least significant at Bits[0] to
@@ -810,7 +810,7 @@ private:
clear_unused_bits();
}
- /// \brief Perform a logical right shift of \p Count words by moving those
+ /// Perform a logical right shift of \p Count words by moving those
/// words to the left in memory. See wordShl for more information.
///
void wordShr(uint32_t Count) {
@@ -828,7 +828,8 @@ private:
}
MutableArrayRef<BitWord> allocate(size_t NumWords) {
- BitWord *RawBits = (BitWord *)std::malloc(NumWords * sizeof(BitWord));
+ BitWord *RawBits = static_cast<BitWord *>(
+ safe_malloc(NumWords * sizeof(BitWord)));
return MutableArrayRef<BitWord>(RawBits, NumWords);
}
@@ -867,8 +868,8 @@ private:
void grow(unsigned NewSize) {
size_t NewCapacity = std::max<size_t>(NumBitWords(NewSize), Bits.size() * 2);
assert(NewCapacity > 0 && "realloc-ing zero space");
- BitWord *NewBits =
- (BitWord *)std::realloc(Bits.data(), NewCapacity * sizeof(BitWord));
+ BitWord *NewBits = static_cast<BitWord *>(
+ safe_realloc(Bits.data(), NewCapacity * sizeof(BitWord)));
Bits = MutableArrayRef<BitWord>(NewBits, NewCapacity);
clear_unused_bits();
}
diff --git a/include/llvm/ADT/CachedHashString.h b/include/llvm/ADT/CachedHashString.h
index a56a6213a073..d8f0e7afdd49 100644
--- a/include/llvm/ADT/CachedHashString.h
+++ b/include/llvm/ADT/CachedHashString.h
@@ -43,6 +43,7 @@ public:
}
StringRef val() const { return StringRef(P, Size); }
+ const char *data() const { return P; }
uint32_t size() const { return Size; }
uint32_t hash() const { return Hash; }
};
diff --git a/include/llvm/ADT/DenseMapInfo.h b/include/llvm/ADT/DenseMapInfo.h
index a96904c7dbbf..5d12b424fb37 100644
--- a/include/llvm/ADT/DenseMapInfo.h
+++ b/include/llvm/ADT/DenseMapInfo.h
@@ -262,6 +262,13 @@ template <typename T> struct DenseMapInfo<ArrayRef<T>> {
}
};
+template <> struct DenseMapInfo<hash_code> {
+ static inline hash_code getEmptyKey() { return hash_code(-1); }
+ static inline hash_code getTombstoneKey() { return hash_code(-2); }
+ static unsigned getHashValue(hash_code val) { return val; }
+ static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
+};
+
} // end namespace llvm
#endif // LLVM_ADT_DENSEMAPINFO_H
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
index e964d7fa2391..1f3766d3c9de 100644
--- a/include/llvm/ADT/DepthFirstIterator.h
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -177,7 +177,7 @@ public:
return *this;
}
- /// \brief Skips all children of the current node and traverses to next node
+ /// Skips all children of the current node and traverses to next node
///
/// Note: This function takes care of incrementing the iterator. If you
/// always increment and call this function, you risk walking off the end.
diff --git a/include/llvm/ADT/EpochTracker.h b/include/llvm/ADT/EpochTracker.h
index db39ba4e0c50..49ef192364e8 100644
--- a/include/llvm/ADT/EpochTracker.h
+++ b/include/llvm/ADT/EpochTracker.h
@@ -17,7 +17,6 @@
#define LLVM_ADT_EPOCH_TRACKER_H
#include "llvm/Config/abi-breaking.h"
-#include "llvm/Config/llvm-config.h"
#include <cstdint>
@@ -25,7 +24,7 @@ namespace llvm {
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
-/// \brief A base class for data structure classes wishing to make iterators
+/// A base class for data structure classes wishing to make iterators
/// ("handles") pointing into themselves fail-fast. When building without
/// asserts, this class is empty and does nothing.
///
@@ -40,15 +39,15 @@ class DebugEpochBase {
public:
DebugEpochBase() : Epoch(0) {}
- /// \brief Calling incrementEpoch invalidates all handles pointing into the
+ /// Calling incrementEpoch invalidates all handles pointing into the
/// calling instance.
void incrementEpoch() { ++Epoch; }
- /// \brief The destructor calls incrementEpoch to make use-after-free bugs
+ /// The destructor calls incrementEpoch to make use-after-free bugs
/// more likely to crash deterministically.
~DebugEpochBase() { incrementEpoch(); }
- /// \brief A base class for iterator classes ("handles") that wish to poll for
+ /// A base class for iterator classes ("handles") that wish to poll for
/// iterator invalidating modifications in the underlying data structure.
/// When LLVM is built without asserts, this class is empty and does nothing.
///
@@ -66,12 +65,12 @@ public:
explicit HandleBase(const DebugEpochBase *Parent)
: EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch) {}
- /// \brief Returns true if the DebugEpochBase this Handle is linked to has
+ /// Returns true if the DebugEpochBase this Handle is linked to has
/// not called incrementEpoch on itself since the creation of this
/// HandleBase instance.
bool isHandleInSync() const { return *EpochAddress == EpochAtCreation; }
- /// \brief Returns a pointer to the epoch word stored in the data structure
+ /// Returns a pointer to the epoch word stored in the data structure
/// this handle points into. Can be used to check if two iterators point
/// into the same data structure.
const void *getEpochAddress() const { return EpochAddress; }
diff --git a/include/llvm/ADT/FunctionExtras.h b/include/llvm/ADT/FunctionExtras.h
new file mode 100644
index 000000000000..2b75dc6ac219
--- /dev/null
+++ b/include/llvm/ADT/FunctionExtras.h
@@ -0,0 +1,293 @@
+//===- FunctionExtras.h - Function type erasure utilities -------*- 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 collection of function (or more generally, callable)
+/// type erasure utilities supplementing those provided by the standard library
+/// in `<function>`.
+///
+/// It provides `unique_function`, which works like `std::function` but supports
+/// move-only callable objects.
+///
+/// Future plans:
+/// - Add a `function` that provides const, volatile, and ref-qualified support,
+/// which doesn't work with `std::function`.
+/// - Provide support for specifying multiple signatures to type erase callable
+/// objects with an overload set, such as those produced by generic lambdas.
+/// - Expand to include a copyable utility that directly replaces std::function
+/// but brings the above improvements.
+///
+/// Note that LLVM's utilities are greatly simplified by not supporting
+/// allocators.
+///
+/// If the standard library ever begins to provide comparable facilities we can
+/// consider switching to those.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_FUNCTION_EXTRAS_H
+#define LLVM_ADT_FUNCTION_EXTRAS_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/type_traits.h"
+#include <memory>
+
+namespace llvm {
+
+template <typename FunctionT> class unique_function;
+
+template <typename ReturnT, typename... ParamTs>
+class unique_function<ReturnT(ParamTs...)> {
+ static constexpr size_t InlineStorageSize = sizeof(void *) * 3;
+
+ // MSVC has a bug and ICEs if we give it a particular dependent value
+ // expression as part of the `std::conditional` below. To work around this,
+ // we build that into a template struct's constexpr bool.
+ template <typename T> struct IsSizeLessThanThresholdT {
+ static constexpr bool value = sizeof(T) <= (2 * sizeof(void *));
+ };
+
+ // Provide a type function to map parameters that won't observe extra copies
+ // or moves and which are small enough to likely pass in register to values
+ // and all other types to l-value reference types. We use this to compute the
+ // types used in our erased call utility to minimize copies and moves unless
+ // doing so would force things unnecessarily into memory.
+ //
+ // The heuristic used is related to common ABI register passing conventions.
+ // It doesn't have to be exact though, and in one way it is more strict
+ // because we want to still be able to observe either moves *or* copies.
+ template <typename T>
+ using AdjustedParamT = typename std::conditional<
+ !std::is_reference<T>::value &&
+ llvm::is_trivially_copy_constructible<T>::value &&
+ llvm::is_trivially_move_constructible<T>::value &&
+ IsSizeLessThanThresholdT<T>::value,
+ T, T &>::type;
+
+ // The type of the erased function pointer we use as a callback to dispatch to
+ // the stored callable when it is trivial to move and destroy.
+ using CallPtrT = ReturnT (*)(void *CallableAddr,
+ AdjustedParamT<ParamTs>... Params);
+ using MovePtrT = void (*)(void *LHSCallableAddr, void *RHSCallableAddr);
+ using DestroyPtrT = void (*)(void *CallableAddr);
+
+ /// A struct to hold a single trivial callback with sufficient alignment for
+ /// our bitpacking.
+ struct alignas(8) TrivialCallback {
+ CallPtrT CallPtr;
+ };
+
+ /// A struct we use to aggregate three callbacks when we need full set of
+ /// operations.
+ struct alignas(8) NonTrivialCallbacks {
+ CallPtrT CallPtr;
+ MovePtrT MovePtr;
+ DestroyPtrT DestroyPtr;
+ };
+
+ // Create a pointer union between either a pointer to a static trivial call
+ // pointer in a struct or a pointer to a static struct of the call, move, and
+ // destroy pointers.
+ using CallbackPointerUnionT =
+ PointerUnion<TrivialCallback *, NonTrivialCallbacks *>;
+
+ // The main storage buffer. This will either have a pointer to out-of-line
+ // storage or an inline buffer storing the callable.
+ union StorageUnionT {
+ // For out-of-line storage we keep a pointer to the underlying storage and
+ // the size. This is enough to deallocate the memory.
+ struct OutOfLineStorageT {
+ void *StoragePtr;
+ size_t Size;
+ size_t Alignment;
+ } OutOfLineStorage;
+ static_assert(
+ sizeof(OutOfLineStorageT) <= InlineStorageSize,
+ "Should always use all of the out-of-line storage for inline storage!");
+
+ // For in-line storage, we just provide an aligned character buffer. We
+ // provide three pointers worth of storage here.
+ typename std::aligned_storage<InlineStorageSize, alignof(void *)>::type
+ InlineStorage;
+ } StorageUnion;
+
+ // A compressed pointer to either our dispatching callback or our table of
+ // dispatching callbacks and the flag for whether the callable itself is
+ // stored inline or not.
+ PointerIntPair<CallbackPointerUnionT, 1, bool> CallbackAndInlineFlag;
+
+ bool isInlineStorage() const { return CallbackAndInlineFlag.getInt(); }
+
+ bool isTrivialCallback() const {
+ return CallbackAndInlineFlag.getPointer().template is<TrivialCallback *>();
+ }
+
+ CallPtrT getTrivialCallback() const {
+ return CallbackAndInlineFlag.getPointer().template get<TrivialCallback *>()->CallPtr;
+ }
+
+ NonTrivialCallbacks *getNonTrivialCallbacks() const {
+ return CallbackAndInlineFlag.getPointer()
+ .template get<NonTrivialCallbacks *>();
+ }
+
+ void *getInlineStorage() { return &StorageUnion.InlineStorage; }
+
+ void *getOutOfLineStorage() {
+ return StorageUnion.OutOfLineStorage.StoragePtr;
+ }
+ size_t getOutOfLineStorageSize() const {
+ return StorageUnion.OutOfLineStorage.Size;
+ }
+ size_t getOutOfLineStorageAlignment() const {
+ return StorageUnion.OutOfLineStorage.Alignment;
+ }
+
+ void setOutOfLineStorage(void *Ptr, size_t Size, size_t Alignment) {
+ StorageUnion.OutOfLineStorage = {Ptr, Size, Alignment};
+ }
+
+ template <typename CallableT>
+ static ReturnT CallImpl(void *CallableAddr, AdjustedParamT<ParamTs>... Params) {
+ return (*reinterpret_cast<CallableT *>(CallableAddr))(
+ std::forward<ParamTs>(Params)...);
+ }
+
+ template <typename CallableT>
+ static void MoveImpl(void *LHSCallableAddr, void *RHSCallableAddr) noexcept {
+ new (LHSCallableAddr)
+ CallableT(std::move(*reinterpret_cast<CallableT *>(RHSCallableAddr)));
+ }
+
+ template <typename CallableT>
+ static void DestroyImpl(void *CallableAddr) noexcept {
+ reinterpret_cast<CallableT *>(CallableAddr)->~CallableT();
+ }
+
+public:
+ unique_function() = default;
+ unique_function(std::nullptr_t /*null_callable*/) {}
+
+ ~unique_function() {
+ if (!CallbackAndInlineFlag.getPointer())
+ return;
+
+ // Cache this value so we don't re-check it after type-erased operations.
+ bool IsInlineStorage = isInlineStorage();
+
+ if (!isTrivialCallback())
+ getNonTrivialCallbacks()->DestroyPtr(
+ IsInlineStorage ? getInlineStorage() : getOutOfLineStorage());
+
+ if (!IsInlineStorage)
+ deallocate_buffer(getOutOfLineStorage(), getOutOfLineStorageSize(),
+ getOutOfLineStorageAlignment());
+ }
+
+ unique_function(unique_function &&RHS) noexcept {
+ // Copy the callback and inline flag.
+ CallbackAndInlineFlag = RHS.CallbackAndInlineFlag;
+
+ // If the RHS is empty, just copying the above is sufficient.
+ if (!RHS)
+ return;
+
+ if (!isInlineStorage()) {
+ // The out-of-line case is easiest to move.
+ StorageUnion.OutOfLineStorage = RHS.StorageUnion.OutOfLineStorage;
+ } else if (isTrivialCallback()) {
+ // Move is trivial, just memcpy the bytes across.
+ memcpy(getInlineStorage(), RHS.getInlineStorage(), InlineStorageSize);
+ } else {
+ // Non-trivial move, so dispatch to a type-erased implementation.
+ getNonTrivialCallbacks()->MovePtr(getInlineStorage(),
+ RHS.getInlineStorage());
+ }
+
+ // Clear the old callback and inline flag to get back to as-if-null.
+ RHS.CallbackAndInlineFlag = {};
+
+#ifndef NDEBUG
+ // In debug builds, we also scribble across the rest of the storage.
+ memset(RHS.getInlineStorage(), 0xAD, InlineStorageSize);
+#endif
+ }
+
+ unique_function &operator=(unique_function &&RHS) noexcept {
+ if (this == &RHS)
+ return *this;
+
+ // Because we don't try to provide any exception safety guarantees we can
+ // implement move assignment very simply by first destroying the current
+ // object and then move-constructing over top of it.
+ this->~unique_function();
+ new (this) unique_function(std::move(RHS));
+ return *this;
+ }
+
+ template <typename CallableT> unique_function(CallableT Callable) {
+ bool IsInlineStorage = true;
+ void *CallableAddr = getInlineStorage();
+ if (sizeof(CallableT) > InlineStorageSize ||
+ alignof(CallableT) > alignof(decltype(StorageUnion.InlineStorage))) {
+ IsInlineStorage = false;
+ // Allocate out-of-line storage. FIXME: Use an explicit alignment
+ // parameter in C++17 mode.
+ auto Size = sizeof(CallableT);
+ auto Alignment = alignof(CallableT);
+ CallableAddr = allocate_buffer(Size, Alignment);
+ setOutOfLineStorage(CallableAddr, Size, Alignment);
+ }
+
+ // Now move into the storage.
+ new (CallableAddr) CallableT(std::move(Callable));
+
+ // See if we can create a trivial callback. We need the callable to be
+ // trivially moved and trivially destroyed so that we don't have to store
+ // type erased callbacks for those operations.
+ //
+ // FIXME: We should use constexpr if here and below to avoid instantiating
+ // the non-trivial static objects when unnecessary. While the linker should
+ // remove them, it is still wasteful.
+ if (llvm::is_trivially_move_constructible<CallableT>::value &&
+ std::is_trivially_destructible<CallableT>::value) {
+ // We need to create a nicely aligned object. We use a static variable
+ // for this because it is a trivial struct.
+ static TrivialCallback Callback = { &CallImpl<CallableT> };
+
+ CallbackAndInlineFlag = {&Callback, IsInlineStorage};
+ return;
+ }
+
+ // Otherwise, we need to point at an object that contains all the different
+ // type erased behaviors needed. Create a static instance of the struct type
+ // here and then use a pointer to that.
+ static NonTrivialCallbacks Callbacks = {
+ &CallImpl<CallableT>, &MoveImpl<CallableT>, &DestroyImpl<CallableT>};
+
+ CallbackAndInlineFlag = {&Callbacks, IsInlineStorage};
+ }
+
+ ReturnT operator()(ParamTs... Params) {
+ void *CallableAddr =
+ isInlineStorage() ? getInlineStorage() : getOutOfLineStorage();
+
+ return (isTrivialCallback()
+ ? getTrivialCallback()
+ : getNonTrivialCallbacks()->CallPtr)(CallableAddr, Params...);
+ }
+
+ explicit operator bool() const {
+ return (bool)CallbackAndInlineFlag.getPointer();
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_FUNCTION_H
diff --git a/include/llvm/ADT/GraphTraits.h b/include/llvm/ADT/GraphTraits.h
index 225d9eb847f0..27c647f4bbbd 100644
--- a/include/llvm/ADT/GraphTraits.h
+++ b/include/llvm/ADT/GraphTraits.h
@@ -47,6 +47,19 @@ struct GraphTraits {
// static nodes_iterator nodes_end (GraphType *G)
// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ // typedef EdgeRef - Type of Edge token in the graph, which should
+ // be cheap to copy.
+ // typedef ChildEdgeIteratorType - Type used to iterate over children edges in
+ // graph, dereference to a EdgeRef.
+
+ // static ChildEdgeIteratorType child_edge_begin(NodeRef)
+ // static ChildEdgeIteratorType child_edge_end(NodeRef)
+ // Return iterators that point to the beginning and ending of the
+ // edge list for the given callgraph node.
+ //
+ // static NodeRef edge_dest(EdgeRef)
+ // Return the destination node of an edge.
+
// static unsigned size (GraphType *G)
// Return total number of nodes in the graph
@@ -111,6 +124,13 @@ inverse_children(const typename GraphTraits<GraphType>::NodeRef &G) {
GraphTraits<Inverse<GraphType>>::child_end(G));
}
+template <class GraphType>
+iterator_range<typename GraphTraits<GraphType>::ChildEdgeIteratorType>
+children_edges(const typename GraphTraits<GraphType>::NodeRef &G) {
+ return make_range(GraphTraits<GraphType>::child_edge_begin(G),
+ GraphTraits<GraphType>::child_edge_end(G));
+}
+
} // end namespace llvm
#endif // LLVM_ADT_GRAPHTRAITS_H
diff --git a/include/llvm/ADT/Hashing.h b/include/llvm/ADT/Hashing.h
index c3b574102f69..9f830baa4243 100644
--- a/include/llvm/ADT/Hashing.h
+++ b/include/llvm/ADT/Hashing.h
@@ -57,7 +57,7 @@
namespace llvm {
-/// \brief An opaque object representing a hash code.
+/// An opaque object representing a hash code.
///
/// This object represents the result of hashing some entity. It is intended to
/// be used to implement hashtables or other hashing-based data structures.
@@ -73,14 +73,14 @@ class hash_code {
size_t value;
public:
- /// \brief Default construct a hash_code.
+ /// Default construct a hash_code.
/// Note that this leaves the value uninitialized.
hash_code() = default;
- /// \brief Form a hash code directly from a numerical value.
+ /// Form a hash code directly from a numerical value.
hash_code(size_t value) : value(value) {}
- /// \brief Convert the hash code to its numerical value for use.
+ /// Convert the hash code to its numerical value for use.
/*explicit*/ operator size_t() const { return value; }
friend bool operator==(const hash_code &lhs, const hash_code &rhs) {
@@ -90,11 +90,11 @@ public:
return lhs.value != rhs.value;
}
- /// \brief Allow a hash_code to be directly run through hash_value.
+ /// Allow a hash_code to be directly run through hash_value.
friend size_t hash_value(const hash_code &code) { return code.value; }
};
-/// \brief Compute a hash_code for any integer value.
+/// Compute a hash_code for any integer value.
///
/// Note that this function is intended to compute the same hash_code for
/// a particular value without regard to the pre-promotion type. This is in
@@ -105,21 +105,21 @@ template <typename T>
typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
hash_value(T value);
-/// \brief Compute a hash_code for a pointer's address.
+/// Compute a hash_code for a pointer's address.
///
/// N.B.: This hashes the *address*. Not the value and not the type.
template <typename T> hash_code hash_value(const T *ptr);
-/// \brief Compute a hash_code for a pair of objects.
+/// Compute a hash_code for a pair of objects.
template <typename T, typename U>
hash_code hash_value(const std::pair<T, U> &arg);
-/// \brief Compute a hash_code for a standard string.
+/// Compute a hash_code for a standard string.
template <typename T>
hash_code hash_value(const std::basic_string<T> &arg);
-/// \brief Override the execution seed with a fixed value.
+/// Override the execution seed with a fixed value.
///
/// This hashing library uses a per-execution seed designed to change on each
/// run with high probability in order to ensure that the hash codes are not
@@ -164,7 +164,7 @@ static const uint64_t k1 = 0xb492b66fbe98f273ULL;
static const uint64_t k2 = 0x9ae16a3b2f90404fULL;
static const uint64_t k3 = 0xc949d7c7509e6557ULL;
-/// \brief Bitwise right rotate.
+/// Bitwise right rotate.
/// Normally this will compile to a single instruction, especially if the
/// shift is a manifest constant.
inline uint64_t rotate(uint64_t val, size_t shift) {
@@ -254,13 +254,13 @@ inline uint64_t hash_short(const char *s, size_t length, uint64_t seed) {
return k2 ^ seed;
}
-/// \brief The intermediate state used during hashing.
+/// The intermediate state used during hashing.
/// Currently, the algorithm for computing hash codes is based on CityHash and
/// keeps 56 bytes of arbitrary state.
struct hash_state {
uint64_t h0, h1, h2, h3, h4, h5, h6;
- /// \brief Create a new hash_state structure and initialize it based on the
+ /// Create a new hash_state structure and initialize it based on the
/// seed and the first 64-byte chunk.
/// This effectively performs the initial mix.
static hash_state create(const char *s, uint64_t seed) {
@@ -272,7 +272,7 @@ struct hash_state {
return state;
}
- /// \brief Mix 32-bytes from the input sequence into the 16-bytes of 'a'
+ /// Mix 32-bytes from the input sequence into the 16-bytes of 'a'
/// and 'b', including whatever is already in 'a' and 'b'.
static void mix_32_bytes(const char *s, uint64_t &a, uint64_t &b) {
a += fetch64(s);
@@ -284,7 +284,7 @@ struct hash_state {
a += c;
}
- /// \brief Mix in a 64-byte buffer of data.
+ /// Mix in a 64-byte buffer of data.
/// We mix all 64 bytes even when the chunk length is smaller, but we
/// record the actual length.
void mix(const char *s) {
@@ -302,7 +302,7 @@ struct hash_state {
std::swap(h2, h0);
}
- /// \brief Compute the final 64-bit hash code value based on the current
+ /// Compute the final 64-bit hash code value based on the current
/// state and the length of bytes hashed.
uint64_t finalize(size_t length) {
return hash_16_bytes(hash_16_bytes(h3, h5) + shift_mix(h1) * k1 + h2,
@@ -311,7 +311,7 @@ struct hash_state {
};
-/// \brief A global, fixed seed-override variable.
+/// A global, fixed seed-override variable.
///
/// This variable can be set using the \see llvm::set_fixed_execution_seed
/// function. See that function for details. Do not, under any circumstances,
@@ -332,7 +332,7 @@ inline size_t get_execution_seed() {
}
-/// \brief Trait to indicate whether a type's bits can be hashed directly.
+/// Trait to indicate whether a type's bits can be hashed directly.
///
/// A type trait which is true if we want to combine values for hashing by
/// reading the underlying data. It is false if values of this type must
@@ -359,14 +359,14 @@ template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
(sizeof(T) + sizeof(U)) ==
sizeof(std::pair<T, U>))> {};
-/// \brief Helper to get the hashable data representation for a type.
+/// Helper to get the hashable data representation for a type.
/// This variant is enabled when the type itself can be used.
template <typename T>
typename std::enable_if<is_hashable_data<T>::value, T>::type
get_hashable_data(const T &value) {
return value;
}
-/// \brief Helper to get the hashable data representation for a type.
+/// Helper to get the hashable data representation for a type.
/// This variant is enabled when we must first call hash_value and use the
/// result as our data.
template <typename T>
@@ -376,7 +376,7 @@ get_hashable_data(const T &value) {
return hash_value(value);
}
-/// \brief Helper to store data from a value into a buffer and advance the
+/// Helper to store data from a value into a buffer and advance the
/// pointer into that buffer.
///
/// This routine first checks whether there is enough space in the provided
@@ -395,7 +395,7 @@ bool store_and_advance(char *&buffer_ptr, char *buffer_end, const T& value,
return true;
}
-/// \brief Implement the combining of integral values into a hash_code.
+/// Implement the combining of integral values into a hash_code.
///
/// This overload is selected when the value type of the iterator is
/// integral. Rather than computing a hash_code for each object and then
@@ -435,7 +435,7 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
return state.finalize(length);
}
-/// \brief Implement the combining of integral values into a hash_code.
+/// Implement the combining of integral values into a hash_code.
///
/// This overload is selected when the value type of the iterator is integral
/// and when the input iterator is actually a pointer. Rather than computing
@@ -470,7 +470,7 @@ hash_combine_range_impl(ValueT *first, ValueT *last) {
} // namespace hashing
-/// \brief Compute a hash_code for a sequence of values.
+/// Compute a hash_code for a sequence of values.
///
/// This hashes a sequence of values. It produces the same hash_code as
/// 'hash_combine(a, b, c, ...)', but can run over arbitrary sized sequences
@@ -486,7 +486,7 @@ hash_code hash_combine_range(InputIteratorT first, InputIteratorT last) {
namespace hashing {
namespace detail {
-/// \brief Helper class to manage the recursive combining of hash_combine
+/// Helper class to manage the recursive combining of hash_combine
/// arguments.
///
/// This class exists to manage the state and various calls involved in the
@@ -499,14 +499,14 @@ struct hash_combine_recursive_helper {
const size_t seed;
public:
- /// \brief Construct a recursive hash combining helper.
+ /// Construct a recursive hash combining helper.
///
/// This sets up the state for a recursive hash combine, including getting
/// the seed and buffer setup.
hash_combine_recursive_helper()
: seed(get_execution_seed()) {}
- /// \brief Combine one chunk of data into the current in-flight hash.
+ /// Combine one chunk of data into the current in-flight hash.
///
/// This merges one chunk of data into the hash. First it tries to buffer
/// the data. If the buffer is full, it hashes the buffer into its
@@ -547,7 +547,7 @@ public:
return buffer_ptr;
}
- /// \brief Recursive, variadic combining method.
+ /// Recursive, variadic combining method.
///
/// This function recurses through each argument, combining that argument
/// into a single hash.
@@ -560,7 +560,7 @@ public:
return combine(length, buffer_ptr, buffer_end, args...);
}
- /// \brief Base case for recursive, variadic combining.
+ /// Base case for recursive, variadic combining.
///
/// The base case when combining arguments recursively is reached when all
/// arguments have been handled. It flushes the remaining buffer and
@@ -588,7 +588,7 @@ public:
} // namespace detail
} // namespace hashing
-/// \brief Combine values into a single hash_code.
+/// Combine values into a single hash_code.
///
/// This routine accepts a varying number of arguments of any type. It will
/// attempt to combine them into a single hash_code. For user-defined types it
@@ -610,7 +610,7 @@ template <typename ...Ts> hash_code hash_combine(const Ts &...args) {
namespace hashing {
namespace detail {
-/// \brief Helper to hash the value of a single integer.
+/// Helper to hash the value of a single integer.
///
/// Overloads for smaller integer types are not provided to ensure consistent
/// behavior in the presence of integral promotions. Essentially,
diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h
index 60d63e09d426..1f5e9813798d 100644
--- a/include/llvm/ADT/ImmutableList.h
+++ b/include/llvm/ADT/ImmutableList.h
@@ -166,7 +166,7 @@ public:
if (ownsAllocator()) delete &getAllocator();
}
- ImmutableList<T> concat(const T& Head, ImmutableList<T> Tail) {
+ LLVM_NODISCARD ImmutableList<T> concat(const T &Head, ImmutableList<T> Tail) {
// Profile the new list to see if it already exists in our cache.
FoldingSetNodeID ID;
void* InsertPos;
@@ -188,7 +188,7 @@ public:
return L;
}
- ImmutableList<T> add(const T& D, ImmutableList<T> L) {
+ LLVM_NODISCARD ImmutableList<T> add(const T& D, ImmutableList<T> L) {
return concat(D, L);
}
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index 10d1e1f0139b..cbc27ff17ccf 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -114,12 +114,13 @@ public:
ImmutableMap getEmptyMap() { return ImmutableMap(F.getEmptyTree()); }
- ImmutableMap add(ImmutableMap Old, key_type_ref K, data_type_ref D) {
+ LLVM_NODISCARD ImmutableMap add(ImmutableMap Old, key_type_ref K,
+ data_type_ref D) {
TreeTy *T = F.add(Old.Root, std::pair<key_type,data_type>(K,D));
return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
}
- ImmutableMap remove(ImmutableMap Old, key_type_ref K) {
+ LLVM_NODISCARD ImmutableMap remove(ImmutableMap Old, key_type_ref K) {
TreeTy *T = F.remove(Old.Root,K);
return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
}
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index 9d580c5a3d41..b1d5f4ac42e4 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -1017,7 +1017,7 @@ public:
/// of this operation is logarithmic in the size of the original set.
/// The memory allocated to represent the set is released when the
/// factory object that created the set is destroyed.
- ImmutableSet add(ImmutableSet Old, value_type_ref V) {
+ LLVM_NODISCARD ImmutableSet add(ImmutableSet Old, value_type_ref V) {
TreeTy *NewT = F.add(Old.Root, V);
return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
}
@@ -1029,7 +1029,7 @@ public:
/// of this operation is logarithmic in the size of the original set.
/// The memory allocated to represent the set is released when the
/// factory object that created the set is destroyed.
- ImmutableSet remove(ImmutableSet Old, value_type_ref V) {
+ LLVM_NODISCARD ImmutableSet remove(ImmutableSet Old, value_type_ref V) {
TreeTy *NewT = F.remove(Old.Root, V);
return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
}
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
index 3d78f4b203c8..47b4987f210a 100644
--- a/include/llvm/ADT/MapVector.h
+++ b/include/llvm/ADT/MapVector.h
@@ -36,13 +36,17 @@ template<typename KeyT, typename ValueT,
typename MapType = DenseMap<KeyT, unsigned>,
typename VectorType = std::vector<std::pair<KeyT, ValueT>>>
class MapVector {
- using value_type = typename VectorType::value_type;
- using size_type = typename VectorType::size_type;
-
MapType Map;
VectorType Vector;
+ static_assert(
+ std::is_integral<typename MapType::mapped_type>::value,
+ "The mapped_type of the specified Map must be an integral type");
+
public:
+ using value_type = typename VectorType::value_type;
+ using size_type = typename VectorType::size_type;
+
using iterator = typename VectorType::iterator;
using const_iterator = typename VectorType::const_iterator;
using reverse_iterator = typename VectorType::reverse_iterator;
@@ -93,9 +97,9 @@ public:
}
ValueT &operator[](const KeyT &Key) {
- std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
+ std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(Key, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
- unsigned &I = Result.first->second;
+ auto &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::make_pair(Key, ValueT()));
I = Vector.size() - 1;
@@ -112,9 +116,9 @@ public:
}
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
- std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0);
+ std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
- unsigned &I = Result.first->second;
+ auto &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::make_pair(KV.first, KV.second));
I = Vector.size() - 1;
@@ -125,9 +129,9 @@ public:
std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
// Copy KV.first into the map, then move it into the vector.
- std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0);
+ std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
- unsigned &I = Result.first->second;
+ auto &I = Result.first->second;
if (Result.second) {
Vector.push_back(std::move(KV));
I = Vector.size() - 1;
@@ -153,14 +157,14 @@ public:
(Vector.begin() + Pos->second);
}
- /// \brief Remove the last element from the vector.
+ /// Remove the last element from the vector.
void pop_back() {
typename MapType::iterator Pos = Map.find(Vector.back().first);
Map.erase(Pos);
Vector.pop_back();
}
- /// \brief Remove the element given by Iterator.
+ /// Remove the element given by Iterator.
///
/// Returns an iterator to the element following the one which was removed,
/// which may be end().
@@ -183,7 +187,7 @@ public:
return Next;
}
- /// \brief Remove all elements with the key value Key.
+ /// Remove all elements with the key value Key.
///
/// Returns the number of elements removed.
size_type erase(const KeyT &Key) {
@@ -194,7 +198,7 @@ public:
return 1;
}
- /// \brief Remove the elements that match the predicate.
+ /// Remove the elements that match the predicate.
///
/// Erase all elements that match \c Pred in a single pass. Takes linear
/// time.
@@ -223,7 +227,7 @@ void MapVector<KeyT, ValueT, MapType, VectorType>::remove_if(Function Pred) {
Vector.erase(O, Vector.end());
}
-/// \brief A MapVector that performs no allocations if smaller than a certain
+/// A MapVector that performs no allocations if smaller than a certain
/// size.
template <typename KeyT, typename ValueT, unsigned N>
struct SmallMapVector
diff --git a/include/llvm/ADT/None.h b/include/llvm/ADT/None.h
index c7a99c61994e..4b6bc1e005b5 100644
--- a/include/llvm/ADT/None.h
+++ b/include/llvm/ADT/None.h
@@ -17,7 +17,7 @@
#define LLVM_ADT_NONE_H
namespace llvm {
-/// \brief A simple null object to allow implicit construction of Optional<T>
+/// A simple null object to allow implicit construction of Optional<T>
/// and similar types without having to spell out the specialization's name.
// (constant value 1 in an attempt to workaround MSVC build issue... )
enum class NoneType { None = 1 };
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index 2811d5c1e21b..353e5d0ec9df 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -27,124 +27,164 @@
namespace llvm {
-template <typename T> class Optional {
+namespace optional_detail {
+/// Storage for any type.
+template <typename T, bool IsPodLike> struct OptionalStorage {
AlignedCharArrayUnion<T> storage;
bool hasVal = false;
-public:
- using value_type = T;
-
- Optional(NoneType) {}
- explicit Optional() {}
-
- Optional(const T &y) : hasVal(true) { new (storage.buffer) T(y); }
+ OptionalStorage() = default;
- Optional(const Optional &O) : hasVal(O.hasVal) {
+ OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); }
+ OptionalStorage(const OptionalStorage &O) : hasVal(O.hasVal) {
if (hasVal)
- new (storage.buffer) T(*O);
+ new (storage.buffer) T(*O.getPointer());
}
-
- Optional(T &&y) : hasVal(true) { new (storage.buffer) T(std::forward<T>(y)); }
-
- Optional(Optional<T> &&O) : hasVal(O) {
- if (O) {
- new (storage.buffer) T(std::move(*O));
- O.reset();
+ OptionalStorage(T &&y) : hasVal(true) {
+ new (storage.buffer) T(std::forward<T>(y));
+ }
+ OptionalStorage(OptionalStorage &&O) : hasVal(O.hasVal) {
+ if (O.hasVal) {
+ new (storage.buffer) T(std::move(*O.getPointer()));
}
}
- ~Optional() { reset(); }
-
- Optional &operator=(T &&y) {
+ OptionalStorage &operator=(T &&y) {
if (hasVal)
- **this = std::move(y);
+ *getPointer() = std::move(y);
else {
new (storage.buffer) T(std::move(y));
hasVal = true;
}
return *this;
}
-
- Optional &operator=(Optional &&O) {
- if (!O)
+ OptionalStorage &operator=(OptionalStorage &&O) {
+ if (!O.hasVal)
reset();
else {
- *this = std::move(*O);
- O.reset();
+ *this = std::move(*O.getPointer());
}
return *this;
}
- /// Create a new object by constructing it in place with the given arguments.
- 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) {
- return y ? Optional(*y) : Optional();
- }
-
// FIXME: these assignments (& the equivalent const T&/const Optional& ctors)
// could be made more efficient by passing by value, possibly unifying them
// with the rvalue versions above - but this could place a different set of
// requirements (notably: the existence of a default ctor) when implemented
// in that way. Careful SFINAE to avoid such pitfalls would be required.
- Optional &operator=(const T &y) {
+ OptionalStorage &operator=(const T &y) {
if (hasVal)
- **this = y;
+ *getPointer() = y;
else {
new (storage.buffer) T(y);
hasVal = true;
}
return *this;
}
-
- Optional &operator=(const Optional &O) {
- if (!O)
+ OptionalStorage &operator=(const OptionalStorage &O) {
+ if (!O.hasVal)
reset();
else
- *this = *O;
+ *this = *O.getPointer();
return *this;
}
+ ~OptionalStorage() { reset(); }
+
void reset() {
if (hasVal) {
- (**this).~T();
+ (*getPointer()).~T();
hasVal = false;
}
}
- 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 {
+ const T *getPointer() const {
assert(hasVal);
- return *getPointer();
+ return reinterpret_cast<const T *>(storage.buffer);
}
- T &getValue() LLVM_LVALUE_FUNCTION {
- assert(hasVal);
- return *getPointer();
+};
+
+#if !defined(__GNUC__) || defined(__clang__) // GCC up to GCC7 miscompiles this.
+/// Storage for trivially copyable types only.
+template <typename T> struct OptionalStorage<T, true> {
+ AlignedCharArrayUnion<T> storage;
+ bool hasVal = false;
+
+ OptionalStorage() = default;
+
+ OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); }
+ OptionalStorage &operator=(const T &y) {
+ *reinterpret_cast<T *>(storage.buffer) = y;
+ hasVal = true;
+ return *this;
}
- 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();
+ void reset() { hasVal = false; }
+};
+#endif
+} // namespace optional_detail
+
+template <typename T> class Optional {
+ optional_detail::OptionalStorage<T, isPodLike<T>::value> Storage;
+
+public:
+ using value_type = T;
+
+ constexpr Optional() {}
+ constexpr Optional(NoneType) {}
+
+ Optional(const T &y) : Storage(y) {}
+ Optional(const Optional &O) = default;
+
+ Optional(T &&y) : Storage(std::forward<T>(y)) {}
+ Optional(Optional &&O) = default;
+
+ Optional &operator=(T &&y) {
+ Storage = std::move(y);
+ return *this;
}
- T &operator*() LLVM_LVALUE_FUNCTION {
- assert(hasVal);
- return *getPointer();
+ Optional &operator=(Optional &&O) = default;
+
+ /// Create a new object by constructing it in place with the given arguments.
+ template <typename... ArgTypes> void emplace(ArgTypes &&... Args) {
+ reset();
+ Storage.hasVal = true;
+ new (getPointer()) T(std::forward<ArgTypes>(Args)...);
+ }
+
+ static inline Optional create(const T *y) {
+ return y ? Optional(*y) : Optional();
+ }
+
+ Optional &operator=(const T &y) {
+ Storage = y;
+ return *this;
+ }
+ Optional &operator=(const Optional &O) = default;
+
+ void reset() { Storage.reset(); }
+
+ const T *getPointer() const {
+ assert(Storage.hasVal);
+ return reinterpret_cast<const T *>(Storage.storage.buffer);
+ }
+ T *getPointer() {
+ assert(Storage.hasVal);
+ return reinterpret_cast<T *>(Storage.storage.buffer);
}
+ const T &getValue() const LLVM_LVALUE_FUNCTION { return *getPointer(); }
+ T &getValue() LLVM_LVALUE_FUNCTION { return *getPointer(); }
+
+ explicit operator bool() const { return Storage.hasVal; }
+ bool hasValue() const { return Storage.hasVal; }
+ const T *operator->() const { return getPointer(); }
+ T *operator->() { return getPointer(); }
+ const T &operator*() const LLVM_LVALUE_FUNCTION { return *getPointer(); }
+ T &operator*() LLVM_LVALUE_FUNCTION { return *getPointer(); }
template <typename U>
constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION {
@@ -152,14 +192,8 @@ 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() && { return std::move(*getPointer()); }
+ T &&operator*() && { return std::move(*getPointer()); }
template <typename U>
T getValueOr(U &&value) && {
diff --git a/include/llvm/ADT/PackedVector.h b/include/llvm/ADT/PackedVector.h
index 95adc2926813..3d53c49536d0 100644
--- a/include/llvm/ADT/PackedVector.h
+++ b/include/llvm/ADT/PackedVector.h
@@ -65,7 +65,7 @@ protected:
}
};
-/// \brief Store a vector of values using a specific number of bits for each
+/// Store a vector of values using a specific number of bits for each
/// value. Both signed and unsigned types can be used, e.g
/// @code
/// PackedVector<signed, 2> vec;
diff --git a/include/llvm/ADT/PointerUnion.h b/include/llvm/ADT/PointerUnion.h
index 4276859e9254..315e58336cba 100644
--- a/include/llvm/ADT/PointerUnion.h
+++ b/include/llvm/ADT/PointerUnion.h
@@ -346,6 +346,12 @@ struct PointerLikeTypeTraits<PointerUnion3<PT1, PT2, PT3>> {
};
};
+template <typename PT1, typename PT2, typename PT3>
+bool operator<(PointerUnion3<PT1, PT2, PT3> lhs,
+ PointerUnion3<PT1, PT2, PT3> rhs) {
+ return lhs.getOpaqueValue() < rhs.getOpaqueValue();
+}
+
/// A pointer union of four pointer types. See documentation for PointerUnion
/// for usage.
template <typename PT1, typename PT2, typename PT3, typename PT4>
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
index 784a58dc002f..ab1dc4613be0 100644
--- a/include/llvm/ADT/SCCIterator.h
+++ b/include/llvm/ADT/SCCIterator.h
@@ -33,7 +33,7 @@
namespace llvm {
-/// \brief Enumerate the SCCs of a directed graph in reverse topological order
+/// Enumerate the SCCs of a directed graph in reverse topological order
/// of the SCC DAG.
///
/// This is implemented using Tarjan's DFS algorithm using an internal stack to
@@ -104,7 +104,7 @@ public:
}
static scc_iterator end(const GraphT &) { return scc_iterator(); }
- /// \brief Direct loop termination test which is more efficient than
+ /// Direct loop termination test which is more efficient than
/// comparison with \c end().
bool isAtEnd() const {
assert(!CurrentSCC.empty() || VisitStack.empty());
@@ -125,7 +125,7 @@ public:
return CurrentSCC;
}
- /// \brief Test if the current SCC has a loop.
+ /// Test if the current SCC has a loop.
///
/// If the SCC has more than one node, this is trivially true. If not, it may
/// still contain a loop if the node has an edge back to itself.
@@ -222,12 +222,12 @@ bool scc_iterator<GraphT, GT>::hasLoop() const {
return false;
}
-/// \brief Construct the begin iterator for a deduced graph type T.
+/// Construct the begin iterator for a deduced graph type T.
template <class T> scc_iterator<T> scc_begin(const T &G) {
return scc_iterator<T>::begin(G);
}
-/// \brief Construct the end iterator for a deduced graph type T.
+/// Construct the end iterator for a deduced graph type T.
template <class T> scc_iterator<T> scc_end(const T &G) {
return scc_iterator<T>::end(G);
}
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
index bcd992b4a716..94365dd9ced1 100644
--- a/include/llvm/ADT/STLExtras.h
+++ b/include/llvm/ADT/STLExtras.h
@@ -36,6 +36,10 @@
#include <type_traits>
#include <utility>
+#ifdef EXPENSIVE_CHECKS
+#include <random> // for std::mt19937
+#endif
+
namespace llvm {
// Only used by compiler if both template types are the same. Useful when
@@ -54,6 +58,19 @@ using ValueOfRange = typename std::remove_reference<decltype(
} // end namespace detail
//===----------------------------------------------------------------------===//
+// Extra additions to <type_traits>
+//===----------------------------------------------------------------------===//
+
+template <typename T>
+struct negation : std::integral_constant<bool, !bool(T::value)> {};
+
+template <typename...> struct conjunction : std::true_type {};
+template <typename B1> struct conjunction<B1> : B1 {};
+template <typename B1, typename... Bn>
+struct conjunction<B1, Bn...>
+ : std::conditional<bool(B1::value), conjunction<Bn...>, B1>::type {};
+
+//===----------------------------------------------------------------------===//
// Extra additions to <functional>
//===----------------------------------------------------------------------===//
@@ -101,6 +118,7 @@ class function_ref<Ret(Params...)> {
public:
function_ref() = default;
+ function_ref(std::nullptr_t) {}
template <typename Callable>
function_ref(Callable &&callable,
@@ -266,60 +284,121 @@ auto reverse(
/// auto R = make_filter_range(A, [](int N) { return N % 2 == 1; });
/// // R contains { 1, 3 }.
/// \endcode
-template <typename WrappedIteratorT, typename PredicateT>
-class filter_iterator
+///
+/// Note: filter_iterator_base implements support for forward iteration.
+/// filter_iterator_impl exists to provide support for bidirectional iteration,
+/// conditional on whether the wrapped iterator supports it.
+template <typename WrappedIteratorT, typename PredicateT, typename IterTag>
+class filter_iterator_base
: public iterator_adaptor_base<
- filter_iterator<WrappedIteratorT, PredicateT>, WrappedIteratorT,
+ filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
+ WrappedIteratorT,
typename std::common_type<
- std::forward_iterator_tag,
- typename std::iterator_traits<
- WrappedIteratorT>::iterator_category>::type> {
+ IterTag, typename std::iterator_traits<
+ WrappedIteratorT>::iterator_category>::type> {
using BaseT = iterator_adaptor_base<
- filter_iterator<WrappedIteratorT, PredicateT>, WrappedIteratorT,
+ filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>,
+ WrappedIteratorT,
typename std::common_type<
- std::forward_iterator_tag,
- typename std::iterator_traits<WrappedIteratorT>::iterator_category>::
- type>;
+ IterTag, typename std::iterator_traits<
+ WrappedIteratorT>::iterator_category>::type>;
- struct PayloadType {
- WrappedIteratorT End;
- PredicateT Pred;
- };
-
- Optional<PayloadType> Payload;
+protected:
+ WrappedIteratorT End;
+ PredicateT Pred;
void findNextValid() {
- assert(Payload && "Payload should be engaged when findNextValid is called");
- while (this->I != Payload->End && !Payload->Pred(*this->I))
+ while (this->I != End && !Pred(*this->I))
BaseT::operator++();
}
- // Construct the begin iterator. The begin iterator requires to know where end
- // is, so that it can properly stop when it hits end.
- filter_iterator(WrappedIteratorT Begin, WrappedIteratorT End, PredicateT Pred)
- : BaseT(std::move(Begin)),
- Payload(PayloadType{std::move(End), std::move(Pred)}) {
+ // Construct the iterator. The begin iterator needs to know where the end
+ // is, so that it can properly stop when it gets there. The end iterator only
+ // needs the predicate to support bidirectional iteration.
+ filter_iterator_base(WrappedIteratorT Begin, WrappedIteratorT End,
+ PredicateT Pred)
+ : BaseT(Begin), End(End), Pred(Pred) {
findNextValid();
}
- // Construct the end iterator. It's not incrementable, so Payload doesn't
- // have to be engaged.
- filter_iterator(WrappedIteratorT End) : BaseT(End) {}
-
public:
using BaseT::operator++;
- filter_iterator &operator++() {
+ filter_iterator_base &operator++() {
BaseT::operator++();
findNextValid();
return *this;
}
+};
+
+/// Specialization of filter_iterator_base for forward iteration only.
+template <typename WrappedIteratorT, typename PredicateT,
+ typename IterTag = std::forward_iterator_tag>
+class filter_iterator_impl
+ : public filter_iterator_base<WrappedIteratorT, PredicateT, IterTag> {
+ using BaseT = filter_iterator_base<WrappedIteratorT, PredicateT, IterTag>;
+
+public:
+ filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End,
+ PredicateT Pred)
+ : BaseT(Begin, End, Pred) {}
+};
+
+/// Specialization of filter_iterator_base for bidirectional iteration.
+template <typename WrappedIteratorT, typename PredicateT>
+class filter_iterator_impl<WrappedIteratorT, PredicateT,
+ std::bidirectional_iterator_tag>
+ : public filter_iterator_base<WrappedIteratorT, PredicateT,
+ std::bidirectional_iterator_tag> {
+ using BaseT = filter_iterator_base<WrappedIteratorT, PredicateT,
+ std::bidirectional_iterator_tag>;
+ void findPrevValid() {
+ while (!this->Pred(*this->I))
+ BaseT::operator--();
+ }
+
+public:
+ using BaseT::operator--;
+
+ filter_iterator_impl(WrappedIteratorT Begin, WrappedIteratorT End,
+ PredicateT Pred)
+ : BaseT(Begin, End, Pred) {}
+
+ filter_iterator_impl &operator--() {
+ BaseT::operator--();
+ findPrevValid();
+ return *this;
+ }
+};
+
+namespace detail {
- template <typename RT, typename PT>
- friend iterator_range<filter_iterator<detail::IterOfRange<RT>, PT>>
- make_filter_range(RT &&, PT);
+template <bool is_bidirectional> struct fwd_or_bidi_tag_impl {
+ using type = std::forward_iterator_tag;
};
+template <> struct fwd_or_bidi_tag_impl<true> {
+ using type = std::bidirectional_iterator_tag;
+};
+
+/// Helper which sets its type member to forward_iterator_tag if the category
+/// of \p IterT does not derive from bidirectional_iterator_tag, and to
+/// bidirectional_iterator_tag otherwise.
+template <typename IterT> struct fwd_or_bidi_tag {
+ using type = typename fwd_or_bidi_tag_impl<std::is_base_of<
+ std::bidirectional_iterator_tag,
+ typename std::iterator_traits<IterT>::iterator_category>::value>::type;
+};
+
+} // namespace detail
+
+/// Defines filter_iterator to a suitable specialization of
+/// filter_iterator_impl, based on the underlying iterator's category.
+template <typename WrappedIteratorT, typename PredicateT>
+using filter_iterator = filter_iterator_impl<
+ WrappedIteratorT, PredicateT,
+ typename detail::fwd_or_bidi_tag<WrappedIteratorT>::type>;
+
/// Convenience function that takes a range of elements and a predicate,
/// and return a new filter_iterator range.
///
@@ -332,10 +411,11 @@ iterator_range<filter_iterator<detail::IterOfRange<RangeT>, PredicateT>>
make_filter_range(RangeT &&Range, PredicateT Pred) {
using FilterIteratorT =
filter_iterator<detail::IterOfRange<RangeT>, PredicateT>;
- return make_range(FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
- std::end(std::forward<RangeT>(Range)),
- std::move(Pred)),
- FilterIteratorT(std::end(std::forward<RangeT>(Range))));
+ return make_range(
+ FilterIteratorT(std::begin(std::forward<RangeT>(Range)),
+ std::end(std::forward<RangeT>(Range)), Pred),
+ FilterIteratorT(std::end(std::forward<RangeT>(Range)),
+ std::end(std::forward<RangeT>(Range)), Pred));
}
// forward declarations required by zip_shortest/zip_first
@@ -644,7 +724,7 @@ detail::concat_range<ValueT, RangeTs...> concat(RangeTs &&... Ranges) {
// Extra additions to <utility>
//===----------------------------------------------------------------------===//
-/// \brief Function object to check whether the first component of a std::pair
+/// 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 {
@@ -652,7 +732,7 @@ struct less_first {
}
};
-/// \brief Function object to check whether the second component of a std::pair
+/// 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 {
@@ -662,14 +742,14 @@ struct less_second {
// A subset of N3658. More stuff can be added as-needed.
-/// \brief Represents a compile-time sequence of integers.
+/// Represents a compile-time sequence of integers.
template <class T, T... I> struct integer_sequence {
using value_type = T;
static constexpr size_t size() { return sizeof...(I); }
};
-/// \brief Alias for the common case of a sequence of size_ts.
+/// Alias for the common case of a sequence of size_ts.
template <size_t... I>
struct index_sequence : integer_sequence<std::size_t, I...> {};
@@ -678,7 +758,7 @@ struct build_index_impl : build_index_impl<N - 1, N - 1, I...> {};
template <std::size_t... I>
struct build_index_impl<0, I...> : index_sequence<I...> {};
-/// \brief Creates a compile-time integer sequence for a parameter pack.
+/// Creates a compile-time integer sequence for a parameter pack.
template <class... Ts>
struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
@@ -687,7 +767,7 @@ struct index_sequence_for : build_index_impl<sizeof...(Ts)> {};
template <int N> struct rank : rank<N - 1> {};
template <> struct rank<0> {};
-/// \brief traits class for checking whether type T is one of any of the given
+/// traits class for checking whether type T is one of any of the given
/// types in the variadic list.
template <typename T, typename... Ts> struct is_one_of {
static const bool value = false;
@@ -699,7 +779,7 @@ struct is_one_of<T, U, Ts...> {
std::is_same<T, U>::value || is_one_of<T, Ts...>::value;
};
-/// \brief traits class for checking whether type T is a base class for all
+/// traits class for checking whether type T is a base class for all
/// the given types in the variadic list.
template <typename T, typename... Ts> struct are_base_of {
static const bool value = true;
@@ -761,6 +841,10 @@ inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
// behavior with an empty sequence.
auto NElts = End - Start;
if (NElts <= 1) return;
+#ifdef EXPENSIVE_CHECKS
+ std::mt19937 Generator(std::random_device{}());
+ std::shuffle(Start, End, Generator);
+#endif
qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
}
@@ -774,10 +858,34 @@ inline void array_pod_sort(
// behavior with an empty sequence.
auto NElts = End - Start;
if (NElts <= 1) return;
+#ifdef EXPENSIVE_CHECKS
+ std::mt19937 Generator(std::random_device{}());
+ std::shuffle(Start, End, Generator);
+#endif
qsort(&*Start, NElts, sizeof(*Start),
reinterpret_cast<int (*)(const void *, const void *)>(Compare));
}
+// Provide wrappers to std::sort which shuffle the elements before sorting
+// to help uncover non-deterministic behavior (PR35135).
+template <typename IteratorTy>
+inline void sort(IteratorTy Start, IteratorTy End) {
+#ifdef EXPENSIVE_CHECKS
+ std::mt19937 Generator(std::random_device{}());
+ std::shuffle(Start, End, Generator);
+#endif
+ std::sort(Start, End);
+}
+
+template <typename IteratorTy, typename Compare>
+inline void sort(IteratorTy Start, IteratorTy End, Compare Comp) {
+#ifdef EXPENSIVE_CHECKS
+ std::mt19937 Generator(std::random_device{}());
+ std::shuffle(Start, End, Generator);
+#endif
+ std::sort(Start, End, Comp);
+}
+
//===----------------------------------------------------------------------===//
// Extra additions to <algorithm>
//===----------------------------------------------------------------------===//
@@ -861,6 +969,11 @@ OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P) {
return std::copy_if(adl_begin(Range), adl_end(Range), Out, P);
}
+template <typename R, typename OutputIt>
+OutputIt copy(R &&Range, OutputIt Out) {
+ return std::copy(adl_begin(Range), adl_end(Range), Out);
+}
+
/// Wrapper function around std::find to detect if an element exists
/// in a container.
template <typename R, typename E>
@@ -905,7 +1018,7 @@ 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
+/// Given a range of type R, iterate the entire range and return a
/// SmallVector with elements of the vector. This is useful, for example,
/// when you want to iterate a range and then sort the results.
template <unsigned Size, typename R>
@@ -926,13 +1039,25 @@ void erase_if(Container &C, UnaryPredicate P) {
C.erase(remove_if(C, P), C.end());
}
+/// Get the size of a range. This is a wrapper function around std::distance
+/// which is only enabled when the operation is O(1).
+template <typename R>
+auto size(R &&Range, typename std::enable_if<
+ std::is_same<typename std::iterator_traits<decltype(
+ Range.begin())>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ void>::type * = nullptr)
+ -> decltype(std::distance(Range.begin(), Range.end())) {
+ return std::distance(Range.begin(), Range.end());
+}
+
//===----------------------------------------------------------------------===//
// Extra additions to <memory>
//===----------------------------------------------------------------------===//
// Implement make_unique according to N3656.
-/// \brief Constructs a `new T()` with the given args and returns a
+/// Constructs a `new T()` with the given args and returns a
/// `unique_ptr<T>` which owns the object.
///
/// Example:
@@ -945,7 +1070,7 @@ make_unique(Args &&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
-/// \brief Constructs a `new T[n]` with the given args and returns a
+/// Constructs a `new T[n]` with the given args and returns a
/// `unique_ptr<T[]>` which owns the object.
///
/// \param n size of the new array.
diff --git a/include/llvm/ADT/ScopeExit.h b/include/llvm/ADT/ScopeExit.h
index 4e64352c77df..bd13755fa999 100644
--- a/include/llvm/ADT/ScopeExit.h
+++ b/include/llvm/ADT/ScopeExit.h
@@ -25,14 +25,26 @@ namespace detail {
template <typename Callable> class scope_exit {
Callable ExitFunction;
+ bool Engaged = true; // False once moved-from or release()d.
public:
template <typename Fp>
explicit scope_exit(Fp &&F) : ExitFunction(std::forward<Fp>(F)) {}
- scope_exit(scope_exit &&Rhs) : ExitFunction(std::move(Rhs.ExitFunction)) {}
+ scope_exit(scope_exit &&Rhs)
+ : ExitFunction(std::move(Rhs.ExitFunction)), Engaged(Rhs.Engaged) {
+ Rhs.release();
+ }
+ scope_exit(const scope_exit &) = delete;
+ scope_exit &operator=(scope_exit &&) = delete;
+ scope_exit &operator=(const scope_exit &) = delete;
- ~scope_exit() { ExitFunction(); }
+ void release() { Engaged = false; }
+
+ ~scope_exit() {
+ if (Engaged)
+ ExitFunction();
+ }
};
} // end namespace detail
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
index 04ed52fc543f..3d6781041320 100644
--- a/include/llvm/ADT/SetVector.h
+++ b/include/llvm/ADT/SetVector.h
@@ -31,7 +31,7 @@
namespace llvm {
-/// \brief A vector that has set insertion semantics.
+/// A vector that has set insertion semantics.
///
/// This adapter class provides a way to keep a set of things that also has the
/// property of a deterministic iteration order. The order of iteration is the
@@ -52,10 +52,10 @@ public:
using const_reverse_iterator = typename vector_type::const_reverse_iterator;
using size_type = typename vector_type::size_type;
- /// \brief Construct an empty SetVector
+ /// Construct an empty SetVector
SetVector() = default;
- /// \brief Initialize a SetVector with a range of elements
+ /// Initialize a SetVector with a range of elements
template<typename It>
SetVector(It Start, It End) {
insert(Start, End);
@@ -69,75 +69,75 @@ public:
return std::move(vector_);
}
- /// \brief Determine if the SetVector is empty or not.
+ /// Determine if the SetVector is empty or not.
bool empty() const {
return vector_.empty();
}
- /// \brief Determine the number of elements in the SetVector.
+ /// Determine the number of elements in the SetVector.
size_type size() const {
return vector_.size();
}
- /// \brief Get an iterator to the beginning of the SetVector.
+ /// Get an iterator to the beginning of the SetVector.
iterator begin() {
return vector_.begin();
}
- /// \brief Get a const_iterator to the beginning of the SetVector.
+ /// Get a const_iterator to the beginning of the SetVector.
const_iterator begin() const {
return vector_.begin();
}
- /// \brief Get an iterator to the end of the SetVector.
+ /// Get an iterator to the end of the SetVector.
iterator end() {
return vector_.end();
}
- /// \brief Get a const_iterator to the end of the SetVector.
+ /// Get a const_iterator to the end of the SetVector.
const_iterator end() const {
return vector_.end();
}
- /// \brief Get an reverse_iterator to the end of the SetVector.
+ /// Get an reverse_iterator to the end of the SetVector.
reverse_iterator rbegin() {
return vector_.rbegin();
}
- /// \brief Get a const_reverse_iterator to the end of the SetVector.
+ /// Get a const_reverse_iterator to the end of the SetVector.
const_reverse_iterator rbegin() const {
return vector_.rbegin();
}
- /// \brief Get a reverse_iterator to the beginning of the SetVector.
+ /// Get a reverse_iterator to the beginning of the SetVector.
reverse_iterator rend() {
return vector_.rend();
}
- /// \brief Get a const_reverse_iterator to the beginning of the SetVector.
+ /// Get a const_reverse_iterator to the beginning of the SetVector.
const_reverse_iterator rend() const {
return vector_.rend();
}
- /// \brief Return the first element of the SetVector.
+ /// Return the first element of the SetVector.
const T &front() const {
assert(!empty() && "Cannot call front() on empty SetVector!");
return vector_.front();
}
- /// \brief Return the last element of the SetVector.
+ /// Return the last element of the SetVector.
const T &back() const {
assert(!empty() && "Cannot call back() on empty SetVector!");
return vector_.back();
}
- /// \brief Index into the SetVector.
+ /// Index into the SetVector.
const_reference operator[](size_type n) const {
assert(n < vector_.size() && "SetVector access out of range!");
return vector_[n];
}
- /// \brief Insert a new element into the SetVector.
+ /// Insert a new element into the SetVector.
/// \returns true if the element was inserted into the SetVector.
bool insert(const value_type &X) {
bool result = set_.insert(X).second;
@@ -146,7 +146,7 @@ public:
return result;
}
- /// \brief Insert a range of elements into the SetVector.
+ /// Insert a range of elements into the SetVector.
template<typename It>
void insert(It Start, It End) {
for (; Start != End; ++Start)
@@ -154,7 +154,7 @@ public:
vector_.push_back(*Start);
}
- /// \brief Remove an item from the set vector.
+ /// Remove an item from the set vector.
bool remove(const value_type& X) {
if (set_.erase(X)) {
typename vector_type::iterator I = find(vector_, X);
@@ -183,7 +183,7 @@ public:
return vector_.erase(NI);
}
- /// \brief Remove items from the set vector based on a predicate function.
+ /// Remove items from the set vector based on a predicate function.
///
/// This is intended to be equivalent to the following code, if we could
/// write it:
@@ -206,19 +206,19 @@ public:
return true;
}
- /// \brief Count the number of elements of a given key in the SetVector.
+ /// Count the number of elements of a given key in the SetVector.
/// \returns 0 if the element is not in the SetVector, 1 if it is.
size_type count(const key_type &key) const {
return set_.count(key);
}
- /// \brief Completely clear the SetVector
+ /// Completely clear the SetVector
void clear() {
set_.clear();
vector_.clear();
}
- /// \brief Remove the last element of the SetVector.
+ /// Remove the last element of the SetVector.
void pop_back() {
assert(!empty() && "Cannot remove an element from an empty SetVector!");
set_.erase(back());
@@ -239,7 +239,7 @@ public:
return vector_ != that.vector_;
}
- /// \brief Compute This := This u S, return whether 'This' changed.
+ /// Compute This := This u S, return whether 'This' changed.
/// TODO: We should be able to use set_union from SetOperations.h, but
/// SetVector interface is inconsistent with DenseSet.
template <class STy>
@@ -254,7 +254,7 @@ public:
return Changed;
}
- /// \brief Compute This := This - B
+ /// Compute This := This - B
/// TODO: We should be able to use set_subtract from SetOperations.h, but
/// SetVector interface is inconsistent with DenseSet.
template <class STy>
@@ -265,7 +265,7 @@ public:
}
private:
- /// \brief A wrapper predicate designed for use with std::remove_if.
+ /// A wrapper predicate designed for use with std::remove_if.
///
/// This predicate wraps a predicate suitable for use with std::remove_if to
/// call set_.erase(x) on each element which is slated for removal.
@@ -292,7 +292,7 @@ private:
vector_type vector_; ///< The vector.
};
-/// \brief A SetVector that performs no allocations if smaller than
+/// A SetVector that performs no allocations if smaller than
/// a certain size.
template <typename T, unsigned N>
class SmallSetVector
@@ -300,7 +300,7 @@ class SmallSetVector
public:
SmallSetVector() = default;
- /// \brief Initialize a SmallSetVector with a range of elements
+ /// Initialize a SmallSetVector with a range of elements
template<typename It>
SmallSetVector(It Start, It End) {
this->insert(Start, End);
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
index 78ea613af693..db08e40257ba 100644
--- a/include/llvm/ADT/SmallPtrSet.h
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -335,7 +335,7 @@ struct RoundUpToPowerOfTwo {
enum { Val = RoundUpToPowerOfTwoH<N, (N&(N-1)) == 0>::Val };
};
-/// \brief A templated base class for \c SmallPtrSet which provides the
+/// A templated base class for \c SmallPtrSet which provides the
/// typesafe interface that is common across all small sizes.
///
/// This is particularly useful for passing around between interface boundaries
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
index d52d0f07f9a6..5d84627714bc 100644
--- a/include/llvm/ADT/SmallSet.h
+++ b/include/llvm/ADT/SmallSet.h
@@ -17,21 +17,120 @@
#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/type_traits.h"
#include <cstddef>
#include <functional>
#include <set>
+#include <type_traits>
#include <utility>
namespace llvm {
+/// SmallSetIterator - This class implements a const_iterator for SmallSet by
+/// delegating to the underlying SmallVector or Set iterators.
+template <typename T, unsigned N, typename C>
+class SmallSetIterator
+ : public iterator_facade_base<SmallSetIterator<T, N, C>,
+ std::forward_iterator_tag, T> {
+private:
+ using SetIterTy = typename std::set<T, C>::const_iterator;
+ using VecIterTy = typename SmallVector<T, N>::const_iterator;
+ using SelfTy = SmallSetIterator<T, N, C>;
+
+ /// Iterators to the parts of the SmallSet containing the data. They are set
+ /// depending on isSmall.
+ union {
+ SetIterTy SetIter;
+ VecIterTy VecIter;
+ };
+
+ bool isSmall;
+
+public:
+ SmallSetIterator(SetIterTy SetIter) : SetIter(SetIter), isSmall(false) {}
+
+ SmallSetIterator(VecIterTy VecIter) : VecIter(VecIter), isSmall(true) {}
+
+ // Spell out destructor, copy/move constructor and assignment operators for
+ // MSVC STL, where set<T>::const_iterator is not trivially copy constructible.
+ ~SmallSetIterator() {
+ if (isSmall)
+ VecIter.~VecIterTy();
+ else
+ SetIter.~SetIterTy();
+ }
+
+ SmallSetIterator(const SmallSetIterator &Other) : isSmall(Other.isSmall) {
+ if (isSmall)
+ VecIter = Other.VecIter;
+ else
+ // Use placement new, to make sure SetIter is properly constructed, even
+ // if it is not trivially copy-able (e.g. in MSVC).
+ new (&SetIter) SetIterTy(Other.SetIter);
+ }
+
+ SmallSetIterator(SmallSetIterator &&Other) : isSmall(Other.isSmall) {
+ if (isSmall)
+ VecIter = std::move(Other.VecIter);
+ else
+ // Use placement new, to make sure SetIter is properly constructed, even
+ // if it is not trivially copy-able (e.g. in MSVC).
+ new (&SetIter) SetIterTy(std::move(Other.SetIter));
+ }
+
+ SmallSetIterator& operator=(const SmallSetIterator& Other) {
+ // Call destructor for SetIter, so it gets properly destroyed if it is
+ // not trivially destructible in case we are setting VecIter.
+ if (!isSmall)
+ SetIter.~SetIterTy();
+
+ isSmall = Other.isSmall;
+ if (isSmall)
+ VecIter = Other.VecIter;
+ else
+ new (&SetIter) SetIterTy(Other.SetIter);
+ return *this;
+ }
+
+ SmallSetIterator& operator=(SmallSetIterator&& Other) {
+ // Call destructor for SetIter, so it gets properly destroyed if it is
+ // not trivially destructible in case we are setting VecIter.
+ if (!isSmall)
+ SetIter.~SetIterTy();
+
+ isSmall = Other.isSmall;
+ if (isSmall)
+ VecIter = std::move(Other.VecIter);
+ else
+ new (&SetIter) SetIterTy(std::move(Other.SetIter));
+ return *this;
+ }
+
+ bool operator==(const SmallSetIterator &RHS) const {
+ if (isSmall != RHS.isSmall)
+ return false;
+ if (isSmall)
+ return VecIter == RHS.VecIter;
+ return SetIter == RHS.SetIter;
+ }
+
+ SmallSetIterator &operator++() { // Preincrement
+ if (isSmall)
+ VecIter++;
+ else
+ SetIter++;
+ return *this;
+ }
+
+ const T &operator*() const { return isSmall ? *VecIter : *SetIter; }
+};
+
/// SmallSet - This maintains a set of unique values, optimizing for the case
/// when the set is small (less than N). In this case, the set can be
/// maintained with no mallocs. If the set gets large, we expand to using an
/// std::set to maintain reasonable lookup times.
-///
-/// Note that this set does not provide a way to iterate over members in the
-/// set.
template <typename T, unsigned N, typename C = std::less<T>>
class SmallSet {
/// Use a SmallVector to hold the elements here (even though it will never
@@ -50,6 +149,7 @@ class SmallSet {
public:
using size_type = size_t;
+ using const_iterator = SmallSetIterator<T, N, C>;
SmallSet() = default;
@@ -121,6 +221,18 @@ public:
Set.clear();
}
+ const_iterator begin() const {
+ if (isSmall())
+ return {Vector.begin()};
+ return {Set.begin()};
+ }
+
+ const_iterator end() const {
+ if (isSmall())
+ return {Vector.end()};
+ return {Set.end()};
+ }
+
private:
bool isSmall() const { return Set.empty(); }
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index a9ac98d1ad4c..acb4426b4f45 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -18,6 +18,7 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemAlloc.h"
#include "llvm/Support/type_traits.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
@@ -37,28 +38,42 @@ namespace llvm {
/// This is all the non-templated stuff common to all SmallVectors.
class SmallVectorBase {
protected:
- void *BeginX, *EndX, *CapacityX;
+ void *BeginX;
+ unsigned Size = 0, Capacity;
-protected:
- SmallVectorBase(void *FirstEl, size_t Size)
- : BeginX(FirstEl), EndX(FirstEl), CapacityX((char*)FirstEl+Size) {}
+ SmallVectorBase() = delete;
+ SmallVectorBase(void *FirstEl, size_t Capacity)
+ : BeginX(FirstEl), Capacity(Capacity) {}
/// This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
- void grow_pod(void *FirstEl, size_t MinSizeInBytes, size_t TSize);
+ void grow_pod(void *FirstEl, size_t MinCapacity, size_t TSize);
public:
- /// This returns size()*sizeof(T).
- size_t size_in_bytes() const {
- return size_t((char*)EndX - (char*)BeginX);
- }
+ size_t size() const { return Size; }
+ size_t capacity() const { return Capacity; }
+
+ LLVM_NODISCARD bool empty() const { return !Size; }
- /// capacity_in_bytes - This returns capacity()*sizeof(T).
- size_t capacity_in_bytes() const {
- return size_t((char*)CapacityX - (char*)BeginX);
+ /// Set the array size to \p N, which the current array must have enough
+ /// capacity for.
+ ///
+ /// This does not construct or destroy any elements in the vector.
+ ///
+ /// Clients can use this in conjunction with capacity() to write past the end
+ /// of the buffer when they know that more elements are available, and only
+ /// update the size later. This avoids the cost of value initializing elements
+ /// which will only be overwritten.
+ void set_size(size_t Size) {
+ assert(Size <= capacity());
+ this->Size = Size;
}
+};
- LLVM_NODISCARD bool empty() const { return BeginX == EndX; }
+/// Figure out the offset of the first element.
+template <class T, typename = void> struct SmallVectorAlignmentAndSize {
+ AlignedCharArrayUnion<SmallVectorBase> Base;
+ AlignedCharArrayUnion<T> FirstEl;
};
/// This is the part of SmallVectorTemplateBase which does not depend on whether
@@ -66,36 +81,34 @@ public:
/// to avoid unnecessarily requiring T to be complete.
template <typename T, typename = void>
class SmallVectorTemplateCommon : public SmallVectorBase {
-private:
- template <typename, unsigned> friend struct SmallVectorStorage;
-
- // Allocate raw space for N elements of type T. If T has a ctor or dtor, we
- // don't want it to be automatically run, so we need to represent the space as
- // something else. Use an array of char of sufficient alignment.
- using U = AlignedCharArrayUnion<T>;
- U FirstEl;
+ /// Find the address of the first element. For this pointer math to be valid
+ /// with small-size of 0 for T with lots of alignment, it's important that
+ /// SmallVectorStorage is properly-aligned even for small-size of 0.
+ void *getFirstEl() const {
+ return const_cast<void *>(reinterpret_cast<const void *>(
+ reinterpret_cast<const char *>(this) +
+ offsetof(SmallVectorAlignmentAndSize<T>, FirstEl)));
+ }
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
protected:
- SmallVectorTemplateCommon(size_t Size) : SmallVectorBase(&FirstEl, Size) {}
+ SmallVectorTemplateCommon(size_t Size)
+ : SmallVectorBase(getFirstEl(), Size) {}
- void grow_pod(size_t MinSizeInBytes, size_t TSize) {
- SmallVectorBase::grow_pod(&FirstEl, MinSizeInBytes, TSize);
+ void grow_pod(size_t MinCapacity, size_t TSize) {
+ SmallVectorBase::grow_pod(getFirstEl(), MinCapacity, TSize);
}
/// Return true if this is a smallvector which has not had dynamic
/// memory allocated for it.
- bool isSmall() const {
- return BeginX == static_cast<const void*>(&FirstEl);
- }
+ bool isSmall() const { return BeginX == getFirstEl(); }
/// Put this vector in a state of being small.
void resetToSmall() {
- BeginX = EndX = CapacityX = &FirstEl;
+ BeginX = getFirstEl();
+ Size = Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
}
- void setEnd(T *P) { this->EndX = P; }
-
public:
using size_type = size_t;
using difference_type = ptrdiff_t;
@@ -117,27 +130,20 @@ public:
LLVM_ATTRIBUTE_ALWAYS_INLINE
const_iterator begin() const { return (const_iterator)this->BeginX; }
LLVM_ATTRIBUTE_ALWAYS_INLINE
- iterator end() { return (iterator)this->EndX; }
+ iterator end() { return begin() + size(); }
LLVM_ATTRIBUTE_ALWAYS_INLINE
- const_iterator end() const { return (const_iterator)this->EndX; }
-
-protected:
- iterator capacity_ptr() { return (iterator)this->CapacityX; }
- const_iterator capacity_ptr() const { return (const_iterator)this->CapacityX;}
+ const_iterator end() const { return begin() + size(); }
-public:
// reverse iterator creation methods.
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
- LLVM_ATTRIBUTE_ALWAYS_INLINE
- size_type size() const { return end()-begin(); }
+ size_type size_in_bytes() const { return size() * sizeof(T); }
size_type max_size() const { return size_type(-1) / sizeof(T); }
- /// Return the total number of elements in the currently allocated buffer.
- size_t capacity() const { return capacity_ptr() - begin(); }
+ size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
/// Return a pointer to the vector's buffer, even if empty().
pointer data() { return pointer(begin()); }
@@ -210,21 +216,21 @@ protected:
public:
void push_back(const T &Elt) {
- if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+ if (LLVM_UNLIKELY(this->size() >= this->capacity()))
this->grow();
::new ((void*) this->end()) T(Elt);
- this->setEnd(this->end()+1);
+ this->set_size(this->size() + 1);
}
void push_back(T &&Elt) {
- if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+ if (LLVM_UNLIKELY(this->size() >= this->capacity()))
this->grow();
::new ((void*) this->end()) T(::std::move(Elt));
- this->setEnd(this->end()+1);
+ this->set_size(this->size() + 1);
}
void pop_back() {
- this->setEnd(this->end()-1);
+ this->set_size(this->size() - 1);
this->end()->~T();
}
};
@@ -232,15 +238,13 @@ public:
// Define this out-of-line to dissuade the C++ compiler from inlining it.
template <typename T, bool isPodLike>
void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
- size_t CurCapacity = this->capacity();
- size_t CurSize = this->size();
+ if (MinSize > UINT32_MAX)
+ report_bad_alloc_error("SmallVector capacity overflow during allocation");
+
// Always grow, even from zero.
- size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
- 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.");
+ size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2));
+ NewCapacity = std::min(std::max(NewCapacity, MinSize), size_t(UINT32_MAX));
+ T *NewElts = static_cast<T*>(llvm::safe_malloc(NewCapacity*sizeof(T)));
// Move the elements over.
this->uninitialized_move(this->begin(), this->end(), NewElts);
@@ -252,9 +256,8 @@ void SmallVectorTemplateBase<T, isPodLike>::grow(size_t MinSize) {
if (!this->isSmall())
free(this->begin());
- this->setEnd(NewElts+CurSize);
this->BeginX = NewElts;
- this->CapacityX = this->begin()+NewCapacity;
+ this->Capacity = NewCapacity;
}
@@ -301,21 +304,17 @@ protected:
/// Double the size of the allocated memory, guaranteeing space for at
/// least one more element or MinSize if specified.
- void grow(size_t MinSize = 0) {
- this->grow_pod(MinSize*sizeof(T), sizeof(T));
- }
+ void grow(size_t MinSize = 0) { this->grow_pod(MinSize, sizeof(T)); }
public:
void push_back(const T &Elt) {
- if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+ if (LLVM_UNLIKELY(this->size() >= this->capacity()))
this->grow();
memcpy(this->end(), &Elt, sizeof(T));
- this->setEnd(this->end()+1);
+ this->set_size(this->size() + 1);
}
- void pop_back() {
- this->setEnd(this->end()-1);
- }
+ void pop_back() { this->set_size(this->size() - 1); }
};
/// This class consists of common code factored out of the SmallVector class to
@@ -332,16 +331,13 @@ public:
protected:
// Default ctor - Initialize to empty.
explicit SmallVectorImpl(unsigned N)
- : SmallVectorTemplateBase<T, isPodLike<T>::value>(N*sizeof(T)) {
- }
+ : SmallVectorTemplateBase<T, isPodLike<T>::value>(N) {}
public:
SmallVectorImpl(const SmallVectorImpl &) = delete;
~SmallVectorImpl() {
- // Destroy the constructed elements in the vector.
- this->destroy_range(this->begin(), this->end());
-
+ // Subclass has already destructed this vector's elements.
// If this wasn't grown from the inline copy, deallocate the old space.
if (!this->isSmall())
free(this->begin());
@@ -349,31 +345,31 @@ public:
void clear() {
this->destroy_range(this->begin(), this->end());
- this->EndX = this->BeginX;
+ this->Size = 0;
}
void resize(size_type N) {
if (N < this->size()) {
this->destroy_range(this->begin()+N, this->end());
- this->setEnd(this->begin()+N);
+ this->set_size(N);
} else if (N > this->size()) {
if (this->capacity() < N)
this->grow(N);
for (auto I = this->end(), E = this->begin() + N; I != E; ++I)
new (&*I) T();
- this->setEnd(this->begin()+N);
+ this->set_size(N);
}
}
void resize(size_type N, const T &NV) {
if (N < this->size()) {
this->destroy_range(this->begin()+N, this->end());
- this->setEnd(this->begin()+N);
+ this->set_size(N);
} else if (N > this->size()) {
if (this->capacity() < N)
this->grow(N);
std::uninitialized_fill(this->end(), this->begin()+N, NV);
- this->setEnd(this->begin()+N);
+ this->set_size(N);
}
}
@@ -398,23 +394,23 @@ public:
void append(in_iter in_start, in_iter in_end) {
size_type NumInputs = std::distance(in_start, in_end);
// Grow allocated space if needed.
- if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+ if (NumInputs > this->capacity() - this->size())
this->grow(this->size()+NumInputs);
// Copy the new elements over.
this->uninitialized_copy(in_start, in_end, this->end());
- this->setEnd(this->end() + NumInputs);
+ this->set_size(this->size() + NumInputs);
}
/// Add the specified range to the end of the SmallVector.
void append(size_type NumInputs, const T &Elt) {
// Grow allocated space if needed.
- if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+ if (NumInputs > this->capacity() - this->size())
this->grow(this->size()+NumInputs);
// Copy the new elements over.
std::uninitialized_fill_n(this->end(), NumInputs, Elt);
- this->setEnd(this->end() + NumInputs);
+ this->set_size(this->size() + NumInputs);
}
void append(std::initializer_list<T> IL) {
@@ -428,7 +424,7 @@ public:
clear();
if (this->capacity() < NumElts)
this->grow(NumElts);
- this->setEnd(this->begin()+NumElts);
+ this->set_size(NumElts);
std::uninitialized_fill(this->begin(), this->end(), Elt);
}
@@ -475,7 +471,7 @@ public:
iterator I = std::move(E, this->end(), S);
// Drop the last elts.
this->destroy_range(I, this->end());
- this->setEnd(I);
+ this->set_size(I - this->begin());
return(N);
}
@@ -488,7 +484,7 @@ public:
assert(I >= this->begin() && "Insertion iterator is out of bounds.");
assert(I <= this->end() && "Inserting past the end of the vector.");
- if (this->EndX >= this->CapacityX) {
+ if (this->size() >= this->capacity()) {
size_t EltNo = I-this->begin();
this->grow();
I = this->begin()+EltNo;
@@ -497,12 +493,12 @@ public:
::new ((void*) this->end()) T(::std::move(this->back()));
// Push everything else over.
std::move_backward(I, this->end()-1, this->end());
- this->setEnd(this->end()+1);
+ this->set_size(this->size() + 1);
// If we just moved the element we're inserting, be sure to update
// the reference.
T *EltPtr = &Elt;
- if (I <= EltPtr && EltPtr < this->EndX)
+ if (I <= EltPtr && EltPtr < this->end())
++EltPtr;
*I = ::std::move(*EltPtr);
@@ -518,7 +514,7 @@ public:
assert(I >= this->begin() && "Insertion iterator is out of bounds.");
assert(I <= this->end() && "Inserting past the end of the vector.");
- if (this->EndX >= this->CapacityX) {
+ if (this->size() >= this->capacity()) {
size_t EltNo = I-this->begin();
this->grow();
I = this->begin()+EltNo;
@@ -526,12 +522,12 @@ public:
::new ((void*) this->end()) T(std::move(this->back()));
// Push everything else over.
std::move_backward(I, this->end()-1, this->end());
- this->setEnd(this->end()+1);
+ this->set_size(this->size() + 1);
// If we just moved the element we're inserting, be sure to update
// the reference.
const T *EltPtr = &Elt;
- if (I <= EltPtr && EltPtr < this->EndX)
+ if (I <= EltPtr && EltPtr < this->end())
++EltPtr;
*I = *EltPtr;
@@ -577,7 +573,7 @@ public:
// Move over the elements that we're about to overwrite.
T *OldEnd = this->end();
- this->setEnd(this->end() + NumToInsert);
+ this->set_size(this->size() + NumToInsert);
size_t NumOverwritten = OldEnd-I;
this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
@@ -634,7 +630,7 @@ public:
// Move over the elements that we're about to overwrite.
T *OldEnd = this->end();
- this->setEnd(this->end() + NumToInsert);
+ this->set_size(this->size() + NumToInsert);
size_t NumOverwritten = OldEnd-I;
this->uninitialized_move(I, OldEnd, this->end()-NumOverwritten);
@@ -654,10 +650,10 @@ public:
}
template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) {
- if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
+ if (LLVM_UNLIKELY(this->size() >= this->capacity()))
this->grow();
::new ((void *)this->end()) T(std::forward<ArgTypes>(Args)...);
- this->setEnd(this->end() + 1);
+ this->set_size(this->size() + 1);
}
SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
@@ -676,20 +672,6 @@ public:
return std::lexicographical_compare(this->begin(), this->end(),
RHS.begin(), RHS.end());
}
-
- /// Set the array size to \p N, which the current array must have enough
- /// capacity for.
- ///
- /// This does not construct or destroy any elements in the vector.
- ///
- /// Clients can use this in conjunction with capacity() to write past the end
- /// of the buffer when they know that more elements are available, and only
- /// update the size later. This avoids the cost of value initializing elements
- /// which will only be overwritten.
- void set_size(size_type N) {
- assert(N <= this->capacity());
- this->setEnd(this->begin() + N);
- }
};
template <typename T>
@@ -699,8 +681,8 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
// We can only avoid copying elements if neither vector is small.
if (!this->isSmall() && !RHS.isSmall()) {
std::swap(this->BeginX, RHS.BeginX);
- std::swap(this->EndX, RHS.EndX);
- std::swap(this->CapacityX, RHS.CapacityX);
+ std::swap(this->Size, RHS.Size);
+ std::swap(this->Capacity, RHS.Capacity);
return;
}
if (RHS.size() > this->capacity())
@@ -718,15 +700,15 @@ void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
if (this->size() > RHS.size()) {
size_t EltDiff = this->size() - RHS.size();
this->uninitialized_copy(this->begin()+NumShared, this->end(), RHS.end());
- RHS.setEnd(RHS.end()+EltDiff);
+ RHS.set_size(RHS.size() + EltDiff);
this->destroy_range(this->begin()+NumShared, this->end());
- this->setEnd(this->begin()+NumShared);
+ this->set_size(NumShared);
} else if (RHS.size() > this->size()) {
size_t EltDiff = RHS.size() - this->size();
this->uninitialized_copy(RHS.begin()+NumShared, RHS.end(), this->end());
- this->setEnd(this->end() + EltDiff);
+ this->set_size(this->size() + EltDiff);
this->destroy_range(RHS.begin()+NumShared, RHS.end());
- RHS.setEnd(RHS.begin()+NumShared);
+ RHS.set_size(NumShared);
}
}
@@ -752,7 +734,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
this->destroy_range(NewEnd, this->end());
// Trim.
- this->setEnd(NewEnd);
+ this->set_size(RHSSize);
return *this;
}
@@ -762,7 +744,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
if (this->capacity() < RHSSize) {
// Destroy current elements.
this->destroy_range(this->begin(), this->end());
- this->setEnd(this->begin());
+ this->set_size(0);
CurSize = 0;
this->grow(RHSSize);
} else if (CurSize) {
@@ -775,7 +757,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::
this->begin()+CurSize);
// Set end.
- this->setEnd(this->begin()+RHSSize);
+ this->set_size(RHSSize);
return *this;
}
@@ -789,8 +771,8 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
this->destroy_range(this->begin(), this->end());
if (!this->isSmall()) free(this->begin());
this->BeginX = RHS.BeginX;
- this->EndX = RHS.EndX;
- this->CapacityX = RHS.CapacityX;
+ this->Size = RHS.Size;
+ this->Capacity = RHS.Capacity;
RHS.resetToSmall();
return *this;
}
@@ -807,7 +789,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
// Destroy excess elements and trim the bounds.
this->destroy_range(NewEnd, this->end());
- this->setEnd(NewEnd);
+ this->set_size(RHSSize);
// Clear the RHS.
RHS.clear();
@@ -822,7 +804,7 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
if (this->capacity() < RHSSize) {
// Destroy current elements.
this->destroy_range(this->begin(), this->end());
- this->setEnd(this->begin());
+ this->set_size(0);
CurSize = 0;
this->grow(RHSSize);
} else if (CurSize) {
@@ -835,22 +817,23 @@ SmallVectorImpl<T> &SmallVectorImpl<T>::operator=(SmallVectorImpl<T> &&RHS) {
this->begin()+CurSize);
// Set end.
- this->setEnd(this->begin()+RHSSize);
+ this->set_size(RHSSize);
RHS.clear();
return *this;
}
-/// Storage for the SmallVector elements which aren't contained in
-/// SmallVectorTemplateCommon. There are 'N-1' elements here. The remaining '1'
-/// element is in the base class. This is specialized for the N=1 and N=0 cases
+/// Storage for the SmallVector elements. This is specialized for the N=0 case
/// to avoid allocating unnecessary storage.
template <typename T, unsigned N>
struct SmallVectorStorage {
- typename SmallVectorTemplateCommon<T>::U InlineElts[N - 1];
+ AlignedCharArrayUnion<T> InlineElts[N];
};
-template <typename T> struct SmallVectorStorage<T, 1> {};
-template <typename T> struct SmallVectorStorage<T, 0> {};
+
+/// We need the storage to be properly aligned even for small-size of 0 so that
+/// the pointer math in \a SmallVectorTemplateCommon::getFirstEl() is
+/// well-defined.
+template <typename T> struct alignas(alignof(T)) SmallVectorStorage<T, 0> {};
/// This is a 'vector' (really, a variable-sized array), optimized
/// for the case when the array is small. It contains some number of elements
@@ -861,13 +844,15 @@ template <typename T> struct SmallVectorStorage<T, 0> {};
/// Note that this does not attempt to be exception safe.
///
template <typename T, unsigned N>
-class SmallVector : public SmallVectorImpl<T> {
- /// Inline space for elements which aren't stored in the base class.
- SmallVectorStorage<T, N> Storage;
-
+class SmallVector : public SmallVectorImpl<T>, SmallVectorStorage<T, N> {
public:
SmallVector() : SmallVectorImpl<T>(N) {}
+ ~SmallVector() {
+ // Destroy the constructed elements in the vector.
+ this->destroy_range(this->begin(), this->end());
+ }
+
explicit SmallVector(size_t Size, const T &Value = T())
: SmallVectorImpl<T>(N) {
this->assign(Size, Value);
diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h
index c91e0d70f65a..3c8637621510 100644
--- a/include/llvm/ADT/SparseMultiSet.h
+++ b/include/llvm/ADT/SparseMultiSet.h
@@ -211,7 +211,7 @@ public:
// The Sparse array doesn't actually need to be initialized, so malloc
// would be enough here, but that will cause tools like valgrind to
// complain about branching on uninitialized data.
- Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
+ Sparse = static_cast<SparseT*>(safe_calloc(U, sizeof(SparseT)));
Universe = U;
}
diff --git a/include/llvm/ADT/SparseSet.h b/include/llvm/ADT/SparseSet.h
index 25ade8831922..74cc6dab8c74 100644
--- a/include/llvm/ADT/SparseSet.h
+++ b/include/llvm/ADT/SparseSet.h
@@ -22,6 +22,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Allocator.h"
#include <cassert>
#include <cstdint>
#include <cstdlib>
@@ -163,7 +164,7 @@ public:
// The Sparse array doesn't actually need to be initialized, so malloc
// would be enough here, but that will cause tools like valgrind to
// complain about branching on uninitialized data.
- Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
+ Sparse = static_cast<SparseT*>(safe_calloc(U, sizeof(SparseT)));
Universe = U;
}
diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h
index d5ebba409c3d..90c2eefceb6c 100644
--- a/include/llvm/ADT/Statistic.h
+++ b/include/llvm/ADT/Statistic.h
@@ -26,15 +26,24 @@
#ifndef LLVM_ADT_STATISTIC_H
#define LLVM_ADT_STATISTIC_H
-#include "llvm/Support/Atomic.h"
+#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
#include <atomic>
#include <memory>
+#include <vector>
+
+// Determine whether statistics should be enabled. We must do it here rather
+// than in CMake because multi-config generators cannot determine this at
+// configure time.
+#if !defined(NDEBUG) || LLVM_FORCE_ENABLE_STATS
+#define LLVM_ENABLE_STATS 1
+#endif
namespace llvm {
class raw_ostream;
class raw_fd_ostream;
+class StringRef;
class Statistic {
public:
@@ -42,7 +51,7 @@ public:
const char *Name;
const char *Desc;
std::atomic<unsigned> Value;
- bool Initialized;
+ std::atomic<bool> Initialized;
unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
const char *getDebugType() const { return DebugType; }
@@ -61,7 +70,7 @@ public:
// Allow use of this class as the value itself.
operator unsigned() const { return getValue(); }
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
+#if LLVM_ENABLE_STATS
const Statistic &operator=(unsigned Val) {
Value.store(Val, std::memory_order_relaxed);
return init();
@@ -143,14 +152,12 @@ public:
void updateMax(unsigned V) {}
-#endif // !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
+#endif // LLVM_ENABLE_STATS
protected:
Statistic &init() {
- bool tmp = Initialized;
- sys::MemoryFence();
- if (!tmp) RegisterStatistic();
- TsanHappensAfter(this);
+ if (!Initialized.load(std::memory_order_acquire))
+ RegisterStatistic();
return *this;
}
@@ -160,21 +167,21 @@ protected:
// STATISTIC - A macro to make definition of statistics really simple. This
// automatically passes the DEBUG_TYPE of the file into the statistic.
#define STATISTIC(VARNAME, DESC) \
- static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, false}
+ static llvm::Statistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC, {0}, {false}}
-/// \brief Enable the collection and printing of statistics.
+/// Enable the collection and printing of statistics.
void EnableStatistics(bool PrintOnExit = true);
-/// \brief Check if statistics are enabled.
+/// Check if statistics are enabled.
bool AreStatisticsEnabled();
-/// \brief Return a file stream to print our output on.
+/// Return a file stream to print our output on.
std::unique_ptr<raw_fd_ostream> CreateInfoOutputFile();
-/// \brief Print statistics to the file returned by CreateInfoOutputFile().
+/// Print statistics to the file returned by CreateInfoOutputFile().
void PrintStatistics();
-/// \brief Print statistics to the given output stream.
+/// Print statistics to the given output stream.
void PrintStatistics(raw_ostream &OS);
/// Print statistics in JSON format. This does include all global timers (\see
@@ -183,6 +190,30 @@ void PrintStatistics(raw_ostream &OS);
/// PrintStatisticsJSON().
void PrintStatisticsJSON(raw_ostream &OS);
+/// Get the statistics. This can be used to look up the value of
+/// statistics without needing to parse JSON.
+///
+/// This function does not prevent statistics being updated by other threads
+/// during it's execution. It will return the value at the point that it is
+/// read. However, it will prevent new statistics from registering until it
+/// completes.
+const std::vector<std::pair<StringRef, unsigned>> GetStatistics();
+
+/// Reset the statistics. This can be used to zero and de-register the
+/// statistics in order to measure a compilation.
+///
+/// When this function begins to call destructors prior to returning, all
+/// statistics will be zero and unregistered. However, that might not remain the
+/// case by the time this function finishes returning. Whether update from other
+/// threads are lost or merely deferred until during the function return is
+/// timing sensitive.
+///
+/// Callers who intend to use this to measure statistics for a single
+/// compilation should ensure that no compilations are in progress at the point
+/// this function is called and that only one compilation executes until calling
+/// GetStatistics().
+void ResetStatistics();
+
} // end namespace llvm
#endif // LLVM_ADT_STATISTIC_H
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index 60652f8c55c5..71b0e7527cb7 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -39,6 +39,16 @@ inline char hexdigit(unsigned X, bool LowerCase = false) {
return X < 10 ? '0' + X : HexChar + X - 10;
}
+/// Given an array of c-style strings terminated by a null pointer, construct
+/// a vector of StringRefs representing the same strings without the terminating
+/// null string.
+inline std::vector<StringRef> toStringRefArray(const char *const *Strings) {
+ std::vector<StringRef> Result;
+ while (*Strings)
+ Result.push_back(*Strings++);
+ return Result;
+}
+
/// Construct a string ref from a boolean.
inline StringRef toStringRef(bool B) { return StringRef(B ? "true" : "false"); }
@@ -78,6 +88,26 @@ inline bool isAlpha(char C) {
/// lowercase letter as classified by "C" locale.
inline bool isAlnum(char C) { return isAlpha(C) || isDigit(C); }
+/// Checks whether character \p C is valid ASCII (high bit is zero).
+inline bool isASCII(char C) { return static_cast<unsigned char>(C) <= 127; }
+
+/// Checks whether all characters in S are ASCII.
+inline bool isASCII(llvm::StringRef S) {
+ for (char C : S)
+ if (LLVM_UNLIKELY(!isASCII(C)))
+ return false;
+ return true;
+}
+
+/// Checks whether character \p C is printable.
+///
+/// Locale-independent version of the C standard library isprint whose results
+/// may differ on different platforms.
+inline bool isPrint(char C) {
+ unsigned char UC = static_cast<unsigned char>(C);
+ return (0x20 <= UC) && (UC <= 0x7E);
+}
+
/// Returns the corresponding lowercase character if \p x is uppercase.
inline char toLower(char x) {
if (x >= 'A' && x <= 'Z')
@@ -157,7 +187,7 @@ inline std::string fromHex(StringRef Input) {
return Output;
}
-/// \brief Convert the string \p S to an integer of the specified type using
+/// Convert the string \p S to an integer of the specified type using
/// the radix \p Base. If \p Base is 0, auto-detects the radix.
/// Returns true if the number was successfully converted, false otherwise.
template <typename N> bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
@@ -232,19 +262,6 @@ void SplitString(StringRef Source,
SmallVectorImpl<StringRef> &OutFragments,
StringRef Delimiters = " \t\n\v\f\r");
-/// HashString - Hash function for strings.
-///
-/// This is the Bernstein hash function.
-//
-// 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
-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).
inline StringRef getOrdinalSuffix(unsigned Val) {
// It is critically important that we do this perfectly for
@@ -264,9 +281,13 @@ inline StringRef getOrdinalSuffix(unsigned Val) {
}
}
-/// PrintEscapedString - Print each character of the specified string, escaping
-/// it if it is not printable or if it is an escape char.
-void PrintEscapedString(StringRef Name, raw_ostream &Out);
+/// Print each character of the specified string, escaping it if it is not
+/// printable or if it is an escape char.
+void printEscapedString(StringRef Name, raw_ostream &Out);
+
+/// Print each character of the specified string, escaping HTML special
+/// characters.
+void printHTMLEscaped(StringRef String, raw_ostream &Out);
/// printLowerCase - Print each character as lowercase if it is uppercase.
void printLowerCase(StringRef String, raw_ostream &Out);
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index 6c2830b44914..a9f83d3f5091 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -37,12 +37,12 @@ template<typename ValueTy> class StringMapKeyIterator;
/// StringMapEntryBase - Shared base class of StringMapEntry instances.
class StringMapEntryBase {
- unsigned StrLen;
+ size_t StrLen;
public:
- explicit StringMapEntryBase(unsigned Len) : StrLen(Len) {}
+ explicit StringMapEntryBase(size_t Len) : StrLen(Len) {}
- unsigned getKeyLength() const { return StrLen; }
+ size_t getKeyLength() const { return StrLen; }
};
/// StringMapImpl - This is the base class of StringMap that is shared among
@@ -127,10 +127,10 @@ class StringMapEntry : public StringMapEntryBase {
public:
ValueTy second;
- explicit StringMapEntry(unsigned strLen)
+ explicit StringMapEntry(size_t strLen)
: StringMapEntryBase(strLen), second() {}
template <typename... InitTy>
- StringMapEntry(unsigned strLen, InitTy &&... InitVals)
+ StringMapEntry(size_t strLen, InitTy &&... InitVals)
: StringMapEntryBase(strLen), second(std::forward<InitTy>(InitVals)...) {}
StringMapEntry(StringMapEntry &E) = delete;
@@ -155,19 +155,16 @@ public:
template <typename AllocatorTy, typename... InitTy>
static StringMapEntry *Create(StringRef Key, AllocatorTy &Allocator,
InitTy &&... InitVals) {
- unsigned KeyLength = Key.size();
+ size_t KeyLength = Key.size();
// Allocate a new item with space for the string at the end and a null
// terminator.
- unsigned AllocSize = static_cast<unsigned>(sizeof(StringMapEntry))+
- KeyLength+1;
- unsigned Alignment = alignof(StringMapEntry);
+ size_t AllocSize = sizeof(StringMapEntry) + KeyLength + 1;
+ size_t Alignment = alignof(StringMapEntry);
StringMapEntry *NewItem =
static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
-
- if (NewItem == nullptr)
- report_bad_alloc_error("Allocation of StringMap entry failed.");
+ assert(NewItem && "Unhandled out-of-memory");
// Construct the value.
new (NewItem) StringMapEntry(KeyLength, std::forward<InitTy>(InitVals)...);
@@ -203,8 +200,7 @@ public:
template<typename AllocatorTy>
void Destroy(AllocatorTy &Allocator) {
// Free memory referenced by the item.
- unsigned AllocSize =
- static_cast<unsigned>(sizeof(StringMapEntry)) + getKeyLength() + 1;
+ size_t AllocSize = sizeof(StringMapEntry) + getKeyLength() + 1;
this->~StringMapEntry();
Allocator.Deallocate(static_cast<void *>(this), AllocSize);
}
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index f6c93a858db1..a5ba5b59b5a3 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -201,7 +201,7 @@ namespace llvm {
LLVM_NODISCARD
int compare_numeric(StringRef RHS) const;
- /// \brief Determine the edit distance between this string and another
+ /// Determine the edit distance between this string and another
/// string.
///
/// \param Other the string to compare this string against.
@@ -725,10 +725,7 @@ namespace llvm {
/// \returns The split substrings.
LLVM_NODISCARD
std::pair<StringRef, StringRef> split(char Separator) const {
- size_t Idx = find(Separator);
- if (Idx == npos)
- return std::make_pair(*this, StringRef());
- return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
+ return split(StringRef(&Separator, 1));
}
/// Split into two substrings around the first occurrence of a separator
@@ -749,6 +746,24 @@ namespace llvm {
return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
}
+ /// Split into two substrings around the last occurrence of a separator
+ /// string.
+ ///
+ /// If \p Separator is in the string, then the result is a pair (LHS, RHS)
+ /// such that (*this == LHS + Separator + RHS) is true and RHS is
+ /// minimal. If \p Separator is not in the string, then the result is a
+ /// pair (LHS, RHS) where (*this == LHS) and (RHS == "").
+ ///
+ /// \param Separator - The string to split on.
+ /// \return - The split substrings.
+ LLVM_NODISCARD
+ std::pair<StringRef, StringRef> rsplit(StringRef Separator) const {
+ size_t Idx = rfind(Separator);
+ if (Idx == npos)
+ return std::make_pair(*this, StringRef());
+ return std::make_pair(slice(0, Idx), slice(Idx + Separator.size(), npos));
+ }
+
/// Split into substrings around the occurrences of a separator string.
///
/// Each substring is stored in \p A. If \p MaxSplit is >= 0, at most
@@ -796,10 +811,7 @@ namespace llvm {
/// \return - The split substrings.
LLVM_NODISCARD
std::pair<StringRef, StringRef> rsplit(char Separator) const {
- size_t Idx = rfind(Separator);
- if (Idx == npos)
- return std::make_pair(*this, StringRef());
- return std::make_pair(slice(0, Idx), slice(Idx+1, npos));
+ return rsplit(StringRef(&Separator, 1));
}
/// Return string with consecutive \p Char characters starting from the
@@ -855,6 +867,10 @@ namespace llvm {
/// constexpr StringLiteral S("test");
///
class StringLiteral : public StringRef {
+ private:
+ constexpr StringLiteral(const char *Str, size_t N) : StringRef(Str, N) {
+ }
+
public:
template <size_t N>
constexpr StringLiteral(const char (&Str)[N])
@@ -867,6 +883,12 @@ namespace llvm {
#endif
: StringRef(Str, N - 1) {
}
+
+ // Explicit construction for strings like "foo\0bar".
+ template <size_t N>
+ static constexpr StringLiteral withInnerNUL(const char (&Str)[N]) {
+ return StringLiteral(Str, N - 1);
+ }
};
/// @name StringRef Comparison Operators
@@ -902,7 +924,7 @@ namespace llvm {
/// @}
- /// \brief Compute a hash_code for a StringRef.
+ /// Compute a hash_code for a StringRef.
LLVM_NODISCARD
hash_code hash_value(StringRef S);
diff --git a/include/llvm/ADT/StringSwitch.h b/include/llvm/ADT/StringSwitch.h
index 75577b7738ba..b7860b98ce5d 100644
--- a/include/llvm/ADT/StringSwitch.h
+++ b/include/llvm/ADT/StringSwitch.h
@@ -20,7 +20,7 @@
namespace llvm {
-/// \brief A switch()-like statement whose cases are string literals.
+/// A switch()-like statement whose cases are string literals.
///
/// The StringSwitch class is a simple form of a switch() statement that
/// determines whether the given string matches one of the given string
@@ -41,216 +41,176 @@ namespace llvm {
/// \endcode
template<typename T, typename R = T>
class StringSwitch {
- /// \brief The string we are matching.
- StringRef Str;
+ /// The string we are matching.
+ const StringRef Str;
- /// \brief The pointer to the result of this switch statement, once known,
+ /// The pointer to the result of this switch statement, once known,
/// null before that.
- const T *Result;
+ Optional<T> Result;
public:
LLVM_ATTRIBUTE_ALWAYS_INLINE
explicit StringSwitch(StringRef S)
- : Str(S), Result(nullptr) { }
+ : Str(S), Result() { }
// StringSwitch is not copyable.
StringSwitch(const StringSwitch &) = delete;
+
+ // StringSwitch is not assignable due to 'Str' being 'const'.
void operator=(const StringSwitch &) = delete;
+ void operator=(StringSwitch &&other) = delete;
- StringSwitch(StringSwitch &&other) {
- *this = std::move(other);
- }
- StringSwitch &operator=(StringSwitch &&other) {
- Str = other.Str;
- Result = other.Result;
- return *this;
- }
+ StringSwitch(StringSwitch &&other)
+ : Str(other.Str), Result(std::move(other.Result)) { }
~StringSwitch() = default;
// Case-sensitive case matchers
- template<unsigned N>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch& Case(const char (&S)[N], const T& Value) {
- assert(N);
- if (!Result && N-1 == Str.size() &&
- (N == 1 || std::memcmp(S, Str.data(), N-1) == 0)) {
- Result = &Value;
+ StringSwitch &Case(StringLiteral S, T Value) {
+ if (!Result && Str == S) {
+ Result = std::move(Value);
}
return *this;
}
- template<unsigned N>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch& EndsWith(const char (&S)[N], const T &Value) {
- assert(N);
- if (!Result && Str.size() >= N-1 &&
- (N == 1 || std::memcmp(S, Str.data() + Str.size() + 1 - N, N-1) == 0)) {
- Result = &Value;
+ StringSwitch& EndsWith(StringLiteral S, T Value) {
+ if (!Result && Str.endswith(S)) {
+ Result = std::move(Value);
}
return *this;
}
- template<unsigned N>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch& StartsWith(const char (&S)[N], const T &Value) {
- assert(N);
- if (!Result && Str.size() >= N-1 &&
- (N == 1 || std::memcmp(S, Str.data(), N-1) == 0)) {
- Result = &Value;
+ StringSwitch& StartsWith(StringLiteral S, T Value) {
+ if (!Result && Str.startswith(S)) {
+ Result = std::move(Value);
}
return *this;
}
- template<unsigned N0, unsigned N1>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const T& Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, T Value) {
return Case(S0, Value).Case(S1, Value);
}
- template<unsigned N0, unsigned N1, unsigned N2>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const char (&S2)[N2], const T& Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ T Value) {
return Case(S0, Value).Cases(S1, S2, Value);
}
- template<unsigned N0, unsigned N1, unsigned N2, unsigned N3>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const char (&S2)[N2], const char (&S3)[N3],
- const T& Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, T Value) {
return Case(S0, Value).Cases(S1, S2, S3, Value);
}
- template<unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const char (&S2)[N2], const char (&S3)[N3],
- const char (&S4)[N4], const T& Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, StringLiteral S4, T Value) {
return Case(S0, Value).Cases(S1, S2, S3, S4, Value);
}
- template <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
- unsigned N5>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const char (&S2)[N2], const char (&S3)[N3],
- const char (&S4)[N4], const char (&S5)[N5],
- const T &Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, StringLiteral S4, StringLiteral S5,
+ T Value) {
return Case(S0, Value).Cases(S1, S2, S3, S4, S5, Value);
}
- template <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
- unsigned N5, unsigned N6>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const char (&S2)[N2], const char (&S3)[N3],
- const char (&S4)[N4], const char (&S5)[N5],
- const char (&S6)[N6], const T &Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, StringLiteral S4, StringLiteral S5,
+ StringLiteral S6, T Value) {
return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, Value);
}
- template <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
- unsigned N5, unsigned N6, unsigned N7>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const char (&S2)[N2], const char (&S3)[N3],
- const char (&S4)[N4], const char (&S5)[N5],
- const char (&S6)[N6], const char (&S7)[N7],
- const T &Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, StringLiteral S4, StringLiteral S5,
+ StringLiteral S6, StringLiteral S7, T Value) {
return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, Value);
}
- template <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
- unsigned N5, unsigned N6, unsigned N7, unsigned N8>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const char (&S2)[N2], const char (&S3)[N3],
- const char (&S4)[N4], const char (&S5)[N5],
- const char (&S6)[N6], const char (&S7)[N7],
- const char (&S8)[N8], const T &Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, StringLiteral S4, StringLiteral S5,
+ StringLiteral S6, StringLiteral S7, StringLiteral S8,
+ T Value) {
return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, Value);
}
- template <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4,
- unsigned N5, unsigned N6, unsigned N7, unsigned N8, unsigned N9>
LLVM_ATTRIBUTE_ALWAYS_INLINE
- StringSwitch &Cases(const char (&S0)[N0], const char (&S1)[N1],
- const char (&S2)[N2], const char (&S3)[N3],
- const char (&S4)[N4], const char (&S5)[N5],
- const char (&S6)[N6], const char (&S7)[N7],
- const char (&S8)[N8], const char (&S9)[N9],
- const T &Value) {
+ StringSwitch &Cases(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, StringLiteral S4, StringLiteral S5,
+ StringLiteral S6, StringLiteral S7, StringLiteral S8,
+ StringLiteral S9, T Value) {
return Case(S0, Value).Cases(S1, S2, S3, S4, S5, S6, S7, S8, S9, Value);
}
// Case-insensitive case matchers.
- template <unsigned N>
- LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &CaseLower(const char (&S)[N],
- const T &Value) {
- if (!Result && Str.equals_lower(StringRef(S, N - 1)))
- Result = &Value;
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
+ StringSwitch &CaseLower(StringLiteral S, T Value) {
+ if (!Result && Str.equals_lower(S))
+ Result = std::move(Value);
return *this;
}
- template <unsigned N>
- LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &EndsWithLower(const char (&S)[N],
- const T &Value) {
- if (!Result && Str.endswith_lower(StringRef(S, N - 1)))
- Result = &Value;
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
+ StringSwitch &EndsWithLower(StringLiteral S, T Value) {
+ if (!Result && Str.endswith_lower(S))
+ Result = Value;
return *this;
}
- template <unsigned N>
- LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &StartsWithLower(const char (&S)[N],
- const T &Value) {
- if (!Result && Str.startswith_lower(StringRef(S, N - 1)))
- Result = &Value;
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
+ StringSwitch &StartsWithLower(StringLiteral S, T Value) {
+ if (!Result && Str.startswith_lower(S))
+ Result = std::move(Value);
return *this;
}
- template <unsigned N0, unsigned N1>
- LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &
- CasesLower(const char (&S0)[N0], const char (&S1)[N1], const T &Value) {
+
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
+ StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, T Value) {
return CaseLower(S0, Value).CaseLower(S1, Value);
}
- template <unsigned N0, unsigned N1, unsigned N2>
- LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &
- CasesLower(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2],
- const T &Value) {
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
+ StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ T Value) {
return CaseLower(S0, Value).CasesLower(S1, S2, Value);
}
- template <unsigned N0, unsigned N1, unsigned N2, unsigned N3>
- LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &
- CasesLower(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2],
- const char (&S3)[N3], const T &Value) {
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
+ StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, T Value) {
return CaseLower(S0, Value).CasesLower(S1, S2, S3, Value);
}
- template <unsigned N0, unsigned N1, unsigned N2, unsigned N3, unsigned N4>
- LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch &
- CasesLower(const char (&S0)[N0], const char (&S1)[N1], const char (&S2)[N2],
- const char (&S3)[N3], const char (&S4)[N4], const T &Value) {
+ LLVM_ATTRIBUTE_ALWAYS_INLINE
+ StringSwitch &CasesLower(StringLiteral S0, StringLiteral S1, StringLiteral S2,
+ StringLiteral S3, StringLiteral S4, T Value) {
return CaseLower(S0, Value).CasesLower(S1, S2, S3, S4, Value);
}
+ LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
- R Default(const T &Value) const {
+ R Default(T Value) {
if (Result)
- return *Result;
+ return std::move(*Result);
return Value;
}
+ LLVM_NODISCARD
LLVM_ATTRIBUTE_ALWAYS_INLINE
- operator R() const {
+ operator R() {
assert(Result && "Fell off the end of a string-switch");
- return *Result;
+ return std::move(*Result);
}
};
diff --git a/include/llvm/ADT/TinyPtrVector.h b/include/llvm/ADT/TinyPtrVector.h
index 73573d65e2b3..1b8e9aa658c3 100644
--- a/include/llvm/ADT/TinyPtrVector.h
+++ b/include/llvm/ADT/TinyPtrVector.h
@@ -108,6 +108,12 @@ public:
return *this;
}
+ TinyPtrVector(std::initializer_list<EltTy> IL)
+ : Val(IL.size() == 0
+ ? PtrUnion()
+ : IL.size() == 1 ? PtrUnion(*IL.begin())
+ : PtrUnion(new VecTy(IL.begin(), IL.end()))) {}
+
/// Constructor from an ArrayRef.
///
/// This also is a constructor for individual array elements due to the single
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 74fc8eb8ccbf..c95b16dd4e8c 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -101,6 +101,7 @@ public:
enum SubArchType {
NoSubArch,
+ ARMSubArch_v8_4a,
ARMSubArch_v8_3a,
ARMSubArch_v8_2a,
ARMSubArch_v8_1a,
@@ -144,7 +145,8 @@ public:
AMD,
Mesa,
SUSE,
- LastVendorType = SUSE
+ OpenEmbedded,
+ LastVendorType = OpenEmbedded
};
enum OSType {
UnknownOS,
@@ -202,9 +204,7 @@ public:
MSVC,
Itanium,
Cygnus,
- AMDOpenCL,
CoreCLR,
- OpenCL,
Simulator, // Simulator variants of other systems, e.g., Apple's iOS
LastEnvironmentType = Simulator
};
@@ -660,9 +660,29 @@ public:
return getArch() == Triple::aarch64 || getArch() == Triple::aarch64_be;
}
- /// Tests wether the target supports comdat
+ /// Tests whether the target is MIPS 32-bit (little and big endian).
+ bool isMIPS32() const {
+ return getArch() == Triple::mips || getArch() == Triple::mipsel;
+ }
+
+ /// Tests whether the target is MIPS 64-bit (little and big endian).
+ bool isMIPS64() const {
+ return getArch() == Triple::mips64 || getArch() == Triple::mips64el;
+ }
+
+ /// Tests whether the target is MIPS (little and big endian, 32- or 64-bit).
+ bool isMIPS() const {
+ return isMIPS32() || isMIPS64();
+ }
+
+ /// Tests whether the target supports comdat
bool supportsCOMDAT() const {
- return !isOSBinFormatMachO() && !isOSBinFormatWasm();
+ return !isOSBinFormatMachO();
+ }
+
+ /// Tests whether the target uses emulated TLS as default.
+ bool hasDefaultEmulatedTLS() const {
+ return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment();
}
/// @}
diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h
index b17fb2392baf..c86bedd07687 100644
--- a/include/llvm/ADT/UniqueVector.h
+++ b/include/llvm/ADT/UniqueVector.h
@@ -72,16 +72,16 @@ public:
return Vector[ID - 1];
}
- /// \brief Return an iterator to the start of the vector.
+ /// Return an iterator to the start of the vector.
iterator begin() { return Vector.begin(); }
- /// \brief Return an iterator to the start of the vector.
+ /// Return an iterator to the start of the vector.
const_iterator begin() const { return Vector.begin(); }
- /// \brief Return an iterator to the end of the vector.
+ /// Return an iterator to the end of the vector.
iterator end() { return Vector.end(); }
- /// \brief Return an iterator to the end of the vector.
+ /// Return an iterator to the end of the vector.
const_iterator end() const { return Vector.end(); }
/// size - Returns the number of entries in the vector.
diff --git a/include/llvm/ADT/VariadicFunction.h b/include/llvm/ADT/VariadicFunction.h
index 403130c623eb..9028abe4c72c 100644
--- a/include/llvm/ADT/VariadicFunction.h
+++ b/include/llvm/ADT/VariadicFunction.h
@@ -53,7 +53,7 @@ namespace llvm {
#define LLVM_COMMA_JOIN31(x) LLVM_COMMA_JOIN30(x), x ## 30
#define LLVM_COMMA_JOIN32(x) LLVM_COMMA_JOIN31(x), x ## 31
-/// \brief Class which can simulate a type-safe variadic function.
+/// Class which can simulate a type-safe variadic function.
///
/// The VariadicFunction class template makes it easy to define
/// type-safe variadic functions where all arguments have the same
diff --git a/include/llvm/ADT/edit_distance.h b/include/llvm/ADT/edit_distance.h
index 06a01b18a9fb..b2e8ec5c3f6d 100644
--- a/include/llvm/ADT/edit_distance.h
+++ b/include/llvm/ADT/edit_distance.h
@@ -22,7 +22,7 @@
namespace llvm {
-/// \brief Determine the edit distance between two sequences.
+/// Determine the edit distance between two sequences.
///
/// \param FromArray the first sequence to compare.
///
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
index a788f811e4c6..00bb6d528175 100644
--- a/include/llvm/ADT/ilist.h
+++ b/include/llvm/ADT/ilist.h
@@ -84,21 +84,11 @@ template <typename NodeTy>
struct ilist_node_traits : ilist_alloc_traits<NodeTy>,
ilist_callback_traits<NodeTy> {};
-/// Default template traits for intrusive list.
-///
-/// By inheriting from this, you can easily use default implementations for all
-/// common operations.
-///
-/// TODO: Remove this customization point. Specializing ilist_traits is
-/// already fully general.
-template <typename NodeTy>
-struct ilist_default_traits : public ilist_node_traits<NodeTy> {};
-
/// Template traits for intrusive list.
///
/// Customize callbacks and allocation semantics.
template <typename NodeTy>
-struct ilist_traits : public ilist_default_traits<NodeTy> {};
+struct ilist_traits : public ilist_node_traits<NodeTy> {};
/// Const traits should never be instantiated.
template <typename Ty> struct ilist_traits<const Ty> {};
@@ -178,9 +168,6 @@ template <class IntrusiveListT, class TraitsT>
class iplist_impl : public TraitsT, IntrusiveListT {
typedef IntrusiveListT base_list_type;
-protected:
- typedef iplist_impl iplist_impl_type;
-
public:
typedef typename base_list_type::pointer pointer;
typedef typename base_list_type::const_pointer const_pointer;
@@ -369,26 +356,26 @@ public:
using base_list_type::sort;
- /// \brief Get the previous node, or \c nullptr for the list head.
+ /// Get the previous node, or \c nullptr for the list head.
pointer getPrevNode(reference N) const {
auto I = N.getIterator();
if (I == begin())
return nullptr;
return &*std::prev(I);
}
- /// \brief Get the previous node, or \c nullptr for the list head.
+ /// Get the previous node, or \c nullptr for the list head.
const_pointer getPrevNode(const_reference N) const {
return getPrevNode(const_cast<reference >(N));
}
- /// \brief Get the next node, or \c nullptr for the list tail.
+ /// Get the next node, or \c nullptr for the list tail.
pointer getNextNode(reference N) const {
auto Next = std::next(N.getIterator());
if (Next == end())
return nullptr;
return &*Next;
}
- /// \brief Get the next node, or \c nullptr for the list tail.
+ /// Get the next node, or \c nullptr for the list tail.
const_pointer getNextNode(const_reference N) const {
return getNextNode(const_cast<reference >(N));
}
@@ -402,7 +389,7 @@ public:
template <class T, class... Options>
class iplist
: public iplist_impl<simple_ilist<T, Options...>, ilist_traits<T>> {
- typedef typename iplist::iplist_impl_type iplist_impl_type;
+ using iplist_impl_type = typename iplist::iplist_impl;
public:
iplist() = default;
diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h
index 3362611697cb..dd0e6b4ec2b9 100644
--- a/include/llvm/ADT/ilist_node.h
+++ b/include/llvm/ADT/ilist_node.h
@@ -271,7 +271,7 @@ private:
public:
/// @name Adjacent Node Accessors
/// @{
- /// \brief Get the previous node, or \c nullptr for the list head.
+ /// Get the previous node, or \c nullptr for the list head.
NodeTy *getPrevNode() {
// Should be separated to a reused function, but then we couldn't use auto
// (and would need the type of the list).
@@ -280,12 +280,12 @@ public:
return List.getPrevNode(*static_cast<NodeTy *>(this));
}
- /// \brief Get the previous node, or \c nullptr for the list head.
+ /// Get the previous node, or \c nullptr for the list head.
const NodeTy *getPrevNode() const {
return const_cast<ilist_node_with_parent *>(this)->getPrevNode();
}
- /// \brief Get the next node, or \c nullptr for the list tail.
+ /// Get the next node, or \c nullptr for the list tail.
NodeTy *getNextNode() {
// Should be separated to a reused function, but then we couldn't use auto
// (and would need the type of the list).
@@ -294,7 +294,7 @@ public:
return List.getNextNode(*static_cast<NodeTy *>(this));
}
- /// \brief Get the next node, or \c nullptr for the list tail.
+ /// Get the next node, or \c nullptr for the list tail.
const NodeTy *getNextNode() const {
return const_cast<ilist_node_with_parent *>(this)->getNextNode();
}
diff --git a/include/llvm/ADT/ilist_node_options.h b/include/llvm/ADT/ilist_node_options.h
index c33df1eeb819..7ff4005f6757 100644
--- a/include/llvm/ADT/ilist_node_options.h
+++ b/include/llvm/ADT/ilist_node_options.h
@@ -11,7 +11,6 @@
#define LLVM_ADT_ILIST_NODE_OPTIONS_H
#include "llvm/Config/abi-breaking.h"
-#include "llvm/Config/llvm-config.h"
#include <type_traits>
diff --git a/include/llvm/ADT/iterator.h b/include/llvm/ADT/iterator.h
index 711f8f221620..549c5221173d 100644
--- a/include/llvm/ADT/iterator.h
+++ b/include/llvm/ADT/iterator.h
@@ -19,7 +19,7 @@
namespace llvm {
-/// \brief CRTP base class which implements the entire standard iterator facade
+/// CRTP base class which implements the entire standard iterator facade
/// in terms of a minimal subset of the interface.
///
/// Use this when it is reasonable to implement most of the iterator
@@ -183,7 +183,7 @@ public:
}
};
-/// \brief CRTP base class for adapting an iterator to a different type.
+/// CRTP base class for adapting an iterator to a different type.
///
/// This class can be used through CRTP to adapt one iterator into another.
/// Typically this is done through providing in the derived class a custom \c
@@ -274,7 +274,7 @@ public:
ReferenceT operator*() const { return *I; }
};
-/// \brief An iterator type that allows iterating over the pointees via some
+/// An iterator type that allows iterating over the pointees via some
/// other iterator.
///
/// The typical usage of this is to expose a type that iterates over Ts, but
@@ -288,7 +288,7 @@ template <typename WrappedIteratorT,
decltype(**std::declval<WrappedIteratorT>())>::type>
struct pointee_iterator
: iterator_adaptor_base<
- pointee_iterator<WrappedIteratorT>, WrappedIteratorT,
+ pointee_iterator<WrappedIteratorT, T>, WrappedIteratorT,
typename std::iterator_traits<WrappedIteratorT>::iterator_category,
T> {
pointee_iterator() = default;
@@ -311,7 +311,7 @@ make_pointee_range(RangeT &&Range) {
template <typename WrappedIteratorT,
typename T = decltype(&*std::declval<WrappedIteratorT>())>
class pointer_iterator
- : public iterator_adaptor_base<pointer_iterator<WrappedIteratorT>,
+ : public iterator_adaptor_base<pointer_iterator<WrappedIteratorT, T>,
WrappedIteratorT, T> {
mutable T Ptr;
diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h
index 3cbf6198eb60..2ba12866ecf3 100644
--- a/include/llvm/ADT/iterator_range.h
+++ b/include/llvm/ADT/iterator_range.h
@@ -24,7 +24,7 @@
namespace llvm {
-/// \brief A range adaptor for a pair of iterators.
+/// A range adaptor for a pair of iterators.
///
/// This just wraps two iterators into a range-compatible interface. Nothing
/// fancy at all.
@@ -47,7 +47,7 @@ public:
IteratorT end() const { return end_iterator; }
};
-/// \brief Convenience function for iterating over sub-ranges.
+/// Convenience function for iterating over sub-ranges.
///
/// This provides a bit of syntactic sugar to make using sub-ranges
/// in for loops a bit easier. Analogous to std::make_pair().
@@ -59,9 +59,10 @@ template <typename T> iterator_range<T> make_range(std::pair<T, T> p) {
return iterator_range<T>(std::move(p.first), std::move(p.second));
}
-template<typename T>
-iterator_range<decltype(begin(std::declval<T>()))> drop_begin(T &&t, int n) {
- return make_range(std::next(begin(t), n), end(t));
+template <typename T>
+iterator_range<decltype(adl_begin(std::declval<T>()))> drop_begin(T &&t,
+ int n) {
+ return make_range(std::next(adl_begin(t), n), adl_end(t));
}
}