summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support')
-rw-r--r--contrib/llvm/lib/Support/APFloat.cpp1088
-rw-r--r--contrib/llvm/lib/Support/APInt.cpp66
-rw-r--r--contrib/llvm/lib/Support/ARMBuildAttrs.cpp18
-rw-r--r--contrib/llvm/lib/Support/CachePruning.cpp26
-rw-r--r--contrib/llvm/lib/Support/Chrono.cpp47
-rw-r--r--contrib/llvm/lib/Support/CommandLine.cpp213
-rw-r--r--contrib/llvm/lib/Support/Compression.cpp23
-rw-r--r--contrib/llvm/lib/Support/ConvertUTF.cpp (renamed from contrib/llvm/lib/Support/ConvertUTF.c)6
-rw-r--r--contrib/llvm/lib/Support/DataStream.cpp86
-rw-r--r--contrib/llvm/lib/Support/Debug.cpp11
-rw-r--r--contrib/llvm/lib/Support/DeltaAlgorithm.cpp1
-rw-r--r--contrib/llvm/lib/Support/Dwarf.cpp424
-rw-r--r--contrib/llvm/lib/Support/DynamicLibrary.cpp4
-rw-r--r--contrib/llvm/lib/Support/Error.cpp18
-rw-r--r--contrib/llvm/lib/Support/FileOutputBuffer.cpp69
-rw-r--r--contrib/llvm/lib/Support/FileUtilities.cpp8
-rw-r--r--contrib/llvm/lib/Support/FoldingSet.cpp12
-rw-r--r--contrib/llvm/lib/Support/FormatVariadic.cpp156
-rw-r--r--contrib/llvm/lib/Support/GlobPattern.cpp167
-rw-r--r--contrib/llvm/lib/Support/Host.cpp246
-rw-r--r--contrib/llvm/lib/Support/IntrusiveRefCntPtr.cpp14
-rw-r--r--contrib/llvm/lib/Support/LockFileManager.cpp16
-rw-r--r--contrib/llvm/lib/Support/MD5.cpp40
-rw-r--r--contrib/llvm/lib/Support/MemoryBuffer.cpp22
-rw-r--r--contrib/llvm/lib/Support/MemoryObject.cpp14
-rw-r--r--contrib/llvm/lib/Support/NativeFormatting.cpp262
-rw-r--r--contrib/llvm/lib/Support/Path.cpp87
-rw-r--r--contrib/llvm/lib/Support/PrettyStackTrace.cpp45
-rw-r--r--contrib/llvm/lib/Support/RandomNumberGenerator.cpp44
-rw-r--r--contrib/llvm/lib/Support/Regex.cpp12
-rw-r--r--contrib/llvm/lib/Support/SHA1.cpp205
-rw-r--r--contrib/llvm/lib/Support/ScaledNumber.cpp2
-rw-r--r--contrib/llvm/lib/Support/ScopedPrinter.cpp39
-rw-r--r--contrib/llvm/lib/Support/SmallPtrSet.cpp28
-rw-r--r--contrib/llvm/lib/Support/SourceMgr.cpp8
-rw-r--r--contrib/llvm/lib/Support/SpecialCaseList.cpp18
-rw-r--r--contrib/llvm/lib/Support/Statistic.cpp53
-rw-r--r--contrib/llvm/lib/Support/StreamingMemoryObject.cpp138
-rw-r--r--contrib/llvm/lib/Support/StringMap.cpp10
-rw-r--r--contrib/llvm/lib/Support/StringRef.cpp140
-rw-r--r--contrib/llvm/lib/Support/StringSaver.cpp4
-rw-r--r--contrib/llvm/lib/Support/TarWriter.cpp189
-rw-r--r--contrib/llvm/lib/Support/TargetParser.cpp130
-rw-r--r--contrib/llvm/lib/Support/TargetRegistry.cpp5
-rw-r--r--contrib/llvm/lib/Support/Threading.cpp11
-rw-r--r--contrib/llvm/lib/Support/TimeValue.cpp56
-rw-r--r--contrib/llvm/lib/Support/Timer.cpp149
-rw-r--r--contrib/llvm/lib/Support/TrigramIndex.cpp111
-rw-r--r--contrib/llvm/lib/Support/Triple.cpp54
-rw-r--r--contrib/llvm/lib/Support/Twine.cpp12
-rw-r--r--contrib/llvm/lib/Support/Unix/Memory.inc25
-rw-r--r--contrib/llvm/lib/Support/Unix/Path.inc52
-rw-r--r--contrib/llvm/lib/Support/Unix/Process.inc29
-rw-r--r--contrib/llvm/lib/Support/Unix/Signals.inc40
-rw-r--r--contrib/llvm/lib/Support/Unix/TimeValue.inc54
-rw-r--r--contrib/llvm/lib/Support/Unix/Unix.h40
-rw-r--r--contrib/llvm/lib/Support/Windows/Path.inc38
-rw-r--r--contrib/llvm/lib/Support/Windows/Process.inc22
-rw-r--r--contrib/llvm/lib/Support/Windows/Signals.inc5
-rw-r--r--contrib/llvm/lib/Support/Windows/TimeValue.inc61
-rw-r--r--contrib/llvm/lib/Support/Windows/WindowsSupport.h40
-rw-r--r--contrib/llvm/lib/Support/YAMLParser.cpp90
-rw-r--r--contrib/llvm/lib/Support/YAMLTraits.cpp37
-rw-r--r--contrib/llvm/lib/Support/raw_ostream.cpp266
-rw-r--r--contrib/llvm/lib/Support/xxhash.cpp134
65 files changed, 3334 insertions, 2206 deletions
diff --git a/contrib/llvm/lib/Support/APFloat.cpp b/contrib/llvm/lib/Support/APFloat.cpp
index f9370b8..4cfbbf8 100644
--- a/contrib/llvm/lib/Support/APFloat.cpp
+++ b/contrib/llvm/lib/Support/APFloat.cpp
@@ -19,8 +19,10 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include <cstring>
#include <limits.h>
@@ -39,16 +41,15 @@ using namespace llvm;
static_assert(integerPartWidth % 4 == 0, "Part width must be divisible by 4!");
namespace llvm {
-
/* Represents floating point arithmetic semantics. */
struct fltSemantics {
/* The largest E such that 2^E is representable; this matches the
definition of IEEE 754. */
- APFloat::ExponentType maxExponent;
+ APFloatBase::ExponentType maxExponent;
/* The smallest E such that 2^E is a normalized number; this
matches the definition of IEEE 754. */
- APFloat::ExponentType minExponent;
+ APFloatBase::ExponentType minExponent;
/* Number of bits in the significand. This includes the integer
bit. */
@@ -58,12 +59,12 @@ namespace llvm {
unsigned int sizeInBits;
};
- const fltSemantics APFloat::IEEEhalf = { 15, -14, 11, 16 };
- const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, 32 };
- const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, 64 };
- const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, 128 };
- const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, 80 };
- const fltSemantics APFloat::Bogus = { 0, 0, 0, 0 };
+ static const fltSemantics semIEEEhalf = {15, -14, 11, 16};
+ static const fltSemantics semIEEEsingle = {127, -126, 24, 32};
+ static const fltSemantics semIEEEdouble = {1023, -1022, 53, 64};
+ static const fltSemantics semIEEEquad = {16383, -16382, 113, 128};
+ static const fltSemantics semX87DoubleExtended = {16383, -16382, 64, 80};
+ static const fltSemantics semBogus = {0, 0, 0, 0};
/* The PowerPC format consists of two doubles. It does not map cleanly
onto the usual format above. It is approximated using twice the
@@ -75,8 +76,45 @@ namespace llvm {
compile-time arithmetic on PPC double-double numbers, it is not able
to represent all possible values held by a PPC double-double number,
for example: (long double) 1.0 + (long double) 0x1p-106
- Should this be replaced by a full emulation of PPC double-double? */
- const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022 + 53, 53 + 53, 128 };
+ Should this be replaced by a full emulation of PPC double-double?
+
+ Note: we need to make the value different from semBogus as otherwise
+ an unsafe optimization may collapse both values to a single address,
+ and we heavily rely on them having distinct addresses. */
+ static const fltSemantics semPPCDoubleDouble = {-1, 0, 0, 0};
+
+ /* There are temporary semantics for the real PPCDoubleDouble implementation.
+ Currently, APFloat of PPCDoubleDouble holds one PPCDoubleDoubleImpl as the
+ high part of double double, and one IEEEdouble as the low part, so that
+ the old operations operate on PPCDoubleDoubleImpl, while the newly added
+ operations also populate the IEEEdouble.
+
+ TODO: Once all functions support DoubleAPFloat mode, we'll change all
+ PPCDoubleDoubleImpl to IEEEdouble and remove PPCDoubleDoubleImpl. */
+ static const fltSemantics semPPCDoubleDoubleImpl = {1023, -1022 + 53, 53 + 53,
+ 128};
+
+ const fltSemantics &APFloatBase::IEEEhalf() {
+ return semIEEEhalf;
+ }
+ const fltSemantics &APFloatBase::IEEEsingle() {
+ return semIEEEsingle;
+ }
+ const fltSemantics &APFloatBase::IEEEdouble() {
+ return semIEEEdouble;
+ }
+ const fltSemantics &APFloatBase::IEEEquad() {
+ return semIEEEquad;
+ }
+ const fltSemantics &APFloatBase::x87DoubleExtended() {
+ return semX87DoubleExtended;
+ }
+ const fltSemantics &APFloatBase::Bogus() {
+ return semBogus;
+ }
+ const fltSemantics &APFloatBase::PPCDoubleDouble() {
+ return semPPCDoubleDouble;
+ }
/* A tight upper bound on number of parts required to hold the value
pow(5, power) is
@@ -94,6 +132,24 @@ namespace llvm {
const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1;
const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815)
/ (351 * integerPartWidth));
+
+ unsigned int APFloatBase::semanticsPrecision(const fltSemantics &semantics) {
+ return semantics.precision;
+ }
+ APFloatBase::ExponentType
+ APFloatBase::semanticsMaxExponent(const fltSemantics &semantics) {
+ return semantics.maxExponent;
+ }
+ APFloatBase::ExponentType
+ APFloatBase::semanticsMinExponent(const fltSemantics &semantics) {
+ return semantics.minExponent;
+ }
+ unsigned int APFloatBase::semanticsSizeInBits(const fltSemantics &semantics) {
+ return semantics.sizeInBits;
+ }
+
+ unsigned APFloatBase::getSizeInBits(const fltSemantics &Sem) {
+ return Sem.sizeInBits;
}
/* A bunch of private, handy routines. */
@@ -576,10 +632,9 @@ writeSignedDecimal (char *dst, int value)
return dst;
}
+namespace detail {
/* Constructors. */
-void
-APFloat::initialize(const fltSemantics *ourSemantics)
-{
+void IEEEFloat::initialize(const fltSemantics *ourSemantics) {
unsigned int count;
semantics = ourSemantics;
@@ -588,16 +643,12 @@ APFloat::initialize(const fltSemantics *ourSemantics)
significand.parts = new integerPart[count];
}
-void
-APFloat::freeSignificand()
-{
+void IEEEFloat::freeSignificand() {
if (needsCleanup())
delete [] significand.parts;
}
-void
-APFloat::assign(const APFloat &rhs)
-{
+void IEEEFloat::assign(const IEEEFloat &rhs) {
assert(semantics == rhs.semantics);
sign = rhs.sign;
@@ -607,9 +658,7 @@ APFloat::assign(const APFloat &rhs)
copySignificand(rhs);
}
-void
-APFloat::copySignificand(const APFloat &rhs)
-{
+void IEEEFloat::copySignificand(const IEEEFloat &rhs) {
assert(isFiniteNonZero() || category == fcNaN);
assert(rhs.partCount() >= partCount());
@@ -620,8 +669,7 @@ APFloat::copySignificand(const APFloat &rhs)
/* Make this number a NaN, with an arbitrary but deterministic value
for the significand. If double or longer, this is a signalling NaN,
which may not be ideal. If float, this is QNaN(0). */
-void APFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill)
-{
+void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) {
category = fcNaN;
sign = Negative;
@@ -663,20 +711,11 @@ void APFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill)
// For x87 extended precision, we want to make a NaN, not a
// pseudo-NaN. Maybe we should expose the ability to make
// pseudo-NaNs?
- if (semantics == &APFloat::x87DoubleExtended)
+ if (semantics == &semX87DoubleExtended)
APInt::tcSetBit(significand, QNaNBit + 1);
}
-APFloat APFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
- const APInt *fill) {
- APFloat value(Sem, uninitialized);
- value.makeNaN(SNaN, Negative, fill);
- return value;
-}
-
-APFloat &
-APFloat::operator=(const APFloat &rhs)
-{
+IEEEFloat &IEEEFloat::operator=(const IEEEFloat &rhs) {
if (this != &rhs) {
if (semantics != rhs.semantics) {
freeSignificand();
@@ -688,8 +727,7 @@ APFloat::operator=(const APFloat &rhs)
return *this;
}
-APFloat &
-APFloat::operator=(APFloat &&rhs) {
+IEEEFloat &IEEEFloat::operator=(IEEEFloat &&rhs) {
freeSignificand();
semantics = rhs.semantics;
@@ -698,19 +736,17 @@ APFloat::operator=(APFloat &&rhs) {
category = rhs.category;
sign = rhs.sign;
- rhs.semantics = &Bogus;
+ rhs.semantics = &semBogus;
return *this;
}
-bool
-APFloat::isDenormal() const {
+bool IEEEFloat::isDenormal() const {
return isFiniteNonZero() && (exponent == semantics->minExponent) &&
(APInt::tcExtractBit(significandParts(),
semantics->precision - 1) == 0);
}
-bool
-APFloat::isSmallest() const {
+bool IEEEFloat::isSmallest() const {
// The smallest number by magnitude in our format will be the smallest
// denormal, i.e. the floating point number with exponent being minimum
// exponent and significand bitwise equal to 1 (i.e. with MSB equal to 0).
@@ -718,7 +754,7 @@ APFloat::isSmallest() const {
significandMSB() == 0;
}
-bool APFloat::isSignificandAllOnes() const {
+bool IEEEFloat::isSignificandAllOnes() const {
// Test if the significand excluding the integral bit is all ones. This allows
// us to test for binade boundaries.
const integerPart *Parts = significandParts();
@@ -740,7 +776,7 @@ bool APFloat::isSignificandAllOnes() const {
return true;
}
-bool APFloat::isSignificandAllZeros() const {
+bool IEEEFloat::isSignificandAllZeros() const {
// Test if the significand excluding the integral bit is all zeros. This
// allows us to test for binade boundaries.
const integerPart *Parts = significandParts();
@@ -762,25 +798,22 @@ bool APFloat::isSignificandAllZeros() const {
return true;
}
-bool
-APFloat::isLargest() const {
+bool IEEEFloat::isLargest() const {
// The largest number by magnitude in our format will be the floating point
// number with maximum exponent and with significand that is all ones.
return isFiniteNonZero() && exponent == semantics->maxExponent
&& isSignificandAllOnes();
}
-bool
-APFloat::isInteger() const {
+bool IEEEFloat::isInteger() const {
// This could be made more efficient; I'm going for obviously correct.
if (!isFinite()) return false;
- APFloat truncated = *this;
+ IEEEFloat truncated = *this;
truncated.roundToIntegral(rmTowardZero);
return compare(truncated) == cmpEqual;
}
-bool
-APFloat::bitwiseIsEqual(const APFloat &rhs) const {
+bool IEEEFloat::bitwiseIsEqual(const IEEEFloat &rhs) const {
if (this == &rhs)
return true;
if (semantics != rhs.semantics ||
@@ -797,7 +830,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
rhs.significandParts());
}
-APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
+IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, integerPart value) {
initialize(&ourSemantics);
sign = 0;
category = fcNormal;
@@ -807,93 +840,54 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
normalize(rmNearestTiesToEven, lfExactlyZero);
}
-APFloat::APFloat(const fltSemantics &ourSemantics) {
+IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics) {
initialize(&ourSemantics);
category = fcZero;
sign = false;
}
-APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
- // Allocates storage if necessary but does not initialize it.
- initialize(&ourSemantics);
-}
+// Delegate to the previous constructor, because later copy constructor may
+// actually inspects category, which can't be garbage.
+IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, uninitializedTag tag)
+ : IEEEFloat(ourSemantics) {}
-APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) {
- initialize(&ourSemantics);
- convertFromString(text, rmNearestTiesToEven);
-}
-
-APFloat::APFloat(const APFloat &rhs) {
+IEEEFloat::IEEEFloat(const IEEEFloat &rhs) {
initialize(rhs.semantics);
assign(rhs);
}
-APFloat::APFloat(APFloat &&rhs) : semantics(&Bogus) {
+IEEEFloat::IEEEFloat(IEEEFloat &&rhs) : semantics(&semBogus) {
*this = std::move(rhs);
}
-APFloat::~APFloat()
-{
- freeSignificand();
-}
+IEEEFloat::~IEEEFloat() { freeSignificand(); }
// Profile - This method 'profiles' an APFloat for use with FoldingSet.
-void APFloat::Profile(FoldingSetNodeID& ID) const {
+void IEEEFloat::Profile(FoldingSetNodeID &ID) const {
ID.Add(bitcastToAPInt());
}
-unsigned int
-APFloat::partCount() const
-{
+unsigned int IEEEFloat::partCount() const {
return partCountForBits(semantics->precision + 1);
}
-unsigned int
-APFloat::semanticsPrecision(const fltSemantics &semantics)
-{
- return semantics.precision;
-}
-APFloat::ExponentType
-APFloat::semanticsMaxExponent(const fltSemantics &semantics)
-{
- return semantics.maxExponent;
-}
-APFloat::ExponentType
-APFloat::semanticsMinExponent(const fltSemantics &semantics)
-{
- return semantics.minExponent;
-}
-unsigned int
-APFloat::semanticsSizeInBits(const fltSemantics &semantics)
-{
- return semantics.sizeInBits;
-}
-
-const integerPart *
-APFloat::significandParts() const
-{
- return const_cast<APFloat *>(this)->significandParts();
+const integerPart *IEEEFloat::significandParts() const {
+ return const_cast<IEEEFloat *>(this)->significandParts();
}
-integerPart *
-APFloat::significandParts()
-{
+integerPart *IEEEFloat::significandParts() {
if (partCount() > 1)
return significand.parts;
else
return &significand.part;
}
-void
-APFloat::zeroSignificand()
-{
+void IEEEFloat::zeroSignificand() {
APInt::tcSet(significandParts(), 0, partCount());
}
/* Increment an fcNormal floating point number's significand. */
-void
-APFloat::incrementSignificand()
-{
+void IEEEFloat::incrementSignificand() {
integerPart carry;
carry = APInt::tcIncrement(significandParts(), partCount());
@@ -904,9 +898,7 @@ APFloat::incrementSignificand()
}
/* Add the significand of the RHS. Returns the carry flag. */
-integerPart
-APFloat::addSignificand(const APFloat &rhs)
-{
+integerPart IEEEFloat::addSignificand(const IEEEFloat &rhs) {
integerPart *parts;
parts = significandParts();
@@ -919,9 +911,8 @@ APFloat::addSignificand(const APFloat &rhs)
/* Subtract the significand of the RHS with a borrow flag. Returns
the borrow flag. */
-integerPart
-APFloat::subtractSignificand(const APFloat &rhs, integerPart borrow)
-{
+integerPart IEEEFloat::subtractSignificand(const IEEEFloat &rhs,
+ integerPart borrow) {
integerPart *parts;
parts = significandParts();
@@ -936,9 +927,8 @@ APFloat::subtractSignificand(const APFloat &rhs, integerPart borrow)
/* Multiply the significand of the RHS. If ADDEND is non-NULL, add it
on to the full-precision result of the multiplication. Returns the
lost fraction. */
-lostFraction
-APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
-{
+lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs,
+ const IEEEFloat *addend) {
unsigned int omsb; // One, not zero, based MSB.
unsigned int partsCount, newPartsCount, precision;
integerPart *lhsSignificand;
@@ -1011,7 +1001,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
significand.parts = fullSignificand;
semantics = &extendedSemantics;
- APFloat extendedAddend(*addend);
+ IEEEFloat extendedAddend(*addend);
status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
assert(status == opOK);
(void)status;
@@ -1045,7 +1035,8 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
// the radix point (i.e. "MSB . rest-significant-bits").
//
// Note that the result is not normalized when "omsb < precision". So, the
- // caller needs to call APFloat::normalize() if normalized value is expected.
+ // caller needs to call IEEEFloat::normalize() if normalized value is
+ // expected.
if (omsb > precision) {
unsigned int bits, significantParts;
lostFraction lf;
@@ -1066,9 +1057,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
}
/* Multiply the significands of LHS and RHS to DST. */
-lostFraction
-APFloat::divideSignificand(const APFloat &rhs)
-{
+lostFraction IEEEFloat::divideSignificand(const IEEEFloat &rhs) {
unsigned int bit, i, partsCount;
const integerPart *rhsSignificand;
integerPart *lhsSignificand, *dividend, *divisor;
@@ -1150,22 +1139,16 @@ APFloat::divideSignificand(const APFloat &rhs)
return lost_fraction;
}
-unsigned int
-APFloat::significandMSB() const
-{
+unsigned int IEEEFloat::significandMSB() const {
return APInt::tcMSB(significandParts(), partCount());
}
-unsigned int
-APFloat::significandLSB() const
-{
+unsigned int IEEEFloat::significandLSB() const {
return APInt::tcLSB(significandParts(), partCount());
}
/* Note that a zero result is NOT normalized to fcZero. */
-lostFraction
-APFloat::shiftSignificandRight(unsigned int bits)
-{
+lostFraction IEEEFloat::shiftSignificandRight(unsigned int bits) {
/* Our exponent should not overflow. */
assert((ExponentType) (exponent + bits) >= exponent);
@@ -1175,9 +1158,7 @@ APFloat::shiftSignificandRight(unsigned int bits)
}
/* Shift the significand left BITS bits, subtract BITS from its exponent. */
-void
-APFloat::shiftSignificandLeft(unsigned int bits)
-{
+void IEEEFloat::shiftSignificandLeft(unsigned int bits) {
assert(bits < semantics->precision);
if (bits) {
@@ -1190,9 +1171,8 @@ APFloat::shiftSignificandLeft(unsigned int bits)
}
}
-APFloat::cmpResult
-APFloat::compareAbsoluteValue(const APFloat &rhs) const
-{
+IEEEFloat::cmpResult
+IEEEFloat::compareAbsoluteValue(const IEEEFloat &rhs) const {
int compare;
assert(semantics == rhs.semantics);
@@ -1217,9 +1197,7 @@ APFloat::compareAbsoluteValue(const APFloat &rhs) const
/* Handle overflow. Sign is preserved. We either become infinity or
the largest finite number. */
-APFloat::opStatus
-APFloat::handleOverflow(roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::handleOverflow(roundingMode rounding_mode) {
/* Infinity? */
if (rounding_mode == rmNearestTiesToEven ||
rounding_mode == rmNearestTiesToAway ||
@@ -1243,11 +1221,9 @@ APFloat::handleOverflow(roundingMode rounding_mode)
would need to be rounded away from zero (i.e., by increasing the
signficand). This routine must work for fcZero of both signs, and
fcNormal numbers. */
-bool
-APFloat::roundAwayFromZero(roundingMode rounding_mode,
- lostFraction lost_fraction,
- unsigned int bit) const
-{
+bool IEEEFloat::roundAwayFromZero(roundingMode rounding_mode,
+ lostFraction lost_fraction,
+ unsigned int bit) const {
/* NaNs and infinities should not have lost fractions. */
assert(isFiniteNonZero() || category == fcZero);
@@ -1280,10 +1256,8 @@ APFloat::roundAwayFromZero(roundingMode rounding_mode,
llvm_unreachable("Invalid rounding mode found");
}
-APFloat::opStatus
-APFloat::normalize(roundingMode rounding_mode,
- lostFraction lost_fraction)
-{
+IEEEFloat::opStatus IEEEFloat::normalize(roundingMode rounding_mode,
+ lostFraction lost_fraction) {
unsigned int omsb; /* One, not zero, based MSB. */
int exponentChange;
@@ -1388,9 +1362,8 @@ APFloat::normalize(roundingMode rounding_mode,
return (opStatus) (opUnderflow | opInexact);
}
-APFloat::opStatus
-APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
-{
+IEEEFloat::opStatus IEEEFloat::addOrSubtractSpecials(const IEEEFloat &rhs,
+ bool subtract) {
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
@@ -1445,9 +1418,8 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
}
/* Add or subtract two normal numbers. */
-lostFraction
-APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
-{
+lostFraction IEEEFloat::addOrSubtractSignificand(const IEEEFloat &rhs,
+ bool subtract) {
integerPart carry;
lostFraction lost_fraction;
int bits;
@@ -1461,7 +1433,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
/* Subtraction is more subtle than one might naively expect. */
if (subtract) {
- APFloat temp_rhs(rhs);
+ IEEEFloat temp_rhs(rhs);
bool reverse;
if (bits == 0) {
@@ -1500,7 +1472,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
(void)carry;
} else {
if (bits > 0) {
- APFloat temp_rhs(rhs);
+ IEEEFloat temp_rhs(rhs);
lost_fraction = temp_rhs.shiftSignificandRight(bits);
carry = addSignificand(temp_rhs);
@@ -1517,9 +1489,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
return lost_fraction;
}
-APFloat::opStatus
-APFloat::multiplySpecials(const APFloat &rhs)
-{
+IEEEFloat::opStatus IEEEFloat::multiplySpecials(const IEEEFloat &rhs) {
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
@@ -1561,9 +1531,7 @@ APFloat::multiplySpecials(const APFloat &rhs)
}
}
-APFloat::opStatus
-APFloat::divideSpecials(const APFloat &rhs)
-{
+IEEEFloat::opStatus IEEEFloat::divideSpecials(const IEEEFloat &rhs) {
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
@@ -1602,9 +1570,7 @@ APFloat::divideSpecials(const APFloat &rhs)
}
}
-APFloat::opStatus
-APFloat::modSpecials(const APFloat &rhs)
-{
+IEEEFloat::opStatus IEEEFloat::modSpecials(const IEEEFloat &rhs) {
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
@@ -1640,32 +1606,25 @@ APFloat::modSpecials(const APFloat &rhs)
}
/* Change sign. */
-void
-APFloat::changeSign()
-{
+void IEEEFloat::changeSign() {
/* Look mummy, this one's easy. */
sign = !sign;
}
-void
-APFloat::clearSign()
-{
+void IEEEFloat::clearSign() {
/* So is this one. */
sign = 0;
}
-void
-APFloat::copySign(const APFloat &rhs)
-{
+void IEEEFloat::copySign(const IEEEFloat &rhs) {
/* And this one. */
sign = rhs.sign;
}
/* Normalized addition or subtraction. */
-APFloat::opStatus
-APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
- bool subtract)
-{
+IEEEFloat::opStatus IEEEFloat::addOrSubtract(const IEEEFloat &rhs,
+ roundingMode rounding_mode,
+ bool subtract) {
opStatus fs;
fs = addOrSubtractSpecials(rhs, subtract);
@@ -1693,23 +1652,20 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
}
/* Normalized addition. */
-APFloat::opStatus
-APFloat::add(const APFloat &rhs, roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::add(const IEEEFloat &rhs,
+ roundingMode rounding_mode) {
return addOrSubtract(rhs, rounding_mode, false);
}
/* Normalized subtraction. */
-APFloat::opStatus
-APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::subtract(const IEEEFloat &rhs,
+ roundingMode rounding_mode) {
return addOrSubtract(rhs, rounding_mode, true);
}
/* Normalized multiply. */
-APFloat::opStatus
-APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::multiply(const IEEEFloat &rhs,
+ roundingMode rounding_mode) {
opStatus fs;
sign ^= rhs.sign;
@@ -1726,9 +1682,8 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
}
/* Normalized divide. */
-APFloat::opStatus
-APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::divide(const IEEEFloat &rhs,
+ roundingMode rounding_mode) {
opStatus fs;
sign ^= rhs.sign;
@@ -1745,11 +1700,9 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
}
/* Normalized remainder. This is not currently correct in all cases. */
-APFloat::opStatus
-APFloat::remainder(const APFloat &rhs)
-{
+IEEEFloat::opStatus IEEEFloat::remainder(const IEEEFloat &rhs) {
opStatus fs;
- APFloat V = *this;
+ IEEEFloat V = *this;
unsigned int origSign = sign;
fs = V.divide(rhs, rmNearestTiesToEven);
@@ -1761,8 +1714,10 @@ APFloat::remainder(const APFloat &rhs)
bool ignored;
fs = V.convertToInteger(x, parts * integerPartWidth, true,
rmNearestTiesToEven, &ignored);
- if (fs==opInvalidOp)
+ if (fs==opInvalidOp) {
+ delete[] x;
return fs;
+ }
fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true,
rmNearestTiesToEven);
@@ -1782,14 +1737,12 @@ APFloat::remainder(const APFloat &rhs)
/* Normalized llvm frem (C fmod).
This is not currently correct in all cases. */
-APFloat::opStatus
-APFloat::mod(const APFloat &rhs)
-{
+IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) {
opStatus fs;
fs = modSpecials(rhs);
if (isFiniteNonZero() && rhs.isFiniteNonZero()) {
- APFloat V = *this;
+ IEEEFloat V = *this;
unsigned int origSign = sign;
fs = V.divide(rhs, rmNearestTiesToEven);
@@ -1801,8 +1754,10 @@ APFloat::mod(const APFloat &rhs)
bool ignored;
fs = V.convertToInteger(x, parts * integerPartWidth, true,
rmTowardZero, &ignored);
- if (fs==opInvalidOp)
+ if (fs==opInvalidOp) {
+ delete[] x;
return fs;
+ }
fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true,
rmNearestTiesToEven);
@@ -1822,11 +1777,9 @@ APFloat::mod(const APFloat &rhs)
}
/* Normalized fused-multiply-add. */
-APFloat::opStatus
-APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
- const APFloat &addend,
- roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::fusedMultiplyAdd(const IEEEFloat &multiplicand,
+ const IEEEFloat &addend,
+ roundingMode rounding_mode) {
opStatus fs;
/* Post-multiplication sign, before addition. */
@@ -1867,7 +1820,7 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
}
/* Rounding-mode corrrect round to integral value. */
-APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) {
+IEEEFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) {
opStatus fs;
// If the exponent is large enough, we know that this value is already
@@ -1884,7 +1837,7 @@ APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) {
// addition instead.
APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1);
IntegerConstant <<= semanticsPrecision(*semantics)-1;
- APFloat MagicConstant(*semantics);
+ IEEEFloat MagicConstant(*semantics);
fs = MagicConstant.convertFromAPInt(IntegerConstant, false,
rmNearestTiesToEven);
MagicConstant.copySign(*this);
@@ -1910,9 +1863,7 @@ APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) {
/* Comparison requires normalized numbers. */
-APFloat::cmpResult
-APFloat::compare(const APFloat &rhs) const
-{
+IEEEFloat::cmpResult IEEEFloat::compare(const IEEEFloat &rhs) const {
cmpResult result;
assert(semantics == rhs.semantics);
@@ -1982,17 +1933,16 @@ APFloat::compare(const APFloat &rhs) const
return result;
}
-/// APFloat::convert - convert a value of one floating point type to another.
+/// IEEEFloat::convert - convert a value of one floating point type to another.
/// The return value corresponds to the IEEE754 exceptions. *losesInfo
/// records whether the transformation lost information, i.e. whether
/// converting the result back to the original type will produce the
/// original value (this is almost the same as return value==fsOK, but there
/// are edge cases where this is not so).
-APFloat::opStatus
-APFloat::convert(const fltSemantics &toSemantics,
- roundingMode rounding_mode, bool *losesInfo)
-{
+IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics,
+ roundingMode rounding_mode,
+ bool *losesInfo) {
lostFraction lostFraction;
unsigned int newPartCount, oldPartCount;
opStatus fs;
@@ -2005,8 +1955,8 @@ APFloat::convert(const fltSemantics &toSemantics,
shift = toSemantics.precision - fromSemantics.precision;
bool X86SpecialNan = false;
- if (&fromSemantics == &APFloat::x87DoubleExtended &&
- &toSemantics != &APFloat::x87DoubleExtended && category == fcNaN &&
+ if (&fromSemantics == &semX87DoubleExtended &&
+ &toSemantics != &semX87DoubleExtended && category == fcNaN &&
(!(*significandParts() & 0x8000000000000000ULL) ||
!(*significandParts() & 0x4000000000000000ULL))) {
// x86 has some unusual NaNs which cannot be represented in any other
@@ -2070,7 +2020,7 @@ APFloat::convert(const fltSemantics &toSemantics,
// For x87 extended precision, we want to make a NaN, not a special NaN if
// the input wasn't special either.
- if (!X86SpecialNan && semantics == &APFloat::x87DoubleExtended)
+ if (!X86SpecialNan && semantics == &semX87DoubleExtended)
APInt::tcSetBit(significandParts(), semantics->precision - 1);
// gcc forces the Quiet bit on, which means (float)(double)(float_sNan)
@@ -2096,12 +2046,9 @@ APFloat::convert(const fltSemantics &toSemantics,
Note that for conversions to integer type the C standard requires
round-to-zero to always be used. */
-APFloat::opStatus
-APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
- bool isSigned,
- roundingMode rounding_mode,
- bool *isExact) const
-{
+IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
+ integerPart *parts, unsigned int width, bool isSigned,
+ roundingMode rounding_mode, bool *isExact) const {
lostFraction lost_fraction;
const integerPart *src;
unsigned int dstPartsCount, truncatedBits;
@@ -2208,11 +2155,11 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
the original value. This is almost equivalent to result==opOK,
except for negative zeroes.
*/
-APFloat::opStatus
-APFloat::convertToInteger(integerPart *parts, unsigned int width,
- bool isSigned,
- roundingMode rounding_mode, bool *isExact) const
-{
+IEEEFloat::opStatus IEEEFloat::convertToInteger(integerPart *parts,
+ unsigned int width,
+ bool isSigned,
+ roundingMode rounding_mode,
+ bool *isExact) const {
opStatus fs;
fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
@@ -2242,10 +2189,9 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width,
an APSInt, whose initial bit-width and signed-ness are used to determine the
precision of the conversion.
*/
-APFloat::opStatus
-APFloat::convertToInteger(APSInt &result,
- roundingMode rounding_mode, bool *isExact) const
-{
+IEEEFloat::opStatus IEEEFloat::convertToInteger(APSInt &result,
+ roundingMode rounding_mode,
+ bool *isExact) const {
unsigned bitWidth = result.getBitWidth();
SmallVector<uint64_t, 4> parts(result.getNumWords());
opStatus status = convertToInteger(
@@ -2258,11 +2204,8 @@ APFloat::convertToInteger(APSInt &result,
/* Convert an unsigned integer SRC to a floating point number,
rounding according to ROUNDING_MODE. The sign of the floating
point number is not modified. */
-APFloat::opStatus
-APFloat::convertFromUnsignedParts(const integerPart *src,
- unsigned int srcCount,
- roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::convertFromUnsignedParts(
+ const integerPart *src, unsigned int srcCount, roundingMode rounding_mode) {
unsigned int omsb, precision, dstCount;
integerPart *dst;
lostFraction lost_fraction;
@@ -2289,11 +2232,8 @@ APFloat::convertFromUnsignedParts(const integerPart *src,
return normalize(rounding_mode, lost_fraction);
}
-APFloat::opStatus
-APFloat::convertFromAPInt(const APInt &Val,
- bool isSigned,
- roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::convertFromAPInt(const APInt &Val, bool isSigned,
+ roundingMode rounding_mode) {
unsigned int partCount = Val.getNumWords();
APInt api = Val;
@@ -2309,12 +2249,10 @@ APFloat::convertFromAPInt(const APInt &Val,
/* Convert a two's complement integer SRC to a floating point number,
rounding according to ROUNDING_MODE. ISSIGNED is true if the
integer is signed, in which case it must be sign-extended. */
-APFloat::opStatus
-APFloat::convertFromSignExtendedInteger(const integerPart *src,
- unsigned int srcCount,
- bool isSigned,
- roundingMode rounding_mode)
-{
+IEEEFloat::opStatus
+IEEEFloat::convertFromSignExtendedInteger(const integerPart *src,
+ unsigned int srcCount, bool isSigned,
+ roundingMode rounding_mode) {
opStatus status;
if (isSigned &&
@@ -2337,11 +2275,10 @@ APFloat::convertFromSignExtendedInteger(const integerPart *src,
}
/* FIXME: should this just take a const APInt reference? */
-APFloat::opStatus
-APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
- unsigned int width, bool isSigned,
- roundingMode rounding_mode)
-{
+IEEEFloat::opStatus
+IEEEFloat::convertFromZeroExtendedInteger(const integerPart *parts,
+ unsigned int width, bool isSigned,
+ roundingMode rounding_mode) {
unsigned int partCount = partCountForBits(width);
APInt api = APInt(width, makeArrayRef(parts, partCount));
@@ -2354,9 +2291,9 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
}
-APFloat::opStatus
-APFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode)
-{
+IEEEFloat::opStatus
+IEEEFloat::convertFromHexadecimalString(StringRef s,
+ roundingMode rounding_mode) {
lostFraction lost_fraction = lfExactlyZero;
category = fcNormal;
@@ -2434,11 +2371,10 @@ APFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode)
return normalize(rounding_mode, lost_fraction);
}
-APFloat::opStatus
-APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
- unsigned sigPartCount, int exp,
- roundingMode rounding_mode)
-{
+IEEEFloat::opStatus
+IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts,
+ unsigned sigPartCount, int exp,
+ roundingMode rounding_mode) {
unsigned int parts, pow5PartCount;
fltSemantics calcSemantics = { 32767, -32767, 0, 0 };
integerPart pow5Parts[maxPowerOfFiveParts];
@@ -2460,8 +2396,9 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
excessPrecision = calcSemantics.precision - semantics->precision;
truncatedBits = excessPrecision;
- APFloat decSig = APFloat::getZero(calcSemantics, sign);
- APFloat pow5(calcSemantics);
+ IEEEFloat decSig(calcSemantics, uninitialized);
+ decSig.makeZero(sign);
+ IEEEFloat pow5(calcSemantics);
sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount,
rmNearestTiesToEven);
@@ -2519,9 +2456,8 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
}
}
-APFloat::opStatus
-APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
-{
+IEEEFloat::opStatus
+IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) {
decimalInfo D;
opStatus fs;
@@ -2637,8 +2573,7 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
return fs;
}
-bool
-APFloat::convertFromStringSpecials(StringRef str) {
+bool IEEEFloat::convertFromStringSpecials(StringRef str) {
if (str.equals("inf") || str.equals("INFINITY")) {
makeInf(false);
return true;
@@ -2662,9 +2597,8 @@ APFloat::convertFromStringSpecials(StringRef str) {
return false;
}
-APFloat::opStatus
-APFloat::convertFromString(StringRef str, roundingMode rounding_mode)
-{
+IEEEFloat::opStatus IEEEFloat::convertFromString(StringRef str,
+ roundingMode rounding_mode) {
assert(!str.empty() && "Invalid string length");
// Handle special cases.
@@ -2714,10 +2648,9 @@ APFloat::convertFromString(StringRef str, roundingMode rounding_mode)
1 (normal numbers) or 2 (normal numbers rounded-away-from-zero with
any other digits zero).
*/
-unsigned int
-APFloat::convertToHexString(char *dst, unsigned int hexDigits,
- bool upperCase, roundingMode rounding_mode) const
-{
+unsigned int IEEEFloat::convertToHexString(char *dst, unsigned int hexDigits,
+ bool upperCase,
+ roundingMode rounding_mode) const {
char *p;
p = dst;
@@ -2762,11 +2695,9 @@ APFloat::convertToHexString(char *dst, unsigned int hexDigits,
form of a normal floating point number with the specified number of
hexadecimal digits. If HEXDIGITS is zero the minimum number of
digits necessary to print the value precisely is output. */
-char *
-APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
- bool upperCase,
- roundingMode rounding_mode) const
-{
+char *IEEEFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
+ bool upperCase,
+ roundingMode rounding_mode) const {
unsigned int count, valueBits, shift, partsCount, outputDigits;
const char *hexDigitChars;
const integerPart *significand;
@@ -2866,7 +2797,7 @@ APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
return writeSignedDecimal (dst, exponent);
}
-hash_code llvm::hash_value(const APFloat &Arg) {
+hash_code hash_value(const IEEEFloat &Arg) {
if (!Arg.isFiniteNonZero())
return hash_combine((uint8_t)Arg.category,
// NaN has no sign, fix it at zero.
@@ -2890,10 +2821,8 @@ hash_code llvm::hash_value(const APFloat &Arg) {
// Denormals have exponent minExponent in APFloat, but minExponent-1 in
// the actual IEEE respresentations. We compensate for that here.
-APInt
-APFloat::convertF80LongDoubleAPFloatToAPInt() const
-{
- assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended);
+APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const {
+ assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended);
assert(partCount()==2);
uint64_t myexponent, mysignificand;
@@ -2922,10 +2851,8 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const
return APInt(80, words);
}
-APInt
-APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
-{
- assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble);
+APInt IEEEFloat::convertPPCDoubleDoubleAPFloatToAPInt() const {
+ assert(semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleImpl);
assert(partCount()==2);
uint64_t words[2];
@@ -2939,14 +2866,14 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
// Declare fltSemantics before APFloat that uses it (and
// saves pointer to it) to ensure correct destruction order.
fltSemantics extendedSemantics = *semantics;
- extendedSemantics.minExponent = IEEEdouble.minExponent;
- APFloat extended(*this);
+ extendedSemantics.minExponent = semIEEEdouble.minExponent;
+ IEEEFloat extended(*this);
fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
(void)fs;
- APFloat u(extended);
- fs = u.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo);
+ IEEEFloat u(extended);
+ fs = u.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK || fs == opInexact);
(void)fs;
words[0] = *u.convertDoubleAPFloatToAPInt().getRawData();
@@ -2960,9 +2887,9 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
assert(fs == opOK && !losesInfo);
(void)fs;
- APFloat v(extended);
+ IEEEFloat v(extended);
v.subtract(u, rmNearestTiesToEven);
- fs = v.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo);
+ fs = v.convert(semIEEEdouble, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
(void)fs;
words[1] = *v.convertDoubleAPFloatToAPInt().getRawData();
@@ -2973,10 +2900,8 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
return APInt(128, words);
}
-APInt
-APFloat::convertQuadrupleAPFloatToAPInt() const
-{
- assert(semantics == (const llvm::fltSemantics*)&IEEEquad);
+APInt IEEEFloat::convertQuadrupleAPFloatToAPInt() const {
+ assert(semantics == (const llvm::fltSemantics*)&semIEEEquad);
assert(partCount()==2);
uint64_t myexponent, mysignificand, mysignificand2;
@@ -3009,10 +2934,8 @@ APFloat::convertQuadrupleAPFloatToAPInt() const
return APInt(128, words);
}
-APInt
-APFloat::convertDoubleAPFloatToAPInt() const
-{
- assert(semantics == (const llvm::fltSemantics*)&IEEEdouble);
+APInt IEEEFloat::convertDoubleAPFloatToAPInt() const {
+ assert(semantics == (const llvm::fltSemantics*)&semIEEEdouble);
assert(partCount()==1);
uint64_t myexponent, mysignificand;
@@ -3039,10 +2962,8 @@ APFloat::convertDoubleAPFloatToAPInt() const
(mysignificand & 0xfffffffffffffLL))));
}
-APInt
-APFloat::convertFloatAPFloatToAPInt() const
-{
- assert(semantics == (const llvm::fltSemantics*)&IEEEsingle);
+APInt IEEEFloat::convertFloatAPFloatToAPInt() const {
+ assert(semantics == (const llvm::fltSemantics*)&semIEEEsingle);
assert(partCount()==1);
uint32_t myexponent, mysignificand;
@@ -3068,10 +2989,8 @@ APFloat::convertFloatAPFloatToAPInt() const
(mysignificand & 0x7fffff)));
}
-APInt
-APFloat::convertHalfAPFloatToAPInt() const
-{
- assert(semantics == (const llvm::fltSemantics*)&IEEEhalf);
+APInt IEEEFloat::convertHalfAPFloatToAPInt() const {
+ assert(semantics == (const llvm::fltSemantics*)&semIEEEhalf);
assert(partCount()==1);
uint32_t myexponent, mysignificand;
@@ -3101,42 +3020,36 @@ APFloat::convertHalfAPFloatToAPInt() const
// point constant as it would appear in memory. It is not a conversion,
// and treating the result as a normal integer is unlikely to be useful.
-APInt
-APFloat::bitcastToAPInt() const
-{
- if (semantics == (const llvm::fltSemantics*)&IEEEhalf)
+APInt IEEEFloat::bitcastToAPInt() const {
+ if (semantics == (const llvm::fltSemantics*)&semIEEEhalf)
return convertHalfAPFloatToAPInt();
- if (semantics == (const llvm::fltSemantics*)&IEEEsingle)
+ if (semantics == (const llvm::fltSemantics*)&semIEEEsingle)
return convertFloatAPFloatToAPInt();
- if (semantics == (const llvm::fltSemantics*)&IEEEdouble)
+ if (semantics == (const llvm::fltSemantics*)&semIEEEdouble)
return convertDoubleAPFloatToAPInt();
- if (semantics == (const llvm::fltSemantics*)&IEEEquad)
+ if (semantics == (const llvm::fltSemantics*)&semIEEEquad)
return convertQuadrupleAPFloatToAPInt();
- if (semantics == (const llvm::fltSemantics*)&PPCDoubleDouble)
+ if (semantics == (const llvm::fltSemantics *)&semPPCDoubleDoubleImpl)
return convertPPCDoubleDoubleAPFloatToAPInt();
- assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended &&
+ assert(semantics == (const llvm::fltSemantics*)&semX87DoubleExtended &&
"unknown format!");
return convertF80LongDoubleAPFloatToAPInt();
}
-float
-APFloat::convertToFloat() const
-{
- assert(semantics == (const llvm::fltSemantics*)&IEEEsingle &&
+float IEEEFloat::convertToFloat() const {
+ assert(semantics == (const llvm::fltSemantics*)&semIEEEsingle &&
"Float semantics are not IEEEsingle");
APInt api = bitcastToAPInt();
return api.bitsToFloat();
}
-double
-APFloat::convertToDouble() const
-{
- assert(semantics == (const llvm::fltSemantics*)&IEEEdouble &&
+double IEEEFloat::convertToDouble() const {
+ assert(semantics == (const llvm::fltSemantics*)&semIEEEdouble &&
"Float semantics are not IEEEdouble");
APInt api = bitcastToAPInt();
return api.bitsToDouble();
@@ -3149,16 +3062,14 @@ APFloat::convertToDouble() const
/// exponent = 0, integer bit 1 ("pseudodenormal")
/// exponent!=0 nor all 1's, integer bit 0 ("unnormal")
/// At the moment, the first two are treated as NaNs, the second two as Normal.
-void
-APFloat::initFromF80LongDoubleAPInt(const APInt &api)
-{
+void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) {
assert(api.getBitWidth()==80);
uint64_t i1 = api.getRawData()[0];
uint64_t i2 = api.getRawData()[1];
uint64_t myexponent = (i2 & 0x7fff);
uint64_t mysignificand = i1;
- initialize(&APFloat::x87DoubleExtended);
+ initialize(&semX87DoubleExtended);
assert(partCount()==2);
sign = static_cast<unsigned int>(i2>>15);
@@ -3183,9 +3094,7 @@ APFloat::initFromF80LongDoubleAPInt(const APInt &api)
}
}
-void
-APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
-{
+void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) {
assert(api.getBitWidth()==128);
uint64_t i1 = api.getRawData()[0];
uint64_t i2 = api.getRawData()[1];
@@ -3194,14 +3103,14 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
// Get the first double and convert to our format.
initFromDoubleAPInt(APInt(64, i1));
- fs = convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
+ fs = convert(semPPCDoubleDoubleImpl, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
(void)fs;
// Unless we have a special case, add in second double.
if (isFiniteNonZero()) {
- APFloat v(IEEEdouble, APInt(64, i2));
- fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
+ IEEEFloat v(semIEEEdouble, APInt(64, i2));
+ fs = v.convert(semPPCDoubleDoubleImpl, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
(void)fs;
@@ -3209,9 +3118,7 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
}
}
-void
-APFloat::initFromQuadrupleAPInt(const APInt &api)
-{
+void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) {
assert(api.getBitWidth()==128);
uint64_t i1 = api.getRawData()[0];
uint64_t i2 = api.getRawData()[1];
@@ -3219,7 +3126,7 @@ APFloat::initFromQuadrupleAPInt(const APInt &api)
uint64_t mysignificand = i1;
uint64_t mysignificand2 = i2 & 0xffffffffffffLL;
- initialize(&APFloat::IEEEquad);
+ initialize(&semIEEEquad);
assert(partCount()==2);
sign = static_cast<unsigned int>(i2>>63);
@@ -3249,15 +3156,13 @@ APFloat::initFromQuadrupleAPInt(const APInt &api)
}
}
-void
-APFloat::initFromDoubleAPInt(const APInt &api)
-{
+void IEEEFloat::initFromDoubleAPInt(const APInt &api) {
assert(api.getBitWidth()==64);
uint64_t i = *api.getRawData();
uint64_t myexponent = (i >> 52) & 0x7ff;
uint64_t mysignificand = i & 0xfffffffffffffLL;
- initialize(&APFloat::IEEEdouble);
+ initialize(&semIEEEdouble);
assert(partCount()==1);
sign = static_cast<unsigned int>(i>>63);
@@ -3282,15 +3187,13 @@ APFloat::initFromDoubleAPInt(const APInt &api)
}
}
-void
-APFloat::initFromFloatAPInt(const APInt & api)
-{
+void IEEEFloat::initFromFloatAPInt(const APInt &api) {
assert(api.getBitWidth()==32);
uint32_t i = (uint32_t)*api.getRawData();
uint32_t myexponent = (i >> 23) & 0xff;
uint32_t mysignificand = i & 0x7fffff;
- initialize(&APFloat::IEEEsingle);
+ initialize(&semIEEEsingle);
assert(partCount()==1);
sign = i >> 31;
@@ -3315,15 +3218,13 @@ APFloat::initFromFloatAPInt(const APInt & api)
}
}
-void
-APFloat::initFromHalfAPInt(const APInt & api)
-{
+void IEEEFloat::initFromHalfAPInt(const APInt &api) {
assert(api.getBitWidth()==16);
uint32_t i = (uint32_t)*api.getRawData();
uint32_t myexponent = (i >> 10) & 0x1f;
uint32_t mysignificand = i & 0x3ff;
- initialize(&APFloat::IEEEhalf);
+ initialize(&semIEEEhalf);
assert(partCount()==1);
sign = i >> 15;
@@ -3352,53 +3253,26 @@ APFloat::initFromHalfAPInt(const APInt & api)
/// we infer the floating point type from the size of the APInt. The
/// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful
/// when the size is anything else).
-void
-APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api)
-{
- if (Sem == &IEEEhalf)
+void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) {
+ if (Sem == &semIEEEhalf)
return initFromHalfAPInt(api);
- if (Sem == &IEEEsingle)
+ if (Sem == &semIEEEsingle)
return initFromFloatAPInt(api);
- if (Sem == &IEEEdouble)
+ if (Sem == &semIEEEdouble)
return initFromDoubleAPInt(api);
- if (Sem == &x87DoubleExtended)
+ if (Sem == &semX87DoubleExtended)
return initFromF80LongDoubleAPInt(api);
- if (Sem == &IEEEquad)
+ if (Sem == &semIEEEquad)
return initFromQuadrupleAPInt(api);
- if (Sem == &PPCDoubleDouble)
+ if (Sem == &semPPCDoubleDoubleImpl)
return initFromPPCDoubleDoubleAPInt(api);
llvm_unreachable(nullptr);
}
-APFloat
-APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE)
-{
- switch (BitWidth) {
- case 16:
- return APFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth));
- case 32:
- return APFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth));
- case 64:
- return APFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth));
- case 80:
- return APFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth));
- case 128:
- if (isIEEE)
- return APFloat(IEEEquad, APInt::getAllOnesValue(BitWidth));
- return APFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth));
- default:
- llvm_unreachable("Unknown floating bit width");
- }
-}
-
-unsigned APFloat::getSizeInBits(const fltSemantics &Sem) {
- return Sem.sizeInBits;
-}
-
/// Make this number the largest magnitude normal number in the given
/// semantics.
-void APFloat::makeLargest(bool Negative) {
+void IEEEFloat::makeLargest(bool Negative) {
// We want (in interchange format):
// sign = {Negative}
// exponent = 1..10
@@ -3423,7 +3297,7 @@ void APFloat::makeLargest(bool Negative) {
/// Make this number the smallest magnitude denormal number in the given
/// semantics.
-void APFloat::makeSmallest(bool Negative) {
+void IEEEFloat::makeSmallest(bool Negative) {
// We want (in interchange format):
// sign = {Negative}
// exponent = 0..0
@@ -3434,55 +3308,30 @@ void APFloat::makeSmallest(bool Negative) {
APInt::tcSet(significandParts(), 1, partCount());
}
-
-APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) {
- // We want (in interchange format):
- // sign = {Negative}
- // exponent = 1..10
- // significand = 1..1
- APFloat Val(Sem, uninitialized);
- Val.makeLargest(Negative);
- return Val;
-}
-
-APFloat APFloat::getSmallest(const fltSemantics &Sem, bool Negative) {
- // We want (in interchange format):
- // sign = {Negative}
- // exponent = 0..0
- // significand = 0..01
- APFloat Val(Sem, uninitialized);
- Val.makeSmallest(Negative);
- return Val;
-}
-
-APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
- APFloat Val(Sem, uninitialized);
-
+void IEEEFloat::makeSmallestNormalized(bool Negative) {
// We want (in interchange format):
// sign = {Negative}
// exponent = 0..0
// significand = 10..0
- Val.category = fcNormal;
- Val.zeroSignificand();
- Val.sign = Negative;
- Val.exponent = Sem.minExponent;
- Val.significandParts()[partCountForBits(Sem.precision)-1] |=
- (((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth));
-
- return Val;
+ category = fcNormal;
+ zeroSignificand();
+ sign = Negative;
+ exponent = semantics->minExponent;
+ significandParts()[partCountForBits(semantics->precision) - 1] |=
+ (((integerPart)1) << ((semantics->precision - 1) % integerPartWidth));
}
-APFloat::APFloat(const fltSemantics &Sem, const APInt &API) {
+IEEEFloat::IEEEFloat(const fltSemantics &Sem, const APInt &API) {
initFromAPInt(&Sem, API);
}
-APFloat::APFloat(float f) {
- initFromAPInt(&IEEEsingle, APInt::floatToBits(f));
+IEEEFloat::IEEEFloat(float f) {
+ initFromAPInt(&semIEEEsingle, APInt::floatToBits(f));
}
-APFloat::APFloat(double d) {
- initFromAPInt(&IEEEdouble, APInt::doubleToBits(d));
+IEEEFloat::IEEEFloat(double d) {
+ initFromAPInt(&semIEEEdouble, APInt::doubleToBits(d));
}
namespace {
@@ -3569,9 +3418,8 @@ namespace {
}
}
-void APFloat::toString(SmallVectorImpl<char> &Str,
- unsigned FormatPrecision,
- unsigned FormatMaxPadding) const {
+void IEEEFloat::toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
+ unsigned FormatMaxPadding) const {
switch (category) {
case fcInfinity:
if (isNegative())
@@ -3772,7 +3620,7 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
Str.push_back(buffer[NDigits-I-1]);
}
-bool APFloat::getExactInverse(APFloat *inv) const {
+bool IEEEFloat::getExactInverse(IEEEFloat *inv) const {
// Special floats and denormals have no exact inverse.
if (!isFiniteNonZero())
return false;
@@ -3783,7 +3631,7 @@ bool APFloat::getExactInverse(APFloat *inv) const {
return false;
// Get the inverse.
- APFloat reciprocal(*semantics, 1ULL);
+ IEEEFloat reciprocal(*semantics, 1ULL);
if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
return false;
@@ -3801,7 +3649,7 @@ bool APFloat::getExactInverse(APFloat *inv) const {
return true;
}
-bool APFloat::isSignaling() const {
+bool IEEEFloat::isSignaling() const {
if (!isNaN())
return false;
@@ -3814,7 +3662,7 @@ bool APFloat::isSignaling() const {
///
/// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with
/// appropriate sign switching before/after the computation.
-APFloat::opStatus APFloat::next(bool nextDown) {
+IEEEFloat::opStatus IEEEFloat::next(bool nextDown) {
// If we are performing nextDown, swap sign so we have -x.
if (nextDown)
changeSign();
@@ -3930,46 +3778,44 @@ APFloat::opStatus APFloat::next(bool nextDown) {
return result;
}
-void
-APFloat::makeInf(bool Negative) {
+void IEEEFloat::makeInf(bool Negative) {
category = fcInfinity;
sign = Negative;
exponent = semantics->maxExponent + 1;
APInt::tcSet(significandParts(), 0, partCount());
}
-void
-APFloat::makeZero(bool Negative) {
+void IEEEFloat::makeZero(bool Negative) {
category = fcZero;
sign = Negative;
exponent = semantics->minExponent-1;
APInt::tcSet(significandParts(), 0, partCount());
}
-void APFloat::makeQuiet() {
+void IEEEFloat::makeQuiet() {
assert(isNaN());
APInt::tcSetBit(significandParts(), semantics->precision - 2);
}
-int llvm::ilogb(const APFloat &Arg) {
+int ilogb(const IEEEFloat &Arg) {
if (Arg.isNaN())
- return APFloat::IEK_NaN;
+ return IEEEFloat::IEK_NaN;
if (Arg.isZero())
- return APFloat::IEK_Zero;
+ return IEEEFloat::IEK_Zero;
if (Arg.isInfinity())
- return APFloat::IEK_Inf;
+ return IEEEFloat::IEK_Inf;
if (!Arg.isDenormal())
return Arg.exponent;
- APFloat Normalized(Arg);
+ IEEEFloat Normalized(Arg);
int SignificandBits = Arg.getSemantics().precision - 1;
Normalized.exponent += SignificandBits;
- Normalized.normalize(APFloat::rmNearestTiesToEven, lfExactlyZero);
+ Normalized.normalize(IEEEFloat::rmNearestTiesToEven, lfExactlyZero);
return Normalized.exponent - SignificandBits;
}
-APFloat llvm::scalbn(APFloat X, int Exp, APFloat::roundingMode RoundingMode) {
+IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode RoundingMode) {
auto MaxExp = X.getSemantics().maxExponent;
auto MinExp = X.getSemantics().minExponent;
@@ -3990,21 +3836,359 @@ APFloat llvm::scalbn(APFloat X, int Exp, APFloat::roundingMode RoundingMode) {
return X;
}
-APFloat llvm::frexp(const APFloat &Val, int &Exp, APFloat::roundingMode RM) {
+IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM) {
Exp = ilogb(Val);
// Quiet signalling nans.
- if (Exp == APFloat::IEK_NaN) {
- APFloat Quiet(Val);
+ if (Exp == IEEEFloat::IEK_NaN) {
+ IEEEFloat Quiet(Val);
Quiet.makeQuiet();
return Quiet;
}
- if (Exp == APFloat::IEK_Inf)
+ if (Exp == IEEEFloat::IEK_Inf)
return Val;
// 1 is added because frexp is defined to return a normalized fraction in
// +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0).
- Exp = Exp == APFloat::IEK_Zero ? 0 : Exp + 1;
+ Exp = Exp == IEEEFloat::IEK_Zero ? 0 : Exp + 1;
return scalbn(Val, -Exp, RM);
}
+
+DoubleAPFloat::DoubleAPFloat(const fltSemantics &S)
+ : Semantics(&S), Floats(new APFloat[2]{APFloat(semPPCDoubleDoubleImpl),
+ APFloat(semIEEEdouble)}) {
+ assert(Semantics == &semPPCDoubleDouble);
+}
+
+DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, uninitializedTag)
+ : Semantics(&S),
+ Floats(new APFloat[2]{APFloat(semPPCDoubleDoubleImpl, uninitialized),
+ APFloat(semIEEEdouble, uninitialized)}) {
+ assert(Semantics == &semPPCDoubleDouble);
+}
+
+DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, integerPart I)
+ : Semantics(&S), Floats(new APFloat[2]{APFloat(semPPCDoubleDoubleImpl, I),
+ APFloat(semIEEEdouble)}) {
+ assert(Semantics == &semPPCDoubleDouble);
+}
+
+DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, const APInt &I)
+ : Semantics(&S), Floats(new APFloat[2]{
+ APFloat(semPPCDoubleDoubleImpl, I),
+ APFloat(semIEEEdouble, APInt(64, I.getRawData()[1]))}) {
+ assert(Semantics == &semPPCDoubleDouble);
+}
+
+DoubleAPFloat::DoubleAPFloat(const fltSemantics &S, APFloat &&First,
+ APFloat &&Second)
+ : Semantics(&S),
+ Floats(new APFloat[2]{std::move(First), std::move(Second)}) {
+ assert(Semantics == &semPPCDoubleDouble);
+ // TODO Check for First == &IEEEdouble once the transition is done.
+ assert(&Floats[0].getSemantics() == &semPPCDoubleDoubleImpl ||
+ &Floats[0].getSemantics() == &semIEEEdouble);
+ assert(&Floats[1].getSemantics() == &semIEEEdouble);
+}
+
+DoubleAPFloat::DoubleAPFloat(const DoubleAPFloat &RHS)
+ : Semantics(RHS.Semantics),
+ Floats(RHS.Floats ? new APFloat[2]{APFloat(RHS.Floats[0]),
+ APFloat(RHS.Floats[1])}
+ : nullptr) {
+ assert(Semantics == &semPPCDoubleDouble);
+}
+
+DoubleAPFloat::DoubleAPFloat(DoubleAPFloat &&RHS)
+ : Semantics(RHS.Semantics), Floats(std::move(RHS.Floats)) {
+ RHS.Semantics = &semBogus;
+ assert(Semantics == &semPPCDoubleDouble);
+}
+
+DoubleAPFloat &DoubleAPFloat::operator=(const DoubleAPFloat &RHS) {
+ if (Semantics == RHS.Semantics && RHS.Floats) {
+ Floats[0] = RHS.Floats[0];
+ Floats[1] = RHS.Floats[1];
+ } else if (this != &RHS) {
+ this->~DoubleAPFloat();
+ new (this) DoubleAPFloat(RHS);
+ }
+ return *this;
+}
+
+// "Software for Doubled-Precision Floating-Point Computations",
+// by Seppo Linnainmaa, ACM TOMS vol 7 no 3, September 1981, pages 272-283.
+APFloat::opStatus DoubleAPFloat::addImpl(const APFloat &a, const APFloat &aa,
+ const APFloat &c, const APFloat &cc,
+ roundingMode RM) {
+ int Status = opOK;
+ APFloat z = a;
+ Status |= z.add(c, RM);
+ if (!z.isFinite()) {
+ if (!z.isInfinity()) {
+ Floats[0] = std::move(z);
+ Floats[1].makeZero(false);
+ return (opStatus)Status;
+ }
+ Status = opOK;
+ auto AComparedToC = a.compareAbsoluteValue(c);
+ z = cc;
+ Status |= z.add(aa, RM);
+ if (AComparedToC == APFloat::cmpGreaterThan) {
+ // z = cc + aa + c + a;
+ Status |= z.add(c, RM);
+ Status |= z.add(a, RM);
+ } else {
+ // z = cc + aa + a + c;
+ Status |= z.add(a, RM);
+ Status |= z.add(c, RM);
+ }
+ if (!z.isFinite()) {
+ Floats[0] = std::move(z);
+ Floats[1].makeZero(false);
+ return (opStatus)Status;
+ }
+ Floats[0] = z;
+ APFloat zz = aa;
+ Status |= zz.add(cc, RM);
+ if (AComparedToC == APFloat::cmpGreaterThan) {
+ // Floats[1] = a - z + c + zz;
+ Floats[1] = a;
+ Status |= Floats[1].subtract(z, RM);
+ Status |= Floats[1].add(c, RM);
+ Status |= Floats[1].add(zz, RM);
+ } else {
+ // Floats[1] = c - z + a + zz;
+ Floats[1] = c;
+ Status |= Floats[1].subtract(z, RM);
+ Status |= Floats[1].add(a, RM);
+ Status |= Floats[1].add(zz, RM);
+ }
+ } else {
+ // q = a - z;
+ APFloat q = a;
+ Status |= q.subtract(z, RM);
+
+ // zz = q + c + (a - (q + z)) + aa + cc;
+ // Compute a - (q + z) as -((q + z) - a) to avoid temporary copies.
+ auto zz = q;
+ Status |= zz.add(c, RM);
+ Status |= q.add(z, RM);
+ Status |= q.subtract(a, RM);
+ q.changeSign();
+ Status |= zz.add(q, RM);
+ Status |= zz.add(aa, RM);
+ Status |= zz.add(cc, RM);
+ if (zz.isZero() && !zz.isNegative()) {
+ Floats[0] = std::move(z);
+ Floats[1].makeZero(false);
+ return opOK;
+ }
+ Floats[0] = z;
+ Status |= Floats[0].add(zz, RM);
+ if (!Floats[0].isFinite()) {
+ Floats[1].makeZero(false);
+ return (opStatus)Status;
+ }
+ Floats[1] = std::move(z);
+ Status |= Floats[1].subtract(Floats[0], RM);
+ Status |= Floats[1].add(zz, RM);
+ }
+ return (opStatus)Status;
+}
+
+APFloat::opStatus DoubleAPFloat::addWithSpecial(const DoubleAPFloat &LHS,
+ const DoubleAPFloat &RHS,
+ DoubleAPFloat &Out,
+ roundingMode RM) {
+ if (LHS.getCategory() == fcNaN) {
+ Out = LHS;
+ return opOK;
+ }
+ if (RHS.getCategory() == fcNaN) {
+ Out = RHS;
+ return opOK;
+ }
+ if (LHS.getCategory() == fcZero) {
+ Out = RHS;
+ return opOK;
+ }
+ if (RHS.getCategory() == fcZero) {
+ Out = LHS;
+ return opOK;
+ }
+ if (LHS.getCategory() == fcInfinity && RHS.getCategory() == fcInfinity &&
+ LHS.isNegative() != RHS.isNegative()) {
+ Out.makeNaN(false, Out.isNegative(), nullptr);
+ return opInvalidOp;
+ }
+ if (LHS.getCategory() == fcInfinity) {
+ Out = LHS;
+ return opOK;
+ }
+ if (RHS.getCategory() == fcInfinity) {
+ Out = RHS;
+ return opOK;
+ }
+ assert(LHS.getCategory() == fcNormal && RHS.getCategory() == fcNormal);
+
+ // These conversions will go away once PPCDoubleDoubleImpl goes away.
+ // (PPCDoubleDoubleImpl, IEEEDouble) -> (IEEEDouble, IEEEDouble)
+ APFloat A(semIEEEdouble,
+ APInt(64, LHS.Floats[0].bitcastToAPInt().getRawData()[0])),
+ AA(LHS.Floats[1]),
+ C(semIEEEdouble, APInt(64, RHS.Floats[0].bitcastToAPInt().getRawData()[0])),
+ CC(RHS.Floats[1]);
+ assert(&AA.getSemantics() == &semIEEEdouble);
+ assert(&CC.getSemantics() == &semIEEEdouble);
+ Out.Floats[0] = APFloat(semIEEEdouble);
+ assert(&Out.Floats[1].getSemantics() == &semIEEEdouble);
+
+ auto Ret = Out.addImpl(A, AA, C, CC, RM);
+
+ // (IEEEDouble, IEEEDouble) -> (PPCDoubleDoubleImpl, IEEEDouble)
+ uint64_t Buffer[] = {Out.Floats[0].bitcastToAPInt().getRawData()[0],
+ Out.Floats[1].bitcastToAPInt().getRawData()[0]};
+ Out.Floats[0] = APFloat(semPPCDoubleDoubleImpl, APInt(128, 2, Buffer));
+ return Ret;
+}
+
+APFloat::opStatus DoubleAPFloat::add(const DoubleAPFloat &RHS,
+ roundingMode RM) {
+ return addWithSpecial(*this, RHS, *this, RM);
+}
+
+APFloat::opStatus DoubleAPFloat::subtract(const DoubleAPFloat &RHS,
+ roundingMode RM) {
+ changeSign();
+ auto Ret = add(RHS, RM);
+ changeSign();
+ return Ret;
+}
+
+void DoubleAPFloat::changeSign() {
+ Floats[0].changeSign();
+ Floats[1].changeSign();
+}
+
+APFloat::cmpResult
+DoubleAPFloat::compareAbsoluteValue(const DoubleAPFloat &RHS) const {
+ auto Result = Floats[0].compareAbsoluteValue(RHS.Floats[0]);
+ if (Result != cmpEqual)
+ return Result;
+ Result = Floats[1].compareAbsoluteValue(RHS.Floats[1]);
+ if (Result == cmpLessThan || Result == cmpGreaterThan) {
+ auto Against = Floats[0].isNegative() ^ Floats[1].isNegative();
+ auto RHSAgainst = RHS.Floats[0].isNegative() ^ RHS.Floats[1].isNegative();
+ if (Against && !RHSAgainst)
+ return cmpLessThan;
+ if (!Against && RHSAgainst)
+ return cmpGreaterThan;
+ if (!Against && !RHSAgainst)
+ return Result;
+ if (Against && RHSAgainst)
+ return (cmpResult)(cmpLessThan + cmpGreaterThan - Result);
+ }
+ return Result;
+}
+
+APFloat::fltCategory DoubleAPFloat::getCategory() const {
+ return Floats[0].getCategory();
+}
+
+bool DoubleAPFloat::isNegative() const { return Floats[0].isNegative(); }
+
+void DoubleAPFloat::makeInf(bool Neg) {
+ Floats[0].makeInf(Neg);
+ Floats[1].makeZero(false);
+}
+
+void DoubleAPFloat::makeNaN(bool SNaN, bool Neg, const APInt *fill) {
+ Floats[0].makeNaN(SNaN, Neg, fill);
+ Floats[1].makeZero(false);
+}
+
+} // End detail namespace
+
+APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) {
+ if (usesLayout<IEEEFloat>(Semantics)) {
+ new (&IEEE) IEEEFloat(std::move(F));
+ return;
+ }
+ if (usesLayout<DoubleAPFloat>(Semantics)) {
+ new (&Double)
+ DoubleAPFloat(Semantics, APFloat(std::move(F), F.getSemantics()),
+ APFloat(semIEEEdouble));
+ return;
+ }
+ llvm_unreachable("Unexpected semantics");
+}
+
+APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) {
+ return getIEEE().convertFromString(Str, RM);
+}
+
+hash_code hash_value(const APFloat &Arg) { return hash_value(Arg.getIEEE()); }
+
+APFloat::APFloat(const fltSemantics &Semantics, StringRef S)
+ : APFloat(Semantics) {
+ convertFromString(S, rmNearestTiesToEven);
+}
+
+APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics,
+ roundingMode RM, bool *losesInfo) {
+ if (&getSemantics() == &ToSemantics)
+ return opOK;
+ if (usesLayout<IEEEFloat>(getSemantics()) &&
+ usesLayout<IEEEFloat>(ToSemantics))
+ return U.IEEE.convert(ToSemantics, RM, losesInfo);
+ if (usesLayout<IEEEFloat>(getSemantics()) &&
+ usesLayout<DoubleAPFloat>(ToSemantics)) {
+ assert(&ToSemantics == &semPPCDoubleDouble);
+ auto Ret = U.IEEE.convert(semPPCDoubleDoubleImpl, RM, losesInfo);
+ *this = APFloat(DoubleAPFloat(semPPCDoubleDouble, std::move(*this),
+ APFloat(semIEEEdouble)),
+ ToSemantics);
+ return Ret;
+ }
+ if (usesLayout<DoubleAPFloat>(getSemantics()) &&
+ usesLayout<IEEEFloat>(ToSemantics)) {
+ auto Ret = getIEEE().convert(ToSemantics, RM, losesInfo);
+ *this = APFloat(std::move(getIEEE()), ToSemantics);
+ return Ret;
+ }
+ llvm_unreachable("Unexpected semantics");
+}
+
+APFloat APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) {
+ if (isIEEE) {
+ switch (BitWidth) {
+ case 16:
+ return APFloat(semIEEEhalf, APInt::getAllOnesValue(BitWidth));
+ case 32:
+ return APFloat(semIEEEsingle, APInt::getAllOnesValue(BitWidth));
+ case 64:
+ return APFloat(semIEEEdouble, APInt::getAllOnesValue(BitWidth));
+ case 80:
+ return APFloat(semX87DoubleExtended, APInt::getAllOnesValue(BitWidth));
+ case 128:
+ return APFloat(semIEEEquad, APInt::getAllOnesValue(BitWidth));
+ default:
+ llvm_unreachable("Unknown floating bit width");
+ }
+ } else {
+ assert(BitWidth == 128);
+ return APFloat(semPPCDoubleDouble, APInt::getAllOnesValue(BitWidth));
+ }
+}
+
+void APFloat::print(raw_ostream &OS) const {
+ SmallVector<char, 16> Buffer;
+ toString(Buffer);
+ OS << Buffer << "\n";
+}
+
+void APFloat::dump() const { print(dbgs()); }
+
+} // End llvm namespace
diff --git a/contrib/llvm/lib/Support/APInt.cpp b/contrib/llvm/lib/Support/APInt.cpp
index 66eee99..fb8b451 100644
--- a/contrib/llvm/lib/Support/APInt.cpp
+++ b/contrib/llvm/lib/Support/APInt.cpp
@@ -22,10 +22,10 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include <climits>
#include <cmath>
#include <cstdlib>
#include <cstring>
-#include <limits>
using namespace llvm;
#define DEBUG_TYPE "apint"
@@ -205,7 +205,7 @@ APInt& APInt::operator++() {
/// This function subtracts a single "digit" (64-bit word), y, from
/// the multi-digit integer array, x[], propagating the borrowed 1 value until
-/// no further borrowing is neeeded or it runs out of "digits" in x. The result
+/// no further borrowing is needed or it runs out of "digits" in x. The result
/// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted.
/// In other words, if y > x then this function returns 1, otherwise 0.
/// @returns the borrow out of the subtraction
@@ -260,6 +260,14 @@ APInt& APInt::operator+=(const APInt& RHS) {
return clearUnusedBits();
}
+APInt& APInt::operator+=(uint64_t RHS) {
+ if (isSingleWord())
+ VAL += RHS;
+ else
+ add_1(pVal, pVal, getNumWords(), RHS);
+ return clearUnusedBits();
+}
+
/// Subtracts the integer array y from the integer array x
/// @returns returns the borrow out.
/// @brief Generalized subtraction of 64-bit integer arrays.
@@ -286,6 +294,14 @@ APInt& APInt::operator-=(const APInt& RHS) {
return clearUnusedBits();
}
+APInt& APInt::operator-=(uint64_t RHS) {
+ if (isSingleWord())
+ VAL -= RHS;
+ else
+ sub_1(pVal, getNumWords(), RHS);
+ return clearUnusedBits();
+}
+
/// Multiplies an integer array, x, by a uint64_t integer and places the result
/// into dest.
/// @returns the carry out of the multiplication.
@@ -470,44 +486,6 @@ APInt APInt::operator*(const APInt& RHS) const {
return Result;
}
-APInt APInt::operator+(const APInt& RHS) const {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
- return APInt(BitWidth, VAL + RHS.VAL);
- APInt Result(BitWidth, 0);
- add(Result.pVal, this->pVal, RHS.pVal, getNumWords());
- Result.clearUnusedBits();
- return Result;
-}
-
-APInt APInt::operator+(uint64_t RHS) const {
- if (isSingleWord())
- return APInt(BitWidth, VAL + RHS);
- APInt Result(*this);
- add_1(Result.pVal, Result.pVal, getNumWords(), RHS);
- Result.clearUnusedBits();
- return Result;
-}
-
-APInt APInt::operator-(const APInt& RHS) const {
- assert(BitWidth == RHS.BitWidth && "Bit widths must be the same");
- if (isSingleWord())
- return APInt(BitWidth, VAL - RHS.VAL);
- APInt Result(BitWidth, 0);
- sub(Result.pVal, this->pVal, RHS.pVal, getNumWords());
- Result.clearUnusedBits();
- return Result;
-}
-
-APInt APInt::operator-(uint64_t RHS) const {
- if (isSingleWord())
- return APInt(BitWidth, VAL - RHS);
- APInt Result(*this);
- sub_1(Result.pVal, getNumWords(), RHS);
- Result.clearUnusedBits();
- return Result;
-}
-
bool APInt::EqualSlowCase(const APInt& RHS) const {
return std::equal(pVal, pVal + getNumWords(), RHS.pVal);
}
@@ -1064,11 +1042,7 @@ APInt APInt::ashr(unsigned shiftAmt) const {
if (isSingleWord()) {
if (shiftAmt == BitWidth)
return APInt(BitWidth, 0); // undefined
- else {
- unsigned SignBit = APINT_BITS_PER_WORD - BitWidth;
- return APInt(BitWidth,
- (((int64_t(VAL) << SignBit) >> SignBit) >> shiftAmt));
- }
+ return APInt(BitWidth, SignExtend64(VAL, BitWidth) >> shiftAmt);
}
// If all the bits were shifted out, the result is, technically, undefined.
@@ -1521,7 +1495,7 @@ static void KnuthDiv(unsigned *u, unsigned *v, unsigned *q, unsigned* r,
assert(n>1 && "n must be > 1");
// b denotes the base of the number system. In our case b is 2^32.
- LLVM_CONSTEXPR uint64_t b = uint64_t(1) << 32;
+ const uint64_t b = uint64_t(1) << 32;
DEBUG(dbgs() << "KnuthDiv: m=" << m << " n=" << n << '\n');
DEBUG(dbgs() << "KnuthDiv: original:");
diff --git a/contrib/llvm/lib/Support/ARMBuildAttrs.cpp b/contrib/llvm/lib/Support/ARMBuildAttrs.cpp
index 6d34f76..134ef8b 100644
--- a/contrib/llvm/lib/Support/ARMBuildAttrs.cpp
+++ b/contrib/llvm/lib/Support/ARMBuildAttrs.cpp
@@ -15,7 +15,7 @@ using namespace llvm;
namespace {
const struct {
ARMBuildAttrs::AttrType Attr;
- const char *TagName;
+ StringRef TagName;
} ARMAttributeTags[] = {
{ ARMBuildAttrs::File, "Tag_File" },
{ ARMBuildAttrs::Section, "Tag_Section" },
@@ -78,17 +78,23 @@ StringRef AttrTypeAsString(unsigned Attr, bool HasTagPrefix) {
StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix) {
for (unsigned TI = 0, TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags);
TI != TE; ++TI)
- if (ARMAttributeTags[TI].Attr == Attr)
- return ARMAttributeTags[TI].TagName + (HasTagPrefix ? 0 : 4);
+ if (ARMAttributeTags[TI].Attr == Attr) {
+ auto TagName = ARMAttributeTags[TI].TagName;
+ return HasTagPrefix ? TagName : TagName.drop_front(4);
+ }
return "";
}
int AttrTypeFromString(StringRef Tag) {
bool HasTagPrefix = Tag.startswith("Tag_");
- for (unsigned TI = 0, TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags);
- TI != TE; ++TI)
- if (StringRef(ARMAttributeTags[TI].TagName + (HasTagPrefix ? 0 : 4)) == Tag)
+ for (unsigned TI = 0,
+ TE = sizeof(ARMAttributeTags) / sizeof(*ARMAttributeTags);
+ TI != TE; ++TI) {
+ auto TagName = ARMAttributeTags[TI].TagName;
+ if (TagName.drop_front(HasTagPrefix ? 0 : 4) == Tag) {
return ARMAttributeTags[TI].Attr;
+ }
+ }
return -1;
}
}
diff --git a/contrib/llvm/lib/Support/CachePruning.cpp b/contrib/llvm/lib/Support/CachePruning.cpp
index bd42bef..3831625 100644
--- a/contrib/llvm/lib/Support/CachePruning.cpp
+++ b/contrib/llvm/lib/Support/CachePruning.cpp
@@ -22,6 +22,7 @@
#define DEBUG_TYPE "cache-pruning"
#include <set>
+#include <system_error>
using namespace llvm;
@@ -34,6 +35,8 @@ static void writeTimestampFile(StringRef TimestampFile) {
/// Prune the cache of files that haven't been accessed in a long time.
bool CachePruning::prune() {
+ using namespace std::chrono;
+
if (Path.empty())
return false;
@@ -44,7 +47,7 @@ bool CachePruning::prune() {
if (!isPathDir)
return false;
- if (Expiration == 0 && PercentageOfAvailableSpace == 0) {
+ if (Expiration == seconds(0) && PercentageOfAvailableSpace == 0) {
DEBUG(dbgs() << "No pruning settings set, exit early\n");
// Nothing will be pruned, early exit
return false;
@@ -54,7 +57,7 @@ bool CachePruning::prune() {
SmallString<128> TimestampFile(Path);
sys::path::append(TimestampFile, "llvmcache.timestamp");
sys::fs::file_status FileStatus;
- sys::TimeValue CurrentTime = sys::TimeValue::now();
+ const auto CurrentTime = system_clock::now();
if (auto EC = sys::fs::status(TimestampFile, FileStatus)) {
if (EC == errc::no_such_file_or_directory) {
// If the timestamp file wasn't there, create one now.
@@ -64,14 +67,14 @@ bool CachePruning::prune() {
return false;
}
} else {
- if (Interval) {
+ if (Interval == seconds(0)) {
// Check whether the time stamp is older than our pruning interval.
// If not, do nothing.
- sys::TimeValue TimeStampModTime = FileStatus.getLastModificationTime();
- auto TimeInterval = sys::TimeValue(sys::TimeValue::SecondsType(Interval));
+ const auto TimeStampModTime = FileStatus.getLastModificationTime();
auto TimeStampAge = CurrentTime - TimeStampModTime;
- if (TimeStampAge <= TimeInterval) {
- DEBUG(dbgs() << "Timestamp file too recent (" << TimeStampAge.seconds()
+ if (TimeStampAge <= Interval) {
+ DEBUG(dbgs() << "Timestamp file too recent ("
+ << duration_cast<seconds>(TimeStampAge).count()
<< "s old), do not prune.\n");
return false;
}
@@ -102,7 +105,6 @@ bool CachePruning::prune() {
std::error_code EC;
SmallString<128> CachePathNative;
sys::path::native(Path, CachePathNative);
- auto TimeExpiration = sys::TimeValue(sys::TimeValue::SecondsType(Expiration));
// Walk all of the files within this directory.
for (sys::fs::directory_iterator File(CachePathNative, EC), FileEnd;
File != FileEnd && !EC; File.increment(EC)) {
@@ -118,11 +120,11 @@ bool CachePruning::prune() {
}
// If the file hasn't been used recently enough, delete it
- sys::TimeValue FileAccessTime = FileStatus.getLastAccessedTime();
+ const auto FileAccessTime = FileStatus.getLastAccessedTime();
auto FileAge = CurrentTime - FileAccessTime;
- if (FileAge > TimeExpiration) {
- DEBUG(dbgs() << "Remove " << File->path() << " (" << FileAge.seconds()
- << "s old)\n");
+ if (FileAge > Expiration) {
+ DEBUG(dbgs() << "Remove " << File->path() << " ("
+ << duration_cast<seconds>(FileAge).count() << "s old)\n");
sys::fs::remove(File->path());
continue;
}
diff --git a/contrib/llvm/lib/Support/Chrono.cpp b/contrib/llvm/lib/Support/Chrono.cpp
new file mode 100644
index 0000000..cdadbd8
--- /dev/null
+++ b/contrib/llvm/lib/Support/Chrono.cpp
@@ -0,0 +1,47 @@
+//===- Support/Chrono.cpp - Utilities for Timing Manipulation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Chrono.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+using namespace sys;
+
+static inline struct tm getStructTM(TimePoint<> TP) {
+ struct tm Storage;
+ std::time_t OurTime = toTimeT(TP);
+
+#if defined(LLVM_ON_UNIX)
+ struct tm *LT = ::localtime_r(&OurTime, &Storage);
+ assert(LT);
+ (void)LT;
+#endif
+#if defined(LLVM_ON_WIN32)
+ int Error = ::localtime_s(&Storage, &OurTime);
+ assert(!Error);
+ (void)Error;
+#endif
+
+ return Storage;
+}
+
+raw_ostream &operator<<(raw_ostream &OS, TimePoint<> TP) {
+ struct tm LT = getStructTM(TP);
+ char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")];
+ strftime(Buffer, sizeof(Buffer), "%Y-%m-%d %H:%M:%S", &LT);
+ return OS << Buffer << '.'
+ << format("%.9lu",
+ long((TP.time_since_epoch() % std::chrono::seconds(1))
+ .count()));
+}
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/CommandLine.cpp b/contrib/llvm/lib/Support/CommandLine.cpp
index a5d2ba2..3889902 100644
--- a/contrib/llvm/lib/Support/CommandLine.cpp
+++ b/contrib/llvm/lib/Support/CommandLine.cpp
@@ -20,6 +20,7 @@
#include "llvm-c/Support.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
@@ -29,10 +30,12 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Process.h"
#include "llvm/Support/StringSaver.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
@@ -42,6 +45,17 @@ using namespace cl;
#define DEBUG_TYPE "commandline"
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+namespace llvm {
+// If LLVM_ENABLE_ABI_BREAKING_CHECKS is set the flag -mllvm -reverse-iterate
+// can be used to toggle forward/reverse iteration of unordered containers.
+// This will help uncover differences in codegen caused due to undefined
+// iteration order.
+static cl::opt<bool, true> ReverseIteration("reverse-iterate",
+ cl::location(ReverseIterate<bool>::value));
+}
+#endif
+
//===----------------------------------------------------------------------===//
// Template instantiations and anchors.
//
@@ -90,10 +104,10 @@ public:
// Globals for name and overview of program. Program name is not a string to
// avoid static ctor/dtor issues.
std::string ProgramName;
- const char *ProgramOverview;
+ StringRef ProgramOverview;
// This collects additional help to be printed.
- std::vector<const char *> MoreHelp;
+ std::vector<StringRef> MoreHelp;
// This collects the different option categories that have been registered.
SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories;
@@ -101,7 +115,7 @@ public:
// This collects the different subcommands that have been registered.
SmallPtrSet<SubCommand *, 4> RegisteredSubCommands;
- CommandLineParser() : ProgramOverview(nullptr), ActiveSubCommand(nullptr) {
+ CommandLineParser() : ActiveSubCommand(nullptr) {
registerSubCommand(&*TopLevelSubCommand);
registerSubCommand(&*AllSubCommands);
}
@@ -109,9 +123,9 @@ public:
void ResetAllOptionOccurrences();
bool ParseCommandLineOptions(int argc, const char *const *argv,
- const char *Overview, bool IgnoreErrors);
+ StringRef Overview, bool IgnoreErrors);
- void addLiteralOption(Option &Opt, SubCommand *SC, const char *Name) {
+ void addLiteralOption(Option &Opt, SubCommand *SC, StringRef Name) {
if (Opt.hasArgStr())
return;
if (!SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) {
@@ -131,7 +145,7 @@ public:
}
}
- void addLiteralOption(Option &Opt, const char *Name) {
+ void addLiteralOption(Option &Opt, StringRef Name) {
if (Opt.Subs.empty())
addLiteralOption(Opt, &*TopLevelSubCommand, Name);
else {
@@ -283,7 +297,7 @@ public:
void registerSubCommand(SubCommand *sub) {
assert(count_if(RegisteredSubCommands,
[sub](const SubCommand *Sub) {
- return (sub->getName() != nullptr) &&
+ return (!sub->getName().empty()) &&
(Sub->getName() == sub->getName());
}) == 0 &&
"Duplicate subcommands");
@@ -298,7 +312,7 @@ public:
O->hasArgStr())
addOption(O, sub);
else
- addLiteralOption(*O, sub, E.first().str().c_str());
+ addLiteralOption(*O, sub, E.first());
}
}
}
@@ -307,10 +321,16 @@ public:
RegisteredSubCommands.erase(sub);
}
+ iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator>
+ getRegisteredSubcommands() {
+ return make_range(RegisteredSubCommands.begin(),
+ RegisteredSubCommands.end());
+ }
+
void reset() {
ActiveSubCommand = nullptr;
ProgramName.clear();
- ProgramOverview = nullptr;
+ ProgramOverview = StringRef();
MoreHelp.clear();
RegisteredOptionCategories.clear();
@@ -328,18 +348,18 @@ private:
SubCommand *ActiveSubCommand;
Option *LookupOption(SubCommand &Sub, StringRef &Arg, StringRef &Value);
- SubCommand *LookupSubCommand(const char *Name);
+ SubCommand *LookupSubCommand(StringRef Name);
};
} // namespace
static ManagedStatic<CommandLineParser> GlobalParser;
-void cl::AddLiteralOption(Option &O, const char *Name) {
+void cl::AddLiteralOption(Option &O, StringRef Name) {
GlobalParser->addLiteralOption(O, Name);
}
-extrahelp::extrahelp(const char *Help) : morehelp(Help) {
+extrahelp::extrahelp(StringRef Help) : morehelp(Help) {
GlobalParser->MoreHelp.push_back(Help);
}
@@ -353,6 +373,7 @@ void Option::removeArgument() { GlobalParser->removeOption(this); }
void Option::setArgStr(StringRef S) {
if (FullyInitialized)
GlobalParser->updateArgStr(this, S);
+ assert((S.empty() || S[0] != '-') && "Option can't start with '-");
ArgStr = S;
}
@@ -426,13 +447,13 @@ Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg,
return I->second;
}
-SubCommand *CommandLineParser::LookupSubCommand(const char *Name) {
- if (Name == nullptr)
+SubCommand *CommandLineParser::LookupSubCommand(StringRef Name) {
+ if (Name.empty())
return &*TopLevelSubCommand;
for (auto S : RegisteredSubCommands) {
if (S == &*AllSubCommands)
continue;
- if (S->getName() == nullptr)
+ if (S->getName().empty())
continue;
if (StringRef(S->getName()) == StringRef(Name))
@@ -505,7 +526,6 @@ static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos,
return true;
// Erase the portion before the comma, AND the comma.
Val = Val.substr(Pos + 1);
- Value.substr(Pos + 1); // Increment the original value pointer as well.
// Check for another comma.
Pos = Val.find(',');
}
@@ -533,7 +553,7 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName,
return Handler->error("requires a value!");
// Steal the next argument, like for '-o filename'
assert(argv && "null check");
- Value = argv[++i];
+ Value = StringRef(argv[++i]);
}
break;
case ValueDisallowed:
@@ -567,7 +587,7 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName,
if (i + 1 >= argc)
return Handler->error("not enough values!");
assert(argv && "null check");
- Value = argv[++i];
+ Value = StringRef(argv[++i]);
if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg))
return true;
@@ -725,7 +745,7 @@ void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,
// End the token if this is whitespace.
if (isWhitespace(Src[I])) {
if (!Token.empty())
- NewArgv.push_back(Saver.save(Token.c_str()));
+ NewArgv.push_back(Saver.save(StringRef(Token)).data());
Token.clear();
continue;
}
@@ -736,7 +756,7 @@ void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,
// Append the last token after hitting EOF with no whitespace.
if (!Token.empty())
- NewArgv.push_back(Saver.save(Token.c_str()));
+ NewArgv.push_back(Saver.save(StringRef(Token)).data());
// Mark the end of response files
if (MarkEOLs)
NewArgv.push_back(nullptr);
@@ -817,7 +837,7 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver,
if (State == UNQUOTED) {
// Whitespace means the end of the token.
if (isWhitespace(Src[I])) {
- NewArgv.push_back(Saver.save(Token.c_str()));
+ NewArgv.push_back(Saver.save(StringRef(Token)).data());
Token.clear();
State = INIT;
// Mark the end of lines in response files
@@ -852,7 +872,7 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver,
}
// Append the last token after hitting EOF with no whitespace.
if (!Token.empty())
- NewArgv.push_back(Saver.save(Token.c_str()));
+ NewArgv.push_back(Saver.save(StringRef(Token)).data());
// Mark the end of response files
if (MarkEOLs)
NewArgv.push_back(nullptr);
@@ -864,10 +884,10 @@ static bool hasUTF8ByteOrderMark(ArrayRef<char> S) {
return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');
}
-static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
+static bool ExpandResponseFile(StringRef FName, StringSaver &Saver,
TokenizerCallback Tokenizer,
SmallVectorImpl<const char *> &NewArgv,
- bool MarkEOLs = false) {
+ bool MarkEOLs, bool RelativeNames) {
ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =
MemoryBuffer::getFile(FName);
if (!MemBufOrErr)
@@ -892,6 +912,30 @@ static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
// Tokenize the contents into NewArgv.
Tokenizer(Str, Saver, NewArgv, MarkEOLs);
+ // If names of nested response files should be resolved relative to including
+ // file, replace the included response file names with their full paths
+ // obtained by required resolution.
+ if (RelativeNames)
+ for (unsigned I = 0; I < NewArgv.size(); ++I)
+ if (NewArgv[I]) {
+ StringRef Arg = NewArgv[I];
+ if (Arg.front() == '@') {
+ StringRef FileName = Arg.drop_front();
+ if (llvm::sys::path::is_relative(FileName)) {
+ SmallString<128> ResponseFile;
+ ResponseFile.append(1, '@');
+ if (llvm::sys::path::is_relative(FName)) {
+ SmallString<128> curr_dir;
+ llvm::sys::fs::current_path(curr_dir);
+ ResponseFile.append(curr_dir.str());
+ }
+ llvm::sys::path::append(
+ ResponseFile, llvm::sys::path::parent_path(FName), FileName);
+ NewArgv[I] = Saver.save(ResponseFile.c_str()).data();
+ }
+ }
+ }
+
return true;
}
@@ -899,7 +943,7 @@ static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
/// StringSaver and tokenization strategy.
bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
SmallVectorImpl<const char *> &Argv,
- bool MarkEOLs) {
+ bool MarkEOLs, bool RelativeNames) {
unsigned RspFiles = 0;
bool AllExpanded = true;
@@ -923,11 +967,9 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
// Replace this response file argument with the tokenization of its
// contents. Nested response files are expanded in subsequent iterations.
- // FIXME: If a nested response file uses a relative path, is it relative to
- // the cwd of the process or the response file?
SmallVector<const char *, 0> ExpandedArgv;
if (!ExpandResponseFile(Arg + 1, Saver, Tokenizer, ExpandedArgv,
- MarkEOLs)) {
+ MarkEOLs, RelativeNames)) {
// We couldn't read this file, so we leave it in the argument stream and
// move on.
AllExpanded = false;
@@ -952,45 +994,26 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
assert(envVar && "Environment variable name missing");
// Get the environment variable they want us to parse options out of.
-#ifdef _WIN32
- std::wstring wenvVar;
- if (!llvm::ConvertUTF8toWide(envVar, wenvVar)) {
- assert(false &&
- "Unicode conversion of environment variable name failed");
- return;
- }
- const wchar_t *wenvValue = _wgetenv(wenvVar.c_str());
- if (!wenvValue)
- return;
- std::string envValueBuffer;
- if (!llvm::convertWideToUTF8(wenvValue, envValueBuffer)) {
- assert(false &&
- "Unicode conversion of environment variable value failed");
- return;
- }
- const char *envValue = envValueBuffer.c_str();
-#else
- const char *envValue = getenv(envVar);
+ llvm::Optional<std::string> envValue = sys::Process::GetEnv(StringRef(envVar));
if (!envValue)
return;
-#endif
// Get program's "name", which we wouldn't know without the caller
// telling us.
SmallVector<const char *, 20> newArgv;
BumpPtrAllocator A;
StringSaver Saver(A);
- newArgv.push_back(Saver.save(progName));
+ newArgv.push_back(Saver.save(progName).data());
// Parse the value of the environment variable into a "command line"
// and hand it off to ParseCommandLineOptions().
- TokenizeGNUCommandLine(envValue, Saver, newArgv);
+ TokenizeGNUCommandLine(*envValue, Saver, newArgv);
int newArgc = static_cast<int>(newArgv.size());
- ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
+ ParseCommandLineOptions(newArgc, &newArgv[0], StringRef(Overview));
}
bool cl::ParseCommandLineOptions(int argc, const char *const *argv,
- const char *Overview, bool IgnoreErrors) {
+ StringRef Overview, bool IgnoreErrors) {
return GlobalParser->ParseCommandLineOptions(argc, argv, Overview,
IgnoreErrors);
}
@@ -1006,7 +1029,7 @@ void CommandLineParser::ResetAllOptionOccurrences() {
bool CommandLineParser::ParseCommandLineOptions(int argc,
const char *const *argv,
- const char *Overview,
+ StringRef Overview,
bool IgnoreErrors) {
assert(hasOptions() && "No options specified!");
@@ -1019,7 +1042,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
argc = static_cast<int>(newArgv.size());
// Copy the program name into ProgName, making sure not to overflow it.
- ProgramName = sys::path::filename(argv[0]);
+ ProgramName = sys::path::filename(StringRef(argv[0]));
ProgramOverview = Overview;
bool ErrorParsing = false;
@@ -1035,7 +1058,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
if (argc >= 2 && argv[FirstArg][0] != '-') {
// If the first argument specifies a valid subcommand, start processing
// options from the second argument.
- ChosenSubCommand = LookupSubCommand(argv[FirstArg]);
+ ChosenSubCommand = LookupSubCommand(StringRef(argv[FirstArg]));
if (ChosenSubCommand != &*TopLevelSubCommand)
FirstArg = 2;
}
@@ -1116,19 +1139,19 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
if (argv[i][0] != '-' || argv[i][1] == 0 || DashDashFound) {
// Positional argument!
if (ActivePositionalArg) {
- ProvidePositionalOption(ActivePositionalArg, argv[i], i);
+ ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i);
continue; // We are done!
}
if (!PositionalOpts.empty()) {
- PositionalVals.push_back(std::make_pair(argv[i], i));
+ PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i));
// All of the positional arguments have been fulfulled, give the rest to
// the consume after option... if it's specified...
//
if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) {
for (++i; i < argc; ++i)
- PositionalVals.push_back(std::make_pair(argv[i], i));
+ PositionalVals.push_back(std::make_pair(StringRef(argv[i]), i));
break; // Handle outside of the argument processing loop...
}
@@ -1144,19 +1167,19 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
// If there is a positional argument eating options, check to see if this
// option is another positional argument. If so, treat it as an argument,
// otherwise feed it to the eating positional.
- ArgName = argv[i] + 1;
+ ArgName = StringRef(argv[i] + 1);
// Eat leading dashes.
while (!ArgName.empty() && ArgName[0] == '-')
ArgName = ArgName.substr(1);
Handler = LookupOption(*ChosenSubCommand, ArgName, Value);
if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
- ProvidePositionalOption(ActivePositionalArg, argv[i], i);
+ ProvidePositionalOption(ActivePositionalArg, StringRef(argv[i]), i);
continue; // We are done!
}
} else { // We start with a '-', must be an argument.
- ArgName = argv[i] + 1;
+ ArgName = StringRef(argv[i] + 1);
// Eat leading dashes.
while (!ArgName.empty() && ArgName[0] == '-')
ArgName = ArgName.substr(1);
@@ -1193,7 +1216,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
for (SmallVectorImpl<Option *>::iterator I = SinkOpts.begin(),
E = SinkOpts.end();
I != E; ++I)
- (*I)->addOccurrence(i, "", argv[i]);
+ (*I)->addOccurrence(i, "", StringRef(argv[i]));
}
continue;
}
@@ -1212,7 +1235,8 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
errs() << ProgramName
<< ": Not enough positional command line arguments specified!\n"
<< "Must specify at least " << NumPositionalRequired
- << " positional arguments: See: " << argv[0] << " -help\n";
+ << " positional argument" << (NumPositionalRequired > 1 ? "s" : "")
+ << ": See: " << argv[0] << " - help\n";
}
ErrorParsing = true;
@@ -1245,7 +1269,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
switch (PositionalOpts[i]->getNumOccurrencesFlag()) {
case cl::Optional:
Done = true; // Optional arguments want _at most_ one value
- // FALL THROUGH
+ LLVM_FALLTHROUGH;
case cl::ZeroOrMore: // Zero or more will take all they can get...
case cl::OneOrMore: // One or more will take all they can get...
ProvidePositionalOption(PositionalOpts[i],
@@ -1299,7 +1323,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
Opt.second->error("must be specified at least once!");
ErrorParsing = true;
}
- // Fall through
+ LLVM_FALLTHROUGH;
default:
break;
}
@@ -1354,7 +1378,7 @@ bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value,
case Required:
if (NumOccurrences > 1)
return error("must occur exactly one time!", ArgName);
- // Fall through
+ LLVM_FALLTHROUGH;
case OneOrMore:
case ZeroOrMore:
case ConsumeAfter:
@@ -1406,7 +1430,8 @@ void alias::printOptionInfo(size_t GlobalWidth) const {
// Return the width of the option tag for printing...
size_t basic_parser_impl::getOptionWidth(const Option &O) const {
size_t Len = O.ArgStr.size();
- if (const char *ValName = getValueName())
+ auto ValName = getValueName();
+ if (!ValName.empty())
Len += getValueStr(O, ValName).size() + 3;
return Len + 6;
@@ -1419,7 +1444,8 @@ void basic_parser_impl::printOptionInfo(const Option &O,
size_t GlobalWidth) const {
outs() << " -" << O.ArgStr;
- if (const char *ValName = getValueName())
+ auto ValName = getValueName();
+ if (!ValName.empty())
outs() << "=<" << getValueStr(O, ValName) << '>';
printHelpStr(O.HelpStr, GlobalWidth, getOptionWidth(O));
@@ -1529,11 +1555,11 @@ bool parser<float>::parse(Option &O, StringRef ArgName, StringRef Arg,
// findOption - Return the option number corresponding to the specified
// argument string. If the option is not found, getNumOptions() is returned.
//
-unsigned generic_parser_base::findOption(const char *Name) {
+unsigned generic_parser_base::findOption(StringRef Name) {
unsigned e = getNumOptions();
for (unsigned i = 0; i != e; ++i) {
- if (strcmp(getOption(i), Name) == 0)
+ if (getOption(i) == Name)
return i;
}
return e;
@@ -1544,12 +1570,12 @@ size_t generic_parser_base::getOptionWidth(const Option &O) const {
if (O.hasArgStr()) {
size_t Size = O.ArgStr.size() + 6;
for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
- Size = std::max(Size, std::strlen(getOption(i)) + 8);
+ Size = std::max(Size, getOption(i).size() + 8);
return Size;
} else {
size_t BaseSize = 0;
for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
- BaseSize = std::max(BaseSize, std::strlen(getOption(i)) + 8);
+ BaseSize = std::max(BaseSize, getOption(i).size() + 8);
return BaseSize;
}
}
@@ -1564,7 +1590,7 @@ void generic_parser_base::printOptionInfo(const Option &O,
printHelpStr(O.HelpStr, GlobalWidth, O.ArgStr.size() + 6);
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
- size_t NumSpaces = GlobalWidth - strlen(getOption(i)) - 8;
+ size_t NumSpaces = GlobalWidth - getOption(i).size() - 8;
outs() << " =" << getOption(i);
outs().indent(NumSpaces) << " - " << getDescription(i) << '\n';
}
@@ -1572,9 +1598,9 @@ void generic_parser_base::printOptionInfo(const Option &O,
if (!O.HelpStr.empty())
outs() << " " << O.HelpStr << '\n';
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
- const char *Option = getOption(i);
+ auto Option = getOption(i);
outs() << " -" << Option;
- printHelpStr(getDescription(i), GlobalWidth, std::strlen(Option) + 8);
+ printHelpStr(getDescription(i), GlobalWidth, Option.size() + 8);
}
}
}
@@ -1596,7 +1622,7 @@ void generic_parser_base::printGenericOptionDiff(
continue;
outs() << "= " << getOption(i);
- size_t L = std::strlen(getOption(i));
+ size_t L = getOption(i).size();
size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0;
outs().indent(NumSpaces) << " (default: ";
for (unsigned j = 0; j != NumOpts; ++j) {
@@ -1709,9 +1735,9 @@ static void
sortSubCommands(const SmallPtrSetImpl<SubCommand *> &SubMap,
SmallVectorImpl<std::pair<const char *, SubCommand *>> &Subs) {
for (const auto &S : SubMap) {
- if (S->getName() == nullptr)
+ if (S->getName().empty())
continue;
- Subs.push_back(std::make_pair(S->getName(), S));
+ Subs.push_back(std::make_pair(S->getName().data(), S));
}
array_pod_sort(Subs.begin(), Subs.end(), SubNameCompare);
}
@@ -1734,7 +1760,7 @@ protected:
void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) {
for (const auto &S : Subs) {
outs() << " " << S.first;
- if (S.second->getDescription()) {
+ if (!S.second->getDescription().empty()) {
outs().indent(MaxSubLen - strlen(S.first));
outs() << " - " << S.second->getDescription();
}
@@ -1762,14 +1788,16 @@ public:
StrSubCommandPairVector Subs;
sortSubCommands(GlobalParser->RegisteredSubCommands, Subs);
- if (GlobalParser->ProgramOverview)
+ if (!GlobalParser->ProgramOverview.empty())
outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";
- if (Sub == &*TopLevelSubCommand)
- outs() << "USAGE: " << GlobalParser->ProgramName
- << " [subcommand] [options]";
- else {
- if (Sub->getDescription() != nullptr) {
+ if (Sub == &*TopLevelSubCommand) {
+ outs() << "USAGE: " << GlobalParser->ProgramName;
+ if (Subs.size() > 2)
+ outs() << " [subcommand]";
+ outs() << " [options]";
+ } else {
+ if (!Sub->getDescription().empty()) {
outs() << "SUBCOMMAND '" << Sub->getName()
<< "': " << Sub->getDescription() << "\n\n";
}
@@ -1787,7 +1815,7 @@ public:
if (ConsumeAfterOpt)
outs() << " " << ConsumeAfterOpt->HelpStr;
- if (Sub == &*TopLevelSubCommand && Subs.size() > 2) {
+ if (Sub == &*TopLevelSubCommand && !Subs.empty()) {
// Compute the maximum subcommand length...
size_t MaxSubLen = 0;
for (size_t i = 0, e = Subs.size(); i != e; ++i)
@@ -1831,7 +1859,7 @@ public:
// ordered before B's name. It returns a value greater equal zero otherwise.
static int OptionCategoryCompare(OptionCategory *const *A,
OptionCategory *const *B) {
- return strcmp((*A)->getName(), (*B)->getName());
+ return (*A)->getName() == (*B)->getName();
}
// Make sure we inherit our base class's operator=()
@@ -1888,7 +1916,7 @@ protected:
outs() << (*Category)->getName() << ":\n";
// Check if description is set.
- if ((*Category)->getDescription() != nullptr)
+ if (!(*Category)->getDescription().empty())
outs() << (*Category)->getDescription() << "\n\n";
else
outs() << "\n";
@@ -2118,10 +2146,15 @@ void cl::AddExtraVersionPrinter(void (*func)()) {
StringMap<Option *> &cl::getRegisteredOptions(SubCommand &Sub) {
auto &Subs = GlobalParser->RegisteredSubCommands;
(void)Subs;
- assert(std::find(Subs.begin(), Subs.end(), &Sub) != Subs.end());
+ assert(is_contained(Subs, &Sub));
return Sub.OptionsMap;
}
+iterator_range<typename SmallPtrSet<SubCommand *, 4>::iterator>
+cl::getRegisteredSubcommands() {
+ return GlobalParser->getRegisteredSubcommands();
+}
+
void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) {
for (auto &I : Sub.OptionsMap) {
if (I.second->Category != &Category &&
@@ -2149,5 +2182,5 @@ void cl::ResetAllOptionOccurrences() {
void LLVMParseCommandLineOptions(int argc, const char *const *argv,
const char *Overview) {
- llvm::cl::ParseCommandLineOptions(argc, argv, Overview, true);
+ llvm::cl::ParseCommandLineOptions(argc, argv, StringRef(Overview), true);
}
diff --git a/contrib/llvm/lib/Support/Compression.cpp b/contrib/llvm/lib/Support/Compression.cpp
index b54613e..5d55646 100644
--- a/contrib/llvm/lib/Support/Compression.cpp
+++ b/contrib/llvm/lib/Support/Compression.cpp
@@ -62,16 +62,23 @@ zlib::Status zlib::compress(StringRef InputBuffer,
return Res;
}
+zlib::Status zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ Status Res = encodeZlibReturnValue(
+ ::uncompress((Bytef *)UncompressedBuffer, (uLongf *)&UncompressedSize,
+ (const Bytef *)InputBuffer.data(), InputBuffer.size()));
+ // Tell MemorySanitizer that zlib output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(UncompressedBuffer, UncompressedSize);
+ return Res;
+}
+
zlib::Status zlib::uncompress(StringRef InputBuffer,
SmallVectorImpl<char> &UncompressedBuffer,
size_t UncompressedSize) {
UncompressedBuffer.resize(UncompressedSize);
- Status Res = encodeZlibReturnValue(::uncompress(
- (Bytef *)UncompressedBuffer.data(), (uLongf *)&UncompressedSize,
- (const Bytef *)InputBuffer.data(), InputBuffer.size()));
- // Tell MemorySanitizer that zlib output buffer is fully initialized.
- // This avoids a false report when running LLVM with uninstrumented ZLib.
- __msan_unpoison(UncompressedBuffer.data(), UncompressedSize);
+ Status Res =
+ uncompress(InputBuffer, UncompressedBuffer.data(), UncompressedSize);
UncompressedBuffer.resize(UncompressedSize);
return Res;
}
@@ -87,6 +94,10 @@ zlib::Status zlib::compress(StringRef InputBuffer,
CompressionLevel Level) {
return zlib::StatusUnsupported;
}
+zlib::Status zlib::uncompress(StringRef InputBuffer, char *UncompressedBuffer,
+ size_t &UncompressedSize) {
+ return zlib::StatusUnsupported;
+}
zlib::Status zlib::uncompress(StringRef InputBuffer,
SmallVectorImpl<char> &UncompressedBuffer,
size_t UncompressedSize) {
diff --git a/contrib/llvm/lib/Support/ConvertUTF.c b/contrib/llvm/lib/Support/ConvertUTF.cpp
index 128459a..39fd218 100644
--- a/contrib/llvm/lib/Support/ConvertUTF.c
+++ b/contrib/llvm/lib/Support/ConvertUTF.cpp
@@ -53,6 +53,8 @@
#endif
#include <assert.h>
+namespace llvm {
+
static const int halfShift = 10; /* used for shifting by 10 bits */
static const UTF32 halfBase = 0x0010000UL;
@@ -62,8 +64,6 @@ static const UTF32 halfMask = 0x3FFUL;
#define UNI_SUR_HIGH_END (UTF32)0xDBFF
#define UNI_SUR_LOW_START (UTF32)0xDC00
#define UNI_SUR_LOW_END (UTF32)0xDFFF
-#define false 0
-#define true 1
/* --------------------------------------------------------------------- */
@@ -706,3 +706,5 @@ ConversionResult ConvertUTF8toUTF32(const UTF8 **sourceStart,
similarly unrolled loops.
--------------------------------------------------------------------- */
+
+} // namespace llvm
diff --git a/contrib/llvm/lib/Support/DataStream.cpp b/contrib/llvm/lib/Support/DataStream.cpp
deleted file mode 100644
index 3b10fc5..0000000
--- a/contrib/llvm/lib/Support/DataStream.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-//===--- llvm/Support/DataStream.cpp - Lazy streamed data -----------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements DataStreamer, which fetches bytes of Data from
-// a stream source. It provides support for streaming (lazy reading) of
-// bitcode. An example implementation of streaming from a file or stdin
-// is included.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/DataStream.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Program.h"
-#include <string>
-#include <system_error>
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-using namespace llvm;
-
-#define DEBUG_TYPE "Data-stream"
-
-// Interface goals:
-// * StreamingMemoryObject doesn't care about complexities like using
-// threads/async callbacks to actually overlap download+compile
-// * Don't want to duplicate Data in memory
-// * Don't need to know total Data len in advance
-// Non-goals:
-// StreamingMemoryObject already has random access so this interface only does
-// in-order streaming (no arbitrary seeking, else we'd have to buffer all the
-// Data here in addition to MemoryObject). This also means that if we want
-// to be able to to free Data, BitstreamBytes/BitcodeReader will implement it
-
-STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch");
-
-namespace llvm {
-DataStreamer::~DataStreamer() {}
-}
-
-namespace {
-
-// Very simple stream backed by a file. Mostly useful for stdin and debugging;
-// actual file access is probably still best done with mmap.
-class DataFileStreamer : public DataStreamer {
- int Fd;
-public:
- DataFileStreamer() : Fd(0) {}
- ~DataFileStreamer() override { close(Fd); }
- size_t GetBytes(unsigned char *buf, size_t len) override {
- NumStreamFetches++;
- return read(Fd, buf, len);
- }
-
- std::error_code OpenFile(const std::string &Filename) {
- if (Filename == "-") {
- Fd = 0;
- sys::ChangeStdinToBinary();
- return std::error_code();
- }
-
- return sys::fs::openFileForRead(Filename, Fd);
- }
-};
-
-}
-
-std::unique_ptr<DataStreamer>
-llvm::getDataFileStreamer(const std::string &Filename, std::string *StrError) {
- std::unique_ptr<DataFileStreamer> s = make_unique<DataFileStreamer>();
- if (std::error_code e = s->OpenFile(Filename)) {
- *StrError = std::string("Could not open ") + Filename + ": " +
- e.message() + "\n";
- return nullptr;
- }
- return std::move(s);
-}
diff --git a/contrib/llvm/lib/Support/Debug.cpp b/contrib/llvm/lib/Support/Debug.cpp
index 323d532..9132911 100644
--- a/contrib/llvm/lib/Support/Debug.cpp
+++ b/contrib/llvm/lib/Support/Debug.cpp
@@ -32,6 +32,7 @@
#undef isCurrentDebugType
#undef setCurrentDebugType
+#undef setCurrentDebugTypes
using namespace llvm;
@@ -62,11 +63,17 @@ bool isCurrentDebugType(const char *DebugType) {
/// option were specified. Note that DebugFlag also needs to be set to true for
/// debug output to be produced.
///
+void setCurrentDebugTypes(const char **Types, unsigned Count);
+
void setCurrentDebugType(const char *Type) {
- CurrentDebugType->clear();
- CurrentDebugType->push_back(Type);
+ setCurrentDebugTypes(&Type, 1);
}
+void setCurrentDebugTypes(const char **Types, unsigned Count) {
+ CurrentDebugType->clear();
+ for (size_t T = 0; T < Count; ++T)
+ CurrentDebugType->push_back(Types[T]);
+}
} // namespace llvm
// All Debug.h functionality is a no-op in NDEBUG mode.
diff --git a/contrib/llvm/lib/Support/DeltaAlgorithm.cpp b/contrib/llvm/lib/Support/DeltaAlgorithm.cpp
index 9e52874..50ea4e9 100644
--- a/contrib/llvm/lib/Support/DeltaAlgorithm.cpp
+++ b/contrib/llvm/lib/Support/DeltaAlgorithm.cpp
@@ -9,6 +9,7 @@
#include "llvm/ADT/DeltaAlgorithm.h"
#include <algorithm>
#include <iterator>
+#include <set>
using namespace llvm;
DeltaAlgorithm::~DeltaAlgorithm() {
diff --git a/contrib/llvm/lib/Support/Dwarf.cpp b/contrib/llvm/lib/Support/Dwarf.cpp
index 7aea05d..8950e8c 100644
--- a/contrib/llvm/lib/Support/Dwarf.cpp
+++ b/contrib/llvm/lib/Support/Dwarf.cpp
@@ -18,9 +18,10 @@
using namespace llvm;
using namespace dwarf;
-const char *llvm::dwarf::TagString(unsigned Tag) {
+StringRef llvm::dwarf::TagString(unsigned Tag) {
switch (Tag) {
- default: return nullptr;
+ default:
+ return StringRef();
#define HANDLE_DW_TAG(ID, NAME) \
case DW_TAG_##NAME: \
return "DW_TAG_" #NAME;
@@ -35,240 +36,46 @@ unsigned llvm::dwarf::getTag(StringRef TagString) {
.Default(DW_TAG_invalid);
}
-const char *llvm::dwarf::ChildrenString(unsigned Children) {
+StringRef llvm::dwarf::ChildrenString(unsigned Children) {
switch (Children) {
case DW_CHILDREN_no: return "DW_CHILDREN_no";
case DW_CHILDREN_yes: return "DW_CHILDREN_yes";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::AttributeString(unsigned Attribute) {
+StringRef llvm::dwarf::AttributeString(unsigned Attribute) {
switch (Attribute) {
- case DW_AT_sibling: return "DW_AT_sibling";
- case DW_AT_location: return "DW_AT_location";
- case DW_AT_name: return "DW_AT_name";
- case DW_AT_ordering: return "DW_AT_ordering";
- case DW_AT_byte_size: return "DW_AT_byte_size";
- case DW_AT_bit_offset: return "DW_AT_bit_offset";
- case DW_AT_bit_size: return "DW_AT_bit_size";
- case DW_AT_stmt_list: return "DW_AT_stmt_list";
- case DW_AT_low_pc: return "DW_AT_low_pc";
- case DW_AT_high_pc: return "DW_AT_high_pc";
- case DW_AT_language: return "DW_AT_language";
- case DW_AT_discr: return "DW_AT_discr";
- case DW_AT_discr_value: return "DW_AT_discr_value";
- case DW_AT_visibility: return "DW_AT_visibility";
- case DW_AT_import: return "DW_AT_import";
- case DW_AT_string_length: return "DW_AT_string_length";
- case DW_AT_common_reference: return "DW_AT_common_reference";
- case DW_AT_comp_dir: return "DW_AT_comp_dir";
- case DW_AT_const_value: return "DW_AT_const_value";
- case DW_AT_containing_type: return "DW_AT_containing_type";
- case DW_AT_default_value: return "DW_AT_default_value";
- case DW_AT_inline: return "DW_AT_inline";
- case DW_AT_is_optional: return "DW_AT_is_optional";
- case DW_AT_lower_bound: return "DW_AT_lower_bound";
- case DW_AT_producer: return "DW_AT_producer";
- case DW_AT_prototyped: return "DW_AT_prototyped";
- case DW_AT_return_addr: return "DW_AT_return_addr";
- case DW_AT_start_scope: return "DW_AT_start_scope";
- case DW_AT_bit_stride: return "DW_AT_bit_stride";
- case DW_AT_upper_bound: return "DW_AT_upper_bound";
- case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
- case DW_AT_accessibility: return "DW_AT_accessibility";
- case DW_AT_address_class: return "DW_AT_address_class";
- case DW_AT_artificial: return "DW_AT_artificial";
- case DW_AT_base_types: return "DW_AT_base_types";
- case DW_AT_calling_convention: return "DW_AT_calling_convention";
- case DW_AT_count: return "DW_AT_count";
- case DW_AT_data_member_location: return "DW_AT_data_member_location";
- case DW_AT_decl_column: return "DW_AT_decl_column";
- case DW_AT_decl_file: return "DW_AT_decl_file";
- case DW_AT_decl_line: return "DW_AT_decl_line";
- case DW_AT_declaration: return "DW_AT_declaration";
- case DW_AT_discr_list: return "DW_AT_discr_list";
- case DW_AT_encoding: return "DW_AT_encoding";
- case DW_AT_external: return "DW_AT_external";
- case DW_AT_frame_base: return "DW_AT_frame_base";
- case DW_AT_friend: return "DW_AT_friend";
- case DW_AT_identifier_case: return "DW_AT_identifier_case";
- case DW_AT_macro_info: return "DW_AT_macro_info";
- case DW_AT_namelist_item: return "DW_AT_namelist_item";
- case DW_AT_priority: return "DW_AT_priority";
- case DW_AT_segment: return "DW_AT_segment";
- case DW_AT_specification: return "DW_AT_specification";
- case DW_AT_static_link: return "DW_AT_static_link";
- case DW_AT_type: return "DW_AT_type";
- case DW_AT_use_location: return "DW_AT_use_location";
- case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
- case DW_AT_virtuality: return "DW_AT_virtuality";
- case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
- case DW_AT_allocated: return "DW_AT_allocated";
- case DW_AT_associated: return "DW_AT_associated";
- case DW_AT_data_location: return "DW_AT_data_location";
- case DW_AT_byte_stride: return "DW_AT_byte_stride";
- case DW_AT_entry_pc: return "DW_AT_entry_pc";
- case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
- case DW_AT_extension: return "DW_AT_extension";
- case DW_AT_ranges: return "DW_AT_ranges";
- case DW_AT_trampoline: return "DW_AT_trampoline";
- case DW_AT_call_column: return "DW_AT_call_column";
- case DW_AT_call_file: return "DW_AT_call_file";
- case DW_AT_call_line: return "DW_AT_call_line";
- case DW_AT_description: return "DW_AT_description";
- case DW_AT_binary_scale: return "DW_AT_binary_scale";
- case DW_AT_decimal_scale: return "DW_AT_decimal_scale";
- case DW_AT_small: return "DW_AT_small";
- case DW_AT_decimal_sign: return "DW_AT_decimal_sign";
- case DW_AT_digit_count: return "DW_AT_digit_count";
- case DW_AT_picture_string: return "DW_AT_picture_string";
- case DW_AT_mutable: return "DW_AT_mutable";
- case DW_AT_threads_scaled: return "DW_AT_threads_scaled";
- case DW_AT_explicit: return "DW_AT_explicit";
- case DW_AT_object_pointer: return "DW_AT_object_pointer";
- case DW_AT_endianity: return "DW_AT_endianity";
- case DW_AT_elemental: return "DW_AT_elemental";
- case DW_AT_pure: return "DW_AT_pure";
- case DW_AT_recursive: return "DW_AT_recursive";
- case DW_AT_signature: return "DW_AT_signature";
- case DW_AT_main_subprogram: return "DW_AT_main_subprogram";
- case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset";
- case DW_AT_const_expr: return "DW_AT_const_expr";
- case DW_AT_enum_class: return "DW_AT_enum_class";
- case DW_AT_linkage_name: return "DW_AT_linkage_name";
- case DW_AT_string_length_bit_size: return "DW_AT_string_length_bit_size";
- case DW_AT_string_length_byte_size: return "DW_AT_string_length_byte_size";
- case DW_AT_rank: return "DW_AT_rank";
- case DW_AT_str_offsets_base: return "DW_AT_str_offsets_base";
- case DW_AT_addr_base: return "DW_AT_addr_base";
- case DW_AT_ranges_base: return "DW_AT_ranges_base";
- case DW_AT_dwo_id: return "DW_AT_dwo_id";
- case DW_AT_dwo_name: return "DW_AT_dwo_name";
- case DW_AT_reference: return "DW_AT_reference";
- case DW_AT_rvalue_reference: return "DW_AT_rvalue_reference";
- case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
- case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
- case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
- case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
- case DW_AT_MIPS_software_pipeline_depth:
- return "DW_AT_MIPS_software_pipeline_depth";
- case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
- case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
- case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
- case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
- case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
- case DW_AT_MIPS_stride_byte: return "DW_AT_MIPS_stride_byte";
- case DW_AT_MIPS_stride_elem: return "DW_AT_MIPS_stride_elem";
- case DW_AT_MIPS_ptr_dopetype: return "DW_AT_MIPS_ptr_dopetype";
- case DW_AT_MIPS_allocatable_dopetype:
- return "DW_AT_MIPS_allocatable_dopetype";
- case DW_AT_MIPS_assumed_shape_dopetype:
- return "DW_AT_MIPS_assumed_shape_dopetype";
- case DW_AT_sf_names: return "DW_AT_sf_names";
- case DW_AT_src_info: return "DW_AT_src_info";
- case DW_AT_mac_info: return "DW_AT_mac_info";
- case DW_AT_src_coords: return "DW_AT_src_coords";
- case DW_AT_body_begin: return "DW_AT_body_begin";
- case DW_AT_body_end: return "DW_AT_body_end";
- case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
- case DW_AT_GNU_template_name: return "DW_AT_GNU_template_name";
- case DW_AT_GNU_odr_signature: return "DW_AT_GNU_odr_signature";
- case DW_AT_MIPS_assumed_size: return "DW_AT_MIPS_assumed_size";
- case DW_AT_lo_user: return "DW_AT_lo_user";
- case DW_AT_hi_user: return "DW_AT_hi_user";
- case DW_AT_BORLAND_property_read: return "DW_AT_BORLAND_property_read";
- case DW_AT_BORLAND_property_write: return "DW_AT_BORLAND_property_write";
- case DW_AT_BORLAND_property_implements: return "DW_AT_BORLAND_property_implements";
- case DW_AT_BORLAND_property_index: return "DW_AT_BORLAND_property_index";
- case DW_AT_BORLAND_property_default: return "DW_AT_BORLAND_property_default";
- case DW_AT_BORLAND_Delphi_unit: return "DW_AT_BORLAND_Delphi_unit";
- case DW_AT_BORLAND_Delphi_class: return "DW_AT_BORLAND_Delphi_class";
- case DW_AT_BORLAND_Delphi_record: return "DW_AT_BORLAND_Delphi_record";
- case DW_AT_BORLAND_Delphi_metaclass: return "DW_AT_BORLAND_Delphi_metaclass";
- case DW_AT_BORLAND_Delphi_constructor: return "DW_AT_BORLAND_Delphi_constructor";
- case DW_AT_BORLAND_Delphi_destructor: return "DW_AT_BORLAND_Delphi_destructor";
- case DW_AT_BORLAND_Delphi_anonymous_method: return "DW_AT_BORLAND_Delphi_anonymous_method";
- case DW_AT_BORLAND_Delphi_interface: return "DW_AT_BORLAND_Delphi_interface";
- case DW_AT_BORLAND_Delphi_ABI: return "DW_AT_BORLAND_Delphi_ABI";
- case DW_AT_BORLAND_Delphi_return: return "DW_AT_BORLAND_Delphi_return";
- case DW_AT_BORLAND_Delphi_frameptr: return "DW_AT_BORLAND_Delphi_frameptr";
- case DW_AT_BORLAND_closure: return "DW_AT_BORLAND_closure";
- case DW_AT_APPLE_optimized: return "DW_AT_APPLE_optimized";
- case DW_AT_APPLE_flags: return "DW_AT_APPLE_flags";
- case DW_AT_APPLE_isa: return "DW_AT_APPLE_isa";
- case DW_AT_APPLE_block: return "DW_AT_APPLE_block";
- case DW_AT_APPLE_major_runtime_vers: return "DW_AT_APPLE_major_runtime_vers";
- case DW_AT_APPLE_runtime_class: return "DW_AT_APPLE_runtime_class";
- case DW_AT_APPLE_omit_frame_ptr: return "DW_AT_APPLE_omit_frame_ptr";
- case DW_AT_APPLE_property_name: return "DW_AT_APPLE_property_name";
- case DW_AT_APPLE_property_getter: return "DW_AT_APPLE_property_getter";
- case DW_AT_APPLE_property_setter: return "DW_AT_APPLE_property_setter";
- case DW_AT_APPLE_property_attribute: return "DW_AT_APPLE_property_attribute";
- case DW_AT_APPLE_property: return "DW_AT_APPLE_property";
- case DW_AT_APPLE_objc_complete_type: return "DW_AT_APPLE_objc_complete_type";
- case DW_AT_LLVM_include_path: return "DW_AT_LLVM_include_path";
- case DW_AT_LLVM_config_macros: return "DW_AT_LLVM_config_macros";
- case DW_AT_LLVM_isysroot: return "DW_AT_LLVM_isysroot";
-
- // DWARF5 Fission Extension Attribute
- case DW_AT_GNU_dwo_name: return "DW_AT_GNU_dwo_name";
- case DW_AT_GNU_dwo_id: return "DW_AT_GNU_dwo_id";
- case DW_AT_GNU_ranges_base: return "DW_AT_GNU_ranges_base";
- case DW_AT_GNU_addr_base: return "DW_AT_GNU_addr_base";
- case DW_AT_GNU_pubnames: return "DW_AT_GNU_pubnames";
- case DW_AT_GNU_pubtypes: return "DW_AT_GNU_pubtypes";
- case DW_AT_GNU_discriminator: return "DW_AT_GNU_discriminator";
+ default:
+ return StringRef();
+#define HANDLE_DW_AT(ID, NAME) \
+ case DW_AT_##NAME: \
+ return "DW_AT_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
}
-const char *llvm::dwarf::FormEncodingString(unsigned Encoding) {
+StringRef llvm::dwarf::FormEncodingString(unsigned Encoding) {
switch (Encoding) {
- case DW_FORM_addr: return "DW_FORM_addr";
- case DW_FORM_block2: return "DW_FORM_block2";
- case DW_FORM_block4: return "DW_FORM_block4";
- case DW_FORM_data2: return "DW_FORM_data2";
- case DW_FORM_data4: return "DW_FORM_data4";
- case DW_FORM_data8: return "DW_FORM_data8";
- case DW_FORM_string: return "DW_FORM_string";
- case DW_FORM_block: return "DW_FORM_block";
- case DW_FORM_block1: return "DW_FORM_block1";
- case DW_FORM_data1: return "DW_FORM_data1";
- case DW_FORM_flag: return "DW_FORM_flag";
- case DW_FORM_sdata: return "DW_FORM_sdata";
- case DW_FORM_strp: return "DW_FORM_strp";
- case DW_FORM_udata: return "DW_FORM_udata";
- case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
- case DW_FORM_ref1: return "DW_FORM_ref1";
- case DW_FORM_ref2: return "DW_FORM_ref2";
- case DW_FORM_ref4: return "DW_FORM_ref4";
- case DW_FORM_ref8: return "DW_FORM_ref8";
- case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
- case DW_FORM_indirect: return "DW_FORM_indirect";
- case DW_FORM_sec_offset: return "DW_FORM_sec_offset";
- case DW_FORM_exprloc: return "DW_FORM_exprloc";
- case DW_FORM_flag_present: return "DW_FORM_flag_present";
- case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8";
-
- // DWARF5 Fission Extension Forms
- case DW_FORM_GNU_addr_index: return "DW_FORM_GNU_addr_index";
- case DW_FORM_GNU_str_index: return "DW_FORM_GNU_str_index";
-
- // Alternate debug sections proposal (output of "dwz" tool).
- case DW_FORM_GNU_ref_alt: return "DW_FORM_GNU_ref_alt";
- case DW_FORM_GNU_strp_alt: return "DW_FORM_GNU_strp_alt";
+ default:
+ return StringRef();
+#define HANDLE_DW_FORM(ID, NAME) \
+ case DW_FORM_##NAME: \
+ return "DW_FORM_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
}
-const char *llvm::dwarf::OperationEncodingString(unsigned Encoding) {
+StringRef llvm::dwarf::OperationEncodingString(unsigned Encoding) {
switch (Encoding) {
- default: return nullptr;
+ default:
+ return StringRef();
#define HANDLE_DW_OP(ID, NAME) \
case DW_OP_##NAME: \
return "DW_OP_" #NAME;
#include "llvm/Support/Dwarf.def"
+ case DW_OP_LLVM_fragment:
+ return "DW_OP_LLVM_fragment";
}
}
@@ -276,12 +83,14 @@ unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
return StringSwitch<unsigned>(OperationEncodingString)
#define HANDLE_DW_OP(ID, NAME) .Case("DW_OP_" #NAME, DW_OP_##NAME)
#include "llvm/Support/Dwarf.def"
+ .Case("DW_OP_LLVM_fragment", DW_OP_LLVM_fragment)
.Default(0);
}
-const char *llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
+StringRef llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
switch (Encoding) {
- default: return nullptr;
+ default:
+ return StringRef();
#define HANDLE_DW_ATE(ID, NAME) \
case DW_ATE_##NAME: \
return "DW_ATE_" #NAME;
@@ -296,7 +105,7 @@ unsigned llvm::dwarf::getAttributeEncoding(StringRef EncodingString) {
.Default(0);
}
-const char *llvm::dwarf::DecimalSignString(unsigned Sign) {
+StringRef llvm::dwarf::DecimalSignString(unsigned Sign) {
switch (Sign) {
case DW_DS_unsigned: return "DW_DS_unsigned";
case DW_DS_leading_overpunch: return "DW_DS_leading_overpunch";
@@ -304,10 +113,10 @@ const char *llvm::dwarf::DecimalSignString(unsigned Sign) {
case DW_DS_leading_separate: return "DW_DS_leading_separate";
case DW_DS_trailing_separate: return "DW_DS_trailing_separate";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::EndianityString(unsigned Endian) {
+StringRef llvm::dwarf::EndianityString(unsigned Endian) {
switch (Endian) {
case DW_END_default: return "DW_END_default";
case DW_END_big: return "DW_END_big";
@@ -315,32 +124,32 @@ const char *llvm::dwarf::EndianityString(unsigned Endian) {
case DW_END_lo_user: return "DW_END_lo_user";
case DW_END_hi_user: return "DW_END_hi_user";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::AccessibilityString(unsigned Access) {
+StringRef llvm::dwarf::AccessibilityString(unsigned Access) {
switch (Access) {
// Accessibility codes
case DW_ACCESS_public: return "DW_ACCESS_public";
case DW_ACCESS_protected: return "DW_ACCESS_protected";
case DW_ACCESS_private: return "DW_ACCESS_private";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::VisibilityString(unsigned Visibility) {
+StringRef llvm::dwarf::VisibilityString(unsigned Visibility) {
switch (Visibility) {
case DW_VIS_local: return "DW_VIS_local";
case DW_VIS_exported: return "DW_VIS_exported";
case DW_VIS_qualified: return "DW_VIS_qualified";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::VirtualityString(unsigned Virtuality) {
+StringRef llvm::dwarf::VirtualityString(unsigned Virtuality) {
switch (Virtuality) {
default:
- return nullptr;
+ return StringRef();
#define HANDLE_DW_VIRTUALITY(ID, NAME) \
case DW_VIRTUALITY_##NAME: \
return "DW_VIRTUALITY_" #NAME;
@@ -356,10 +165,10 @@ unsigned llvm::dwarf::getVirtuality(StringRef VirtualityString) {
.Default(DW_VIRTUALITY_invalid);
}
-const char *llvm::dwarf::LanguageString(unsigned Language) {
+StringRef llvm::dwarf::LanguageString(unsigned Language) {
switch (Language) {
default:
- return nullptr;
+ return StringRef();
#define HANDLE_DW_LANG(ID, NAME) \
case DW_LANG_##NAME: \
return "DW_LANG_" #NAME;
@@ -374,20 +183,20 @@ unsigned llvm::dwarf::getLanguage(StringRef LanguageString) {
.Default(0);
}
-const char *llvm::dwarf::CaseString(unsigned Case) {
+StringRef llvm::dwarf::CaseString(unsigned Case) {
switch (Case) {
case DW_ID_case_sensitive: return "DW_ID_case_sensitive";
case DW_ID_up_case: return "DW_ID_up_case";
case DW_ID_down_case: return "DW_ID_down_case";
case DW_ID_case_insensitive: return "DW_ID_case_insensitive";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::ConventionString(unsigned CC) {
+StringRef llvm::dwarf::ConventionString(unsigned CC) {
switch (CC) {
default:
- return nullptr;
+ return StringRef();
#define HANDLE_DW_CC(ID, NAME) \
case DW_CC_##NAME: \
return "DW_CC_" #NAME;
@@ -402,64 +211,55 @@ unsigned llvm::dwarf::getCallingConvention(StringRef CCString) {
.Default(0);
}
-const char *llvm::dwarf::InlineCodeString(unsigned Code) {
+StringRef llvm::dwarf::InlineCodeString(unsigned Code) {
switch (Code) {
case DW_INL_not_inlined: return "DW_INL_not_inlined";
case DW_INL_inlined: return "DW_INL_inlined";
case DW_INL_declared_not_inlined: return "DW_INL_declared_not_inlined";
case DW_INL_declared_inlined: return "DW_INL_declared_inlined";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::ArrayOrderString(unsigned Order) {
+StringRef llvm::dwarf::ArrayOrderString(unsigned Order) {
switch (Order) {
case DW_ORD_row_major: return "DW_ORD_row_major";
case DW_ORD_col_major: return "DW_ORD_col_major";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::DiscriminantString(unsigned Discriminant) {
+StringRef llvm::dwarf::DiscriminantString(unsigned Discriminant) {
switch (Discriminant) {
case DW_DSC_label: return "DW_DSC_label";
case DW_DSC_range: return "DW_DSC_range";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::LNStandardString(unsigned Standard) {
+StringRef llvm::dwarf::LNStandardString(unsigned Standard) {
switch (Standard) {
- case DW_LNS_copy: return "DW_LNS_copy";
- case DW_LNS_advance_pc: return "DW_LNS_advance_pc";
- case DW_LNS_advance_line: return "DW_LNS_advance_line";
- case DW_LNS_set_file: return "DW_LNS_set_file";
- case DW_LNS_set_column: return "DW_LNS_set_column";
- case DW_LNS_negate_stmt: return "DW_LNS_negate_stmt";
- case DW_LNS_set_basic_block: return "DW_LNS_set_basic_block";
- case DW_LNS_const_add_pc: return "DW_LNS_const_add_pc";
- case DW_LNS_fixed_advance_pc: return "DW_LNS_fixed_advance_pc";
- case DW_LNS_set_prologue_end: return "DW_LNS_set_prologue_end";
- case DW_LNS_set_epilogue_begin: return "DW_LNS_set_epilogue_begin";
- case DW_LNS_set_isa: return "DW_LNS_set_isa";
+ default:
+ return StringRef();
+#define HANDLE_DW_LNS(ID, NAME) \
+ case DW_LNS_##NAME: \
+ return "DW_LNS_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
}
-const char *llvm::dwarf::LNExtendedString(unsigned Encoding) {
+StringRef llvm::dwarf::LNExtendedString(unsigned Encoding) {
switch (Encoding) {
- // Line Number Extended Opcode Encodings
- case DW_LNE_end_sequence: return "DW_LNE_end_sequence";
- case DW_LNE_set_address: return "DW_LNE_set_address";
- case DW_LNE_define_file: return "DW_LNE_define_file";
- case DW_LNE_set_discriminator: return "DW_LNE_set_discriminator";
- case DW_LNE_lo_user: return "DW_LNE_lo_user";
- case DW_LNE_hi_user: return "DW_LNE_hi_user";
+ default:
+ return StringRef();
+#define HANDLE_DW_LNE(ID, NAME) \
+ case DW_LNE_##NAME: \
+ return "DW_LNE_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
}
-const char *llvm::dwarf::MacinfoString(unsigned Encoding) {
+StringRef llvm::dwarf::MacinfoString(unsigned Encoding) {
switch (Encoding) {
// Macinfo Type Encodings
case DW_MACINFO_define: return "DW_MACINFO_define";
@@ -469,7 +269,7 @@ const char *llvm::dwarf::MacinfoString(unsigned Encoding) {
case DW_MACINFO_vendor_ext: return "DW_MACINFO_vendor_ext";
case DW_MACINFO_invalid: return "DW_MACINFO_invalid";
}
- return nullptr;
+ return StringRef();
}
unsigned llvm::dwarf::getMacinfo(StringRef MacinfoString) {
@@ -482,80 +282,29 @@ unsigned llvm::dwarf::getMacinfo(StringRef MacinfoString) {
.Default(DW_MACINFO_invalid);
}
-const char *llvm::dwarf::CallFrameString(unsigned Encoding) {
+StringRef llvm::dwarf::CallFrameString(unsigned Encoding) {
switch (Encoding) {
- case DW_CFA_nop: return "DW_CFA_nop";
- case DW_CFA_advance_loc: return "DW_CFA_advance_loc";
- case DW_CFA_offset: return "DW_CFA_offset";
- case DW_CFA_restore: return "DW_CFA_restore";
- case DW_CFA_set_loc: return "DW_CFA_set_loc";
- case DW_CFA_advance_loc1: return "DW_CFA_advance_loc1";
- case DW_CFA_advance_loc2: return "DW_CFA_advance_loc2";
- case DW_CFA_advance_loc4: return "DW_CFA_advance_loc4";
- case DW_CFA_offset_extended: return "DW_CFA_offset_extended";
- case DW_CFA_restore_extended: return "DW_CFA_restore_extended";
- case DW_CFA_undefined: return "DW_CFA_undefined";
- case DW_CFA_same_value: return "DW_CFA_same_value";
- case DW_CFA_register: return "DW_CFA_register";
- case DW_CFA_remember_state: return "DW_CFA_remember_state";
- case DW_CFA_restore_state: return "DW_CFA_restore_state";
- case DW_CFA_def_cfa: return "DW_CFA_def_cfa";
- case DW_CFA_def_cfa_register: return "DW_CFA_def_cfa_register";
- case DW_CFA_def_cfa_offset: return "DW_CFA_def_cfa_offset";
- case DW_CFA_def_cfa_expression: return "DW_CFA_def_cfa_expression";
- case DW_CFA_expression: return "DW_CFA_expression";
- case DW_CFA_offset_extended_sf: return "DW_CFA_offset_extended_sf";
- case DW_CFA_def_cfa_sf: return "DW_CFA_def_cfa_sf";
- case DW_CFA_def_cfa_offset_sf: return "DW_CFA_def_cfa_offset_sf";
- case DW_CFA_val_offset: return "DW_CFA_val_offset";
- case DW_CFA_val_offset_sf: return "DW_CFA_val_offset_sf";
- case DW_CFA_val_expression: return "DW_CFA_val_expression";
- case DW_CFA_MIPS_advance_loc8: return "DW_CFA_MIPS_advance_loc8";
- case DW_CFA_GNU_window_save: return "DW_CFA_GNU_window_save";
- case DW_CFA_GNU_args_size: return "DW_CFA_GNU_args_size";
- case DW_CFA_lo_user: return "DW_CFA_lo_user";
- case DW_CFA_hi_user: return "DW_CFA_hi_user";
+ default:
+ return StringRef();
+#define HANDLE_DW_CFA(ID, NAME) \
+ case DW_CFA_##NAME: \
+ return "DW_CFA_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
}
-const char *llvm::dwarf::ApplePropertyString(unsigned Prop) {
+StringRef llvm::dwarf::ApplePropertyString(unsigned Prop) {
switch (Prop) {
- case DW_APPLE_PROPERTY_readonly:
- return "DW_APPLE_PROPERTY_readonly";
- case DW_APPLE_PROPERTY_getter:
- return "DW_APPLE_PROPERTY_getter";
- case DW_APPLE_PROPERTY_assign:
- return "DW_APPLE_PROPERTY_assign";
- case DW_APPLE_PROPERTY_readwrite:
- return "DW_APPLE_PROPERTY_readwrite";
- case DW_APPLE_PROPERTY_retain:
- return "DW_APPLE_PROPERTY_retain";
- case DW_APPLE_PROPERTY_copy:
- return "DW_APPLE_PROPERTY_copy";
- case DW_APPLE_PROPERTY_nonatomic:
- return "DW_APPLE_PROPERTY_nonatomic";
- case DW_APPLE_PROPERTY_setter:
- return "DW_APPLE_PROPERTY_setter";
- case DW_APPLE_PROPERTY_atomic:
- return "DW_APPLE_PROPERTY_atomic";
- case DW_APPLE_PROPERTY_weak:
- return "DW_APPLE_PROPERTY_weak";
- case DW_APPLE_PROPERTY_strong:
- return "DW_APPLE_PROPERTY_strong";
- case DW_APPLE_PROPERTY_unsafe_unretained:
- return "DW_APPLE_PROPERTY_unsafe_unretained";
- case DW_APPLE_PROPERTY_nullability:
- return "DW_APPLE_PROPERTY_nullability";
- case DW_APPLE_PROPERTY_null_resettable:
- return "DW_APPLE_PROPERTY_null_resettable";
- case DW_APPLE_PROPERTY_class:
- return "DW_APPLE_PROPERTY_class";
+ default:
+ return StringRef();
+#define HANDLE_DW_APPLE_PROPERTY(ID, NAME) \
+ case DW_APPLE_PROPERTY_##NAME: \
+ return "DW_APPLE_PROPERTY_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
}
-const char *llvm::dwarf::AtomTypeString(unsigned AT) {
+StringRef llvm::dwarf::AtomTypeString(unsigned AT) {
switch (AT) {
case dwarf::DW_ATOM_null:
return "DW_ATOM_null";
@@ -568,10 +317,10 @@ const char *llvm::dwarf::AtomTypeString(unsigned AT) {
case DW_ATOM_type_flags:
return "DW_ATOM_type_flags";
}
- return nullptr;
+ return StringRef();
}
-const char *llvm::dwarf::GDBIndexEntryKindString(GDBIndexEntryKind Kind) {
+StringRef llvm::dwarf::GDBIndexEntryKindString(GDBIndexEntryKind Kind) {
switch (Kind) {
case GIEK_NONE:
return "NONE";
@@ -593,7 +342,8 @@ const char *llvm::dwarf::GDBIndexEntryKindString(GDBIndexEntryKind Kind) {
llvm_unreachable("Unknown GDBIndexEntryKind value");
}
-const char *llvm::dwarf::GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage) {
+StringRef
+llvm::dwarf::GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage) {
switch (Linkage) {
case GIEL_EXTERNAL:
return "EXTERNAL";
@@ -603,7 +353,7 @@ const char *llvm::dwarf::GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage
llvm_unreachable("Unknown GDBIndexEntryLinkage value");
}
-const char *llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
+StringRef llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
switch (Attr) {
case DW_AT_accessibility:
return AccessibilityString(Val);
@@ -631,5 +381,5 @@ const char *llvm::dwarf::AttributeValueString(uint16_t Attr, unsigned Val) {
return DiscriminantString(Val);
}
- return nullptr;
+ return StringRef();
}
diff --git a/contrib/llvm/lib/Support/DynamicLibrary.cpp b/contrib/llvm/lib/Support/DynamicLibrary.cpp
index 9a7aeb5..ced21e4 100644
--- a/contrib/llvm/lib/Support/DynamicLibrary.cpp
+++ b/contrib/llvm/lib/Support/DynamicLibrary.cpp
@@ -41,7 +41,7 @@ char llvm::sys::DynamicLibrary::Invalid = 0;
#else
-#if HAVE_DLFCN_H
+#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
#include <dlfcn.h>
using namespace llvm;
using namespace llvm::sys;
@@ -119,7 +119,7 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
return i->second;
}
-#if HAVE_DLFCN_H
+#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
// Now search the libraries.
if (OpenedHandles) {
for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
diff --git a/contrib/llvm/lib/Support/Error.cpp b/contrib/llvm/lib/Support/Error.cpp
index 6b22691..4730c0b 100644
--- a/contrib/llvm/lib/Support/Error.cpp
+++ b/contrib/llvm/lib/Support/Error.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include <system_error>
using namespace llvm;
@@ -27,7 +28,7 @@ namespace {
// deal with the Error value directly, rather than converting to error_code.
class ErrorErrorCategory : public std::error_category {
public:
- const char *name() const LLVM_NOEXCEPT override { return "Error"; }
+ const char *name() const noexcept override { return "Error"; }
std::string message(int condition) const override {
switch (static_cast<ErrorErrorCode>(condition)) {
@@ -111,3 +112,18 @@ void report_fatal_error(Error Err, bool GenCrashDiag) {
}
}
+
+#ifndef _MSC_VER
+namespace llvm {
+
+// One of these two variables will be referenced by a symbol defined in
+// llvm-config.h. We provide a link-time (or load time for DSO) failure when
+// there is a mismatch in the build configuration of the API client and LLVM.
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+int EnableABIBreakingChecks;
+#else
+int DisableABIBreakingChecks;
+#endif
+
+} // end namespace llvm
+#endif
diff --git a/contrib/llvm/lib/Support/FileOutputBuffer.cpp b/contrib/llvm/lib/Support/FileOutputBuffer.cpp
index 651e679..57e5a8d 100644
--- a/contrib/llvm/lib/Support/FileOutputBuffer.cpp
+++ b/contrib/llvm/lib/Support/FileOutputBuffer.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include <system_error>
@@ -28,18 +29,24 @@ using llvm::sys::fs::mapped_file_region;
namespace llvm {
FileOutputBuffer::FileOutputBuffer(std::unique_ptr<mapped_file_region> R,
- StringRef Path, StringRef TmpPath)
- : Region(std::move(R)), FinalPath(Path), TempPath(TmpPath) {}
+ StringRef Path, StringRef TmpPath,
+ bool IsRegular)
+ : Region(std::move(R)), FinalPath(Path), TempPath(TmpPath),
+ IsRegular(IsRegular) {}
FileOutputBuffer::~FileOutputBuffer() {
+ // Close the mapping before deleting the temp file, so that the removal
+ // succeeds.
+ Region.reset();
sys::fs::remove(Twine(TempPath));
}
ErrorOr<std::unique_ptr<FileOutputBuffer>>
FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) {
- // If file already exists, it must be a regular file (to be mappable).
+ // Check file is not a regular file, in which case we cannot remove it.
sys::fs::file_status Stat;
std::error_code EC = sys::fs::status(FilePath, Stat);
+ bool IsRegular = true;
switch (Stat.type()) {
case sys::fs::file_type::file_not_found:
// If file does not exist, we'll create one.
@@ -53,25 +60,34 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) {
default:
if (EC)
return EC;
- else
- return make_error_code(errc::operation_not_permitted);
+ IsRegular = false;
}
- // Delete target file.
- EC = sys::fs::remove(FilePath);
- if (EC)
- return EC;
-
- unsigned Mode = sys::fs::all_read | sys::fs::all_write;
- // If requested, make the output file executable.
- if (Flags & F_executable)
- Mode |= sys::fs::all_exe;
+ if (IsRegular) {
+ // Delete target file.
+ EC = sys::fs::remove(FilePath);
+ if (EC)
+ return EC;
+ }
- // Create new file in same directory but with random name.
SmallString<128> TempFilePath;
int FD;
- EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD,
- TempFilePath, Mode);
+ if (IsRegular) {
+ unsigned Mode = sys::fs::all_read | sys::fs::all_write;
+ // If requested, make the output file executable.
+ if (Flags & F_executable)
+ Mode |= sys::fs::all_exe;
+ // Create new file in same directory but with random name.
+ EC = sys::fs::createUniqueFile(Twine(FilePath) + ".tmp%%%%%%%", FD,
+ TempFilePath, Mode);
+ } else {
+ // Create a temporary file. Since this is a special file, we will not move
+ // it and the new file can be in another filesystem. This avoids trying to
+ // create a temporary file in /dev when outputting to /dev/null for example.
+ EC = sys::fs::createTemporaryFile(sys::path::filename(FilePath), "", FD,
+ TempFilePath);
+ }
+
if (EC)
return EC;
@@ -96,8 +112,8 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size, unsigned Flags) {
if (Ret)
return std::error_code(errno, std::generic_category());
- std::unique_ptr<FileOutputBuffer> Buf(
- new FileOutputBuffer(std::move(MappedFile), FilePath, TempFilePath));
+ std::unique_ptr<FileOutputBuffer> Buf(new FileOutputBuffer(
+ std::move(MappedFile), FilePath, TempFilePath, IsRegular));
return std::move(Buf);
}
@@ -105,10 +121,19 @@ std::error_code FileOutputBuffer::commit() {
// Unmap buffer, letting OS flush dirty pages to file on disk.
Region.reset();
+ std::error_code EC;
+ if (IsRegular) {
+ // Rename file to final name.
+ EC = sys::fs::rename(Twine(TempPath), Twine(FinalPath));
+ sys::DontRemoveFileOnSignal(TempPath);
+ } else {
+ EC = sys::fs::copy_file(TempPath, FinalPath);
+ std::error_code RMEC = sys::fs::remove(TempPath);
+ sys::DontRemoveFileOnSignal(TempPath);
+ if (RMEC)
+ return RMEC;
+ }
- // Rename file to final name.
- std::error_code EC = sys::fs::rename(Twine(TempPath), Twine(FinalPath));
- sys::DontRemoveFileOnSignal(TempPath);
return EC;
}
} // namespace
diff --git a/contrib/llvm/lib/Support/FileUtilities.cpp b/contrib/llvm/lib/Support/FileUtilities.cpp
index c6a58cc..39dbeff 100644
--- a/contrib/llvm/lib/Support/FileUtilities.cpp
+++ b/contrib/llvm/lib/Support/FileUtilities.cpp
@@ -14,13 +14,17 @@
#include "llvm/Support/FileUtilities.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
+#include <cmath>
+#include <cstdint>
#include <cstdlib>
#include <cstring>
+#include <memory>
#include <system_error>
+
using namespace llvm;
static bool isSignedChar(char C) {
@@ -215,7 +219,7 @@ int llvm::DiffFilesWithTolerance(StringRef NameA,
}
bool CompareFailed = false;
- while (1) {
+ while (true) {
// Scan for the end of file or next difference.
while (F1P < File1End && F2P < File2End && *F1P == *F2P) {
++F1P;
diff --git a/contrib/llvm/lib/Support/FoldingSet.cpp b/contrib/llvm/lib/Support/FoldingSet.cpp
index 52baf86..c9bca7f 100644
--- a/contrib/llvm/lib/Support/FoldingSet.cpp
+++ b/contrib/llvm/lib/Support/FoldingSet.cpp
@@ -54,8 +54,9 @@ void FoldingSetNodeID::AddPointer(const void *Ptr) {
// depend on the host. It doesn't matter, however, because hashing on
// pointer values is inherently unstable. Nothing should depend on the
// ordering of nodes in the folding set.
- Bits.append(reinterpret_cast<unsigned *>(&Ptr),
- reinterpret_cast<unsigned *>(&Ptr+1));
+ static_assert(sizeof(uintptr_t) <= sizeof(unsigned long long),
+ "unexpected pointer size");
+ AddInteger(reinterpret_cast<uintptr_t>(Ptr));
}
void FoldingSetNodeID::AddInteger(signed I) {
Bits.push_back(I);
@@ -80,8 +81,7 @@ void FoldingSetNodeID::AddInteger(long long I) {
}
void FoldingSetNodeID::AddInteger(unsigned long long I) {
AddInteger(unsigned(I));
- if ((uint64_t)(unsigned)I != I)
- Bits.push_back(unsigned(I >> 32));
+ AddInteger(unsigned(I >> 32));
}
void FoldingSetNodeID::AddString(StringRef String) {
@@ -127,8 +127,8 @@ void FoldingSetNodeID::AddString(StringRef String) {
// Pos will have overshot size by 4 - #bytes left over.
// No need to take endianness into account here - this is always executed.
switch (Pos - Size) {
- case 1: V = (V << 8) | (unsigned char)String[Size - 3]; // Fall thru.
- case 2: V = (V << 8) | (unsigned char)String[Size - 2]; // Fall thru.
+ case 1: V = (V << 8) | (unsigned char)String[Size - 3]; LLVM_FALLTHROUGH;
+ case 2: V = (V << 8) | (unsigned char)String[Size - 2]; LLVM_FALLTHROUGH;
case 3: V = (V << 8) | (unsigned char)String[Size - 1]; break;
default: return; // Nothing left.
}
diff --git a/contrib/llvm/lib/Support/FormatVariadic.cpp b/contrib/llvm/lib/Support/FormatVariadic.cpp
new file mode 100644
index 0000000..de61dae
--- /dev/null
+++ b/contrib/llvm/lib/Support/FormatVariadic.cpp
@@ -0,0 +1,156 @@
+//===- FormatVariadic.cpp - Format string parsing and analysis ----*-C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+
+static Optional<AlignStyle> translateLocChar(char C) {
+ switch (C) {
+ case '-':
+ return AlignStyle::Left;
+ case '=':
+ return AlignStyle::Center;
+ case '+':
+ return AlignStyle::Right;
+ default:
+ return None;
+ }
+ LLVM_BUILTIN_UNREACHABLE;
+}
+
+bool formatv_object_base::consumeFieldLayout(StringRef &Spec, AlignStyle &Where,
+ size_t &Align, char &Pad) {
+ Where = AlignStyle::Right;
+ Align = 0;
+ Pad = ' ';
+ if (Spec.empty())
+ return true;
+
+ if (Spec.size() > 1) {
+ // A maximum of 2 characters at the beginning can be used for something
+ // other
+ // than the width.
+ // If Spec[1] is a loc char, then Spec[0] is a pad char and Spec[2:...]
+ // contains the width.
+ // Otherwise, if Spec[0] is a loc char, then Spec[1:...] contains the width.
+ // Otherwise, Spec[0:...] contains the width.
+ if (auto Loc = translateLocChar(Spec[1])) {
+ Pad = Spec[0];
+ Where = *Loc;
+ Spec = Spec.drop_front(2);
+ } else if (auto Loc = translateLocChar(Spec[0])) {
+ Where = *Loc;
+ Spec = Spec.drop_front(1);
+ }
+ }
+
+ bool Failed = Spec.consumeInteger(0, Align);
+ return !Failed;
+}
+
+Optional<ReplacementItem>
+formatv_object_base::parseReplacementItem(StringRef Spec) {
+ StringRef RepString = Spec.trim("{}");
+
+ // If the replacement sequence does not start with a non-negative integer,
+ // this is an error.
+ char Pad = ' ';
+ std::size_t Align = 0;
+ AlignStyle Where = AlignStyle::Right;
+ StringRef Options;
+ size_t Index = 0;
+ RepString = RepString.trim();
+ if (RepString.consumeInteger(0, Index)) {
+ assert(false && "Invalid replacement sequence index!");
+ return ReplacementItem{};
+ }
+ RepString = RepString.trim();
+ if (!RepString.empty() && RepString.front() == ',') {
+ RepString = RepString.drop_front();
+ if (!consumeFieldLayout(RepString, Where, Align, Pad))
+ assert(false && "Invalid replacement field layout specification!");
+ }
+ RepString = RepString.trim();
+ if (!RepString.empty() && RepString.front() == ':') {
+ Options = RepString.drop_front().trim();
+ RepString = StringRef();
+ }
+ RepString = RepString.trim();
+ if (!RepString.empty()) {
+ assert(false && "Unexpected characters found in replacement string!");
+ }
+
+ return ReplacementItem{Spec, Index, Align, Where, Pad, Options};
+}
+
+std::pair<ReplacementItem, StringRef>
+formatv_object_base::splitLiteralAndReplacement(StringRef Fmt) {
+ StringRef Rep;
+ StringRef Remainder;
+ std::size_t From = 0;
+ while (From < Fmt.size() && From != StringRef::npos) {
+ std::size_t BO = Fmt.find_first_of('{', From);
+ // Everything up until the first brace is a literal.
+ if (BO != 0)
+ return std::make_pair(ReplacementItem{Fmt.substr(0, BO)}, Fmt.substr(BO));
+
+ StringRef Braces =
+ Fmt.drop_front(BO).take_while([](char C) { return C == '{'; });
+ // If there is more than one brace, then some of them are escaped. Treat
+ // these as replacements.
+ if (Braces.size() > 1) {
+ size_t NumEscapedBraces = Braces.size() / 2;
+ StringRef Middle = Fmt.substr(BO, NumEscapedBraces);
+ StringRef Right = Fmt.drop_front(BO + NumEscapedBraces * 2);
+ return std::make_pair(ReplacementItem{Middle}, Right);
+ }
+ // An unterminated open brace is undefined. We treat the rest of the string
+ // as a literal replacement, but we assert to indicate that this is
+ // undefined and that we consider it an error.
+ std::size_t BC = Fmt.find_first_of('}', BO);
+ if (BC == StringRef::npos) {
+ assert(
+ false &&
+ "Unterminated brace sequence. Escape with {{ for a literal brace.");
+ return std::make_pair(ReplacementItem{Fmt}, StringRef());
+ }
+
+ // Even if there is a closing brace, if there is another open brace before
+ // this closing brace, treat this portion as literal, and try again with the
+ // next one.
+ std::size_t BO2 = Fmt.find_first_of('{', BO + 1);
+ if (BO2 < BC)
+ return std::make_pair(ReplacementItem{Fmt.substr(0, BO2)},
+ Fmt.substr(BO2));
+
+ StringRef Spec = Fmt.slice(BO + 1, BC);
+ StringRef Right = Fmt.substr(BC + 1);
+
+ auto RI = parseReplacementItem(Spec);
+ if (RI.hasValue())
+ return std::make_pair(*RI, Right);
+
+ // If there was an error parsing the replacement item, treat it as an
+ // invalid replacement spec, and just continue.
+ From = BC + 1;
+ }
+ return std::make_pair(ReplacementItem{Fmt}, StringRef());
+}
+
+std::vector<ReplacementItem>
+formatv_object_base::parseFormatString(StringRef Fmt) {
+ std::vector<ReplacementItem> Replacements;
+ ReplacementItem I;
+ while (!Fmt.empty()) {
+ std::tie(I, Fmt) = splitLiteralAndReplacement(Fmt);
+ if (I.Type != ReplacementType::Empty)
+ Replacements.push_back(I);
+ }
+ return Replacements;
+}
diff --git a/contrib/llvm/lib/Support/GlobPattern.cpp b/contrib/llvm/lib/Support/GlobPattern.cpp
new file mode 100644
index 0000000..8ee2feb
--- /dev/null
+++ b/contrib/llvm/lib/Support/GlobPattern.cpp
@@ -0,0 +1,167 @@
+//===-- GlobPattern.cpp - Glob pattern matcher implementation -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a glob pattern matcher.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/GlobPattern.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errc.h"
+
+using namespace llvm;
+
+static bool hasWildcard(StringRef S) {
+ return S.find_first_of("?*[") != StringRef::npos;
+}
+
+// Expands character ranges and returns a bitmap.
+// For example, "a-cf-hz" is expanded to "abcfghz".
+static Expected<BitVector> expand(StringRef S, StringRef Original) {
+ BitVector BV(256, false);
+
+ // Expand X-Y.
+ for (;;) {
+ if (S.size() < 3)
+ break;
+
+ // If it doesn't start with something like X-Y,
+ // consume the first character and proceed.
+ if (S[1] != '-') {
+ BV[S[0]] = true;
+ S = S.substr(1);
+ continue;
+ }
+
+ // It must be in the form of X-Y.
+ // Validate it and then interpret the range.
+ if (S[0] > S[2])
+ return make_error<StringError>("invalid glob pattern: " + Original,
+ errc::invalid_argument);
+
+ for (int C = S[0]; C <= S[2]; ++C)
+ BV[C] = true;
+ S = S.substr(3);
+ }
+
+ for (char C : S)
+ BV[C] = true;
+ return BV;
+}
+
+// This is a scanner for the glob pattern.
+// A glob pattern token is one of "*", "?", "[<chars>]", "[^<chars>]"
+// (which is a negative form of "[<chars>]"), or a non-meta character.
+// This function returns the first token in S.
+static Expected<BitVector> scan(StringRef &S, StringRef Original) {
+ switch (S[0]) {
+ case '*':
+ S = S.substr(1);
+ // '*' is represented by an empty bitvector.
+ // All other bitvectors are 256-bit long.
+ return BitVector();
+ case '?':
+ S = S.substr(1);
+ return BitVector(256, true);
+ case '[': {
+ size_t End = S.find(']', 1);
+ if (End == StringRef::npos)
+ return make_error<StringError>("invalid glob pattern: " + Original,
+ errc::invalid_argument);
+
+ StringRef Chars = S.substr(1, End - 1);
+ S = S.substr(End + 1);
+ if (Chars.startswith("^")) {
+ Expected<BitVector> BV = expand(Chars.substr(1), Original);
+ if (!BV)
+ return BV.takeError();
+ return BV->flip();
+ }
+ return expand(Chars, Original);
+ }
+ default:
+ BitVector BV(256, false);
+ BV[S[0]] = true;
+ S = S.substr(1);
+ return BV;
+ }
+}
+
+Expected<GlobPattern> GlobPattern::create(StringRef S) {
+ GlobPattern Pat;
+
+ // S doesn't contain any metacharacter,
+ // so the regular string comparison should work.
+ if (!hasWildcard(S)) {
+ Pat.Exact = S;
+ return Pat;
+ }
+
+ // S is something like "foo*". We can use startswith().
+ if (S.endswith("*") && !hasWildcard(S.drop_back())) {
+ Pat.Prefix = S.drop_back();
+ return Pat;
+ }
+
+ // S is something like "*foo". We can use endswith().
+ if (S.startswith("*") && !hasWildcard(S.drop_front())) {
+ Pat.Suffix = S.drop_front();
+ return Pat;
+ }
+
+ // Otherwise, we need to do real glob pattern matching.
+ // Parse the pattern now.
+ StringRef Original = S;
+ while (!S.empty()) {
+ Expected<BitVector> BV = scan(S, Original);
+ if (!BV)
+ return BV.takeError();
+ Pat.Tokens.push_back(*BV);
+ }
+ return Pat;
+}
+
+bool GlobPattern::match(StringRef S) const {
+ if (Exact)
+ return S == *Exact;
+ if (Prefix)
+ return S.startswith(*Prefix);
+ if (Suffix)
+ return S.endswith(*Suffix);
+ return matchOne(Tokens, S);
+}
+
+// Runs glob pattern Pats against string S.
+bool GlobPattern::matchOne(ArrayRef<BitVector> Pats, StringRef S) const {
+ for (;;) {
+ if (Pats.empty())
+ return S.empty();
+
+ // If Pats[0] is '*', try to match Pats[1..] against all possible
+ // tail strings of S to see at least one pattern succeeds.
+ if (Pats[0].size() == 0) {
+ Pats = Pats.slice(1);
+ if (Pats.empty())
+ // Fast path. If a pattern is '*', it matches anything.
+ return true;
+ for (size_t I = 0, E = S.size(); I < E; ++I)
+ if (matchOne(Pats, S.substr(I)))
+ return true;
+ return false;
+ }
+
+ // If Pats[0] is not '*', it must consume one character.
+ if (S.empty() || !Pats[0][S[0]])
+ return false;
+ Pats = Pats.slice(1);
+ S = S.substr(1);
+ }
+}
diff --git a/contrib/llvm/lib/Support/Host.cpp b/contrib/llvm/lib/Support/Host.cpp
index 12ac19d..d1b4041 100644
--- a/contrib/llvm/lib/Support/Host.cpp
+++ b/contrib/llvm/lib/Support/Host.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Host.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
@@ -19,7 +20,9 @@
#include "llvm/Config/config.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
+#include <assert.h>
#include <string.h>
// Include the platform-specific parts of this class.
@@ -69,9 +72,8 @@ static ssize_t LLVM_ATTRIBUTE_UNUSED readCpuInfo(void *Buf, size_t Size) {
}
#endif
-#if defined(i386) || defined(__i386__) || defined(__x86__) || \
- defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) || \
- defined(_M_X64)
+#if defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64__) || defined(_M_X64)
enum VendorSignatures {
SIG_INTEL = 0x756e6547 /* Genu */,
@@ -109,6 +111,7 @@ enum ProcessorTypes {
AMDATHLON,
AMDFAM14H,
AMDFAM16H,
+ AMDFAM17H,
CPU_TYPE_MAX
};
@@ -147,6 +150,7 @@ enum ProcessorSubtypes {
AMD_BTVER2,
AMDFAM15H_BDVER3,
AMDFAM15H_BDVER4,
+ AMDFAM17H_ZNVER1,
CPU_SUBTYPE_MAX
};
@@ -169,30 +173,63 @@ enum ProcessorFeatures {
FEATURE_EM64T
};
+// The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
+// Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
+// support. Consequently, for i386, the presence of CPUID is checked first
+// via the corresponding eflags bit.
+// Removal of cpuid.h header motivated by PR30384
+// Header cpuid.h and method __get_cpuid_max are not used in llvm, clang, openmp
+// or test-suite, but are used in external projects e.g. libstdcxx
+static bool isCpuIdSupported() {
+#if defined(__GNUC__) || defined(__clang__)
+#if defined(__i386__)
+ int __cpuid_supported;
+ __asm__(" pushfl\n"
+ " popl %%eax\n"
+ " movl %%eax,%%ecx\n"
+ " xorl $0x00200000,%%eax\n"
+ " pushl %%eax\n"
+ " popfl\n"
+ " pushfl\n"
+ " popl %%eax\n"
+ " movl $0,%0\n"
+ " cmpl %%eax,%%ecx\n"
+ " je 1f\n"
+ " movl $1,%0\n"
+ "1:"
+ : "=r"(__cpuid_supported)
+ :
+ : "eax", "ecx");
+ if (!__cpuid_supported)
+ return false;
+#endif
+ return true;
+#endif
+ return true;
+}
+
/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in
/// the specified arguments. If we can't run cpuid on the host, return true.
static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
unsigned *rECX, unsigned *rEDX) {
+#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
#if defined(__GNUC__) || defined(__clang__)
-#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
- // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
- asm("movq\t%%rbx, %%rsi\n\t"
- "cpuid\n\t"
- "xchgq\t%%rbx, %%rsi\n\t"
- : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
- : "a"(value));
- return false;
-#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
- asm("movl\t%%ebx, %%esi\n\t"
- "cpuid\n\t"
- "xchgl\t%%ebx, %%esi\n\t"
- : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
- : "a"(value));
- return false;
-// pedantic #else returns to appease -Wunreachable-code (so we don't generate
-// postprocessed code that looks like "return true; return false;")
+#if defined(__x86_64__)
+ // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually.
+ // FIXME: should we save this for Clang?
+ __asm__("movq\t%%rbx, %%rsi\n\t"
+ "cpuid\n\t"
+ "xchgq\t%%rbx, %%rsi\n\t"
+ : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
+ : "a"(value));
+#elif defined(__i386__)
+ __asm__("movl\t%%ebx, %%esi\n\t"
+ "cpuid\n\t"
+ "xchgl\t%%ebx, %%esi\n\t"
+ : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
+ : "a"(value));
#else
- return true;
+ assert(0 && "This method is defined only for x86.");
#endif
#elif defined(_MSC_VER)
// The MSVC intrinsic is portable across x86 and x64.
@@ -202,6 +239,7 @@ static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
*rEBX = registers[1];
*rECX = registers[2];
*rEDX = registers[3];
+#endif
return false;
#else
return true;
@@ -214,15 +252,16 @@ static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
unsigned *rEAX, unsigned *rEBX, unsigned *rECX,
unsigned *rEDX) {
-#if defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
+#if defined(__x86_64__) || defined(_M_X64)
+#if defined(__GNUC__) || defined(__clang__)
// gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
- asm("movq\t%%rbx, %%rsi\n\t"
- "cpuid\n\t"
- "xchgq\t%%rbx, %%rsi\n\t"
- : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
- : "a"(value), "c"(subleaf));
- return false;
+ // FIXME: should we save this for Clang?
+ __asm__("movq\t%%rbx, %%rsi\n\t"
+ "cpuid\n\t"
+ "xchgq\t%%rbx, %%rsi\n\t"
+ : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
+ : "a"(value), "c"(subleaf));
#elif defined(_MSC_VER)
int registers[4];
__cpuidex(registers, value, subleaf);
@@ -230,18 +269,14 @@ static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
*rEBX = registers[1];
*rECX = registers[2];
*rEDX = registers[3];
- return false;
-#else
- return true;
#endif
-#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
-#if defined(__GNUC__)
- asm("movl\t%%ebx, %%esi\n\t"
- "cpuid\n\t"
- "xchgl\t%%ebx, %%esi\n\t"
- : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
- : "a"(value), "c"(subleaf));
- return false;
+#elif defined(__i386__) || defined(_M_IX86)
+#if defined(__GNUC__) || defined(__clang__)
+ __asm__("movl\t%%ebx, %%esi\n\t"
+ "cpuid\n\t"
+ "xchgl\t%%ebx, %%esi\n\t"
+ : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX)
+ : "a"(value), "c"(subleaf));
#elif defined(_MSC_VER)
__asm {
mov eax,value
@@ -256,17 +291,18 @@ static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
mov esi,rEDX
mov dword ptr [esi],edx
}
- return false;
+#endif
#else
- return true;
+ assert(0 && "This method is defined only for x86.");
#endif
+ return false;
#else
return true;
#endif
}
static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) {
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__clang__)
// Check xgetbv; this uses a .byte sequence instead of the instruction
// directly because older assemblers do not include support for xgetbv and
// there is no easy way to conditionally compile based on the assembler used.
@@ -440,15 +476,25 @@ getIntelProcessorTypeAndSubtype(unsigned int Family, unsigned int Model,
break;
// Skylake:
- case 0x4e:
- *Type = INTEL_COREI7; // "skylake-avx512"
- *Subtype = INTEL_COREI7_SKYLAKE_AVX512;
- break;
- case 0x5e:
+ case 0x4e: // Skylake mobile
+ case 0x5e: // Skylake desktop
+ case 0x8e: // Kaby Lake mobile
+ case 0x9e: // Kaby Lake desktop
*Type = INTEL_COREI7; // "skylake"
*Subtype = INTEL_COREI7_SKYLAKE;
break;
+ // Skylake Xeon:
+ case 0x55:
+ *Type = INTEL_COREI7;
+ // Check that we really have AVX512
+ if (Features & (1 << FEATURE_AVX512)) {
+ *Subtype = INTEL_COREI7_SKYLAKE_AVX512; // "skylake-avx512"
+ } else {
+ *Subtype = INTEL_COREI7_SKYLAKE; // "skylake"
+ }
+ break;
+
case 0x1c: // Most 45 nm Intel Atom processors
case 0x26: // 45 nm Atom Lincroft
case 0x27: // 32 nm Atom Medfield
@@ -698,6 +744,14 @@ static void getAMDProcessorTypeAndSubtype(unsigned int Family,
}
*Subtype = AMD_BTVER2;
break; // "btver2"
+ case 23:
+ *Type = AMDFAM17H;
+ if (Features & (1 << FEATURE_ADX)) {
+ *Subtype = AMDFAM17H_ZNVER1;
+ break; // "znver1"
+ }
+ *Subtype = AMD_BTVER1;
+ break;
default:
break; // "generic"
}
@@ -743,6 +797,14 @@ StringRef sys::getHostCPUName() {
unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
unsigned MaxLeaf, Vendor;
+#if defined(__GNUC__) || defined(__clang__)
+ //FIXME: include cpuid.h from clang or copy __get_cpuid_max here
+ // and simplify it to not invoke __cpuid (like cpu_model.c in
+ // compiler-rt/lib/builtins/cpu_model.c?
+ // Opting for the second option.
+ if(!isCpuIdSupported())
+ return "generic";
+#endif
if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX))
return "generic";
if (getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX))
@@ -898,6 +960,15 @@ StringRef sys::getHostCPUName() {
default:
return "amdfam16";
}
+ case AMDFAM17H:
+ switch (Subtype) {
+ case AMD_BTVER1:
+ return "btver1";
+ case AMDFAM17H_ZNVER1:
+ return "znver1";
+ default:
+ return "amdfam17";
+ }
default:
return "generic";
}
@@ -1027,6 +1098,7 @@ StringRef sys::getHostCPUName() {
.Case("POWER7", "pwr7")
.Case("POWER8", "pwr8")
.Case("POWER8E", "pwr8")
+ .Case("POWER8NVL", "pwr8")
.Case("POWER9", "pwr9")
.Default(generic);
}
@@ -1148,9 +1220,81 @@ StringRef sys::getHostCPUName() {
StringRef sys::getHostCPUName() { return "generic"; }
#endif
-#if defined(i386) || defined(__i386__) || defined(__x86__) || \
- defined(_M_IX86) || defined(__x86_64__) || defined(_M_AMD64) || \
- defined(_M_X64)
+#if defined(__linux__) && defined(__x86_64__)
+// On Linux, the number of physical cores can be computed from /proc/cpuinfo,
+// using the number of unique physical/core id pairs. The following
+// implementation reads the /proc/cpuinfo format on an x86_64 system.
+static int computeHostNumPhysicalCores() {
+ // Read /proc/cpuinfo as a stream (until EOF reached). It cannot be
+ // mmapped because it appears to have 0 size.
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Text =
+ llvm::MemoryBuffer::getFileAsStream("/proc/cpuinfo");
+ if (std::error_code EC = Text.getError()) {
+ llvm::errs() << "Can't read "
+ << "/proc/cpuinfo: " << EC.message() << "\n";
+ }
+ SmallVector<StringRef, 8> strs;
+ (*Text)->getBuffer().split(strs, "\n", /*MaxSplit=*/-1,
+ /*KeepEmpty=*/false);
+ int CurPhysicalId = -1;
+ int CurCoreId = -1;
+ SmallSet<std::pair<int, int>, 32> UniqueItems;
+ for (auto &Line : strs) {
+ Line = Line.trim();
+ if (!Line.startswith("physical id") && !Line.startswith("core id"))
+ continue;
+ std::pair<StringRef, StringRef> Data = Line.split(':');
+ auto Name = Data.first.trim();
+ auto Val = Data.second.trim();
+ if (Name == "physical id") {
+ assert(CurPhysicalId == -1 &&
+ "Expected a core id before seeing another physical id");
+ Val.getAsInteger(10, CurPhysicalId);
+ }
+ if (Name == "core id") {
+ assert(CurCoreId == -1 &&
+ "Expected a physical id before seeing another core id");
+ Val.getAsInteger(10, CurCoreId);
+ }
+ if (CurPhysicalId != -1 && CurCoreId != -1) {
+ UniqueItems.insert(std::make_pair(CurPhysicalId, CurCoreId));
+ CurPhysicalId = -1;
+ CurCoreId = -1;
+ }
+ }
+ return UniqueItems.size();
+}
+#elif defined(__APPLE__) && defined(__x86_64__)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+// Gets the number of *physical cores* on the machine.
+static int computeHostNumPhysicalCores() {
+ uint32_t count;
+ size_t len = sizeof(count);
+ sysctlbyname("hw.physicalcpu", &count, &len, NULL, 0);
+ if (count < 1) {
+ int nm[2];
+ nm[0] = CTL_HW;
+ nm[1] = HW_AVAILCPU;
+ sysctl(nm, 2, &count, &len, NULL, 0);
+ if (count < 1)
+ return -1;
+ }
+ return count;
+}
+#else
+// On other systems, return -1 to indicate unknown.
+static int computeHostNumPhysicalCores() { return -1; }
+#endif
+
+int sys::getHostNumPhysicalCores() {
+ static int NumCores = computeHostNumPhysicalCores();
+ return NumCores;
+}
+
+#if defined(__i386__) || defined(_M_IX86) || \
+ defined(__x86_64__) || defined(_M_X64)
bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
unsigned MaxLevel;
diff --git a/contrib/llvm/lib/Support/IntrusiveRefCntPtr.cpp b/contrib/llvm/lib/Support/IntrusiveRefCntPtr.cpp
deleted file mode 100644
index a8b4559..0000000
--- a/contrib/llvm/lib/Support/IntrusiveRefCntPtr.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-//== IntrusiveRefCntPtr.cpp - Smart Refcounting Pointer ----------*- C++ -*-==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/IntrusiveRefCntPtr.h"
-
-using namespace llvm;
-
-void RefCountedBaseVPTR::anchor() { }
diff --git a/contrib/llvm/lib/Support/LockFileManager.cpp b/contrib/llvm/lib/Support/LockFileManager.cpp
index 611f94a..444aaa3 100644
--- a/contrib/llvm/lib/Support/LockFileManager.cpp
+++ b/contrib/llvm/lib/Support/LockFileManager.cpp
@@ -6,13 +6,22 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+
#include "llvm/Support/LockFileManager.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
+#include <cerrno>
+#include <ctime>
+#include <memory>
+#include <tuple>
+#include <system_error>
#include <sys/stat.h>
#include <sys/types.h>
#if LLVM_ON_WIN32
@@ -31,6 +40,7 @@
#if USE_OSX_GETHOSTUUID
#include <uuid/uuid.h>
#endif
+
using namespace llvm;
/// \brief Attempt to read the lock file with the given name, if it exists.
@@ -112,6 +122,7 @@ bool LockFileManager::processStillExecuting(StringRef HostID, int PID) {
}
namespace {
+
/// An RAII helper object ensure that the unique lock file is removed.
///
/// Ensures that if there is an error or a signal before we finish acquiring the
@@ -127,6 +138,7 @@ public:
: Filename(Name), RemoveImmediately(true) {
sys::RemoveFileOnSignal(Filename, nullptr);
}
+
~RemoveUniqueLockFileOnSignal() {
if (!RemoveImmediately) {
// Leave the signal handler enabled. It will be removed when the lock is
@@ -136,8 +148,10 @@ public:
sys::fs::remove(Filename);
sys::DontRemoveFileOnSignal(Filename);
}
+
void lockAcquired() { RemoveImmediately = false; }
};
+
} // end anonymous namespace
LockFileManager::LockFileManager(StringRef FileName)
@@ -202,7 +216,7 @@ LockFileManager::LockFileManager(StringRef FileName)
// held since the .lock symlink will point to a nonexistent file.
RemoveUniqueLockFileOnSignal RemoveUniqueFile(UniqueLockFileName);
- while (1) {
+ while (true) {
// Create a link from the lock file name. If this succeeds, we're done.
std::error_code EC =
sys::fs::create_link(UniqueLockFileName, LockFileName);
diff --git a/contrib/llvm/lib/Support/MD5.cpp b/contrib/llvm/lib/Support/MD5.cpp
index ceab580..942571e 100644
--- a/contrib/llvm/lib/Support/MD5.cpp
+++ b/contrib/llvm/lib/Support/MD5.cpp
@@ -248,33 +248,15 @@ void MD5::final(MD5Result &Result) {
memset(&buffer[used], 0, free - 8);
lo <<= 3;
- buffer[56] = lo;
- buffer[57] = lo >> 8;
- buffer[58] = lo >> 16;
- buffer[59] = lo >> 24;
- buffer[60] = hi;
- buffer[61] = hi >> 8;
- buffer[62] = hi >> 16;
- buffer[63] = hi >> 24;
+ support::endian::write32le(&buffer[56], lo);
+ support::endian::write32le(&buffer[60], hi);
body(makeArrayRef(buffer, 64));
- Result[0] = a;
- Result[1] = a >> 8;
- Result[2] = a >> 16;
- Result[3] = a >> 24;
- Result[4] = b;
- Result[5] = b >> 8;
- Result[6] = b >> 16;
- Result[7] = b >> 24;
- Result[8] = c;
- Result[9] = c >> 8;
- Result[10] = c >> 16;
- Result[11] = c >> 24;
- Result[12] = d;
- Result[13] = d >> 8;
- Result[14] = d >> 16;
- Result[15] = d >> 24;
+ support::endian::write32le(&Result[0], a);
+ support::endian::write32le(&Result[4], b);
+ support::endian::write32le(&Result[8], c);
+ support::endian::write32le(&Result[12], d);
}
void MD5::stringifyResult(MD5Result &Result, SmallString<32> &Str) {
@@ -283,4 +265,14 @@ void MD5::stringifyResult(MD5Result &Result, SmallString<32> &Str) {
Res << format("%.2x", Result[i]);
}
+std::array<uint8_t, 16> MD5::hash(ArrayRef<uint8_t> Data) {
+ MD5 Hash;
+ Hash.update(Data);
+ MD5::MD5Result Res;
+ Hash.final(Res);
+
+ std::array<uint8_t, 16> Arr;
+ memcpy(Arr.data(), Res, sizeof(Res));
+ return Arr;
+}
}
diff --git a/contrib/llvm/lib/Support/MemoryBuffer.cpp b/contrib/llvm/lib/Support/MemoryBuffer.cpp
index b935cbf..a3a18c9 100644
--- a/contrib/llvm/lib/Support/MemoryBuffer.cpp
+++ b/contrib/llvm/lib/Support/MemoryBuffer.cpp
@@ -90,9 +90,9 @@ public:
/// tail-allocated data.
void operator delete(void *p) { ::operator delete(p); }
- const char *getBufferIdentifier() const override {
- // The name is stored after the class itself.
- return reinterpret_cast<const char*>(this + 1);
+ StringRef getBufferIdentifier() const override {
+ // The name is stored after the class itself.
+ return StringRef(reinterpret_cast<const char *>(this + 1));
}
BufferKind getBufferKind() const override {
@@ -221,9 +221,9 @@ public:
/// tail-allocated data.
void operator delete(void *p) { ::operator delete(p); }
- const char *getBufferIdentifier() const override {
+ StringRef getBufferIdentifier() const override {
// The name is stored after the class itself.
- return reinterpret_cast<const char *>(this + 1);
+ return StringRef(reinterpret_cast<const char *>(this + 1));
}
BufferKind getBufferKind() const override {
@@ -438,6 +438,18 @@ ErrorOr<std::unique_ptr<MemoryBuffer>> MemoryBuffer::getSTDIN() {
return getMemoryBufferForStream(0, "<stdin>");
}
+ErrorOr<std::unique_ptr<MemoryBuffer>>
+MemoryBuffer::getFileAsStream(const Twine &Filename) {
+ int FD;
+ std::error_code EC = sys::fs::openFileForRead(Filename, FD);
+ if (EC)
+ return EC;
+ ErrorOr<std::unique_ptr<MemoryBuffer>> Ret =
+ getMemoryBufferForStream(FD, Filename);
+ close(FD);
+ return Ret;
+}
+
MemoryBufferRef MemoryBuffer::getMemBufferRef() const {
StringRef Data = getBuffer();
StringRef Identifier = getBufferIdentifier();
diff --git a/contrib/llvm/lib/Support/MemoryObject.cpp b/contrib/llvm/lib/Support/MemoryObject.cpp
deleted file mode 100644
index d796acf..0000000
--- a/contrib/llvm/lib/Support/MemoryObject.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-//===- MemoryObject.cpp - Abstract memory interface -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/MemoryObject.h"
-using namespace llvm;
-
-MemoryObject::~MemoryObject() {
-}
diff --git a/contrib/llvm/lib/Support/NativeFormatting.cpp b/contrib/llvm/lib/Support/NativeFormatting.cpp
new file mode 100644
index 0000000..b951a88
--- /dev/null
+++ b/contrib/llvm/lib/Support/NativeFormatting.cpp
@@ -0,0 +1,262 @@
+//===- NativeFormatting.cpp - Low level formatting helpers -------*- C++-*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/NativeFormatting.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Format.h"
+
+using namespace llvm;
+
+template<typename T, std::size_t N>
+static int format_to_buffer(T Value, char (&Buffer)[N]) {
+ char *EndPtr = std::end(Buffer);
+ char *CurPtr = EndPtr;
+
+ do {
+ *--CurPtr = '0' + char(Value % 10);
+ Value /= 10;
+ } while (Value);
+ return EndPtr - CurPtr;
+}
+
+static void writeWithCommas(raw_ostream &S, ArrayRef<char> Buffer) {
+ assert(!Buffer.empty());
+
+ ArrayRef<char> ThisGroup;
+ int InitialDigits = ((Buffer.size() - 1) % 3) + 1;
+ ThisGroup = Buffer.take_front(InitialDigits);
+ S.write(ThisGroup.data(), ThisGroup.size());
+
+ Buffer = Buffer.drop_front(InitialDigits);
+ assert(Buffer.size() % 3 == 0);
+ while (!Buffer.empty()) {
+ S << ',';
+ ThisGroup = Buffer.take_front(3);
+ S.write(ThisGroup.data(), 3);
+ Buffer = Buffer.drop_front(3);
+ }
+}
+
+template <typename T>
+static void write_unsigned_impl(raw_ostream &S, T N, size_t MinDigits,
+ IntegerStyle Style, bool IsNegative) {
+ static_assert(std::is_unsigned<T>::value, "Value is not unsigned!");
+
+ char NumberBuffer[128];
+ std::memset(NumberBuffer, '0', sizeof(NumberBuffer));
+
+ size_t Len = 0;
+ Len = format_to_buffer(N, NumberBuffer);
+
+ if (IsNegative)
+ S << '-';
+
+ if (Len < MinDigits && Style != IntegerStyle::Number) {
+ for (size_t I = Len; I < MinDigits; ++I)
+ S << '0';
+ }
+
+ if (Style == IntegerStyle::Number) {
+ writeWithCommas(S, ArrayRef<char>(std::end(NumberBuffer) - Len, Len));
+ } else {
+ S.write(std::end(NumberBuffer) - Len, Len);
+ }
+}
+
+template <typename T>
+static void write_unsigned(raw_ostream &S, T N, size_t MinDigits,
+ IntegerStyle Style, bool IsNegative = false) {
+ // Output using 32-bit div/mod if possible.
+ if (N == static_cast<uint32_t>(N))
+ write_unsigned_impl(S, static_cast<uint32_t>(N), MinDigits, Style,
+ IsNegative);
+ else
+ write_unsigned_impl(S, N, MinDigits, Style, IsNegative);
+}
+
+template <typename T>
+static void write_signed(raw_ostream &S, T N, size_t MinDigits,
+ IntegerStyle Style) {
+ static_assert(std::is_signed<T>::value, "Value is not signed!");
+
+ using UnsignedT = typename std::make_unsigned<T>::type;
+
+ if (N >= 0) {
+ write_unsigned(S, static_cast<UnsignedT>(N), MinDigits, Style);
+ return;
+ }
+
+ UnsignedT UN = -(UnsignedT)N;
+ write_unsigned(S, UN, MinDigits, Style, true);
+}
+
+void llvm::write_integer(raw_ostream &S, unsigned int N, size_t MinDigits,
+ IntegerStyle Style) {
+ write_unsigned(S, N, MinDigits, Style);
+}
+
+void llvm::write_integer(raw_ostream &S, int N, size_t MinDigits,
+ IntegerStyle Style) {
+ write_signed(S, N, MinDigits, Style);
+}
+
+void llvm::write_integer(raw_ostream &S, unsigned long N, size_t MinDigits,
+ IntegerStyle Style) {
+ write_unsigned(S, N, MinDigits, Style);
+}
+
+void llvm::write_integer(raw_ostream &S, long N, size_t MinDigits,
+ IntegerStyle Style) {
+ write_signed(S, N, MinDigits, Style);
+}
+
+void llvm::write_integer(raw_ostream &S, unsigned long long N, size_t MinDigits,
+ IntegerStyle Style) {
+ write_unsigned(S, N, MinDigits, Style);
+}
+
+void llvm::write_integer(raw_ostream &S, long long N, size_t MinDigits,
+ IntegerStyle Style) {
+ write_signed(S, N, MinDigits, Style);
+}
+
+void llvm::write_hex(raw_ostream &S, uint64_t N, HexPrintStyle Style,
+ Optional<size_t> Width) {
+ const size_t kMaxWidth = 128u;
+
+ size_t W = std::min(kMaxWidth, Width.getValueOr(0u));
+
+ unsigned Nibbles = (64 - countLeadingZeros(N) + 3) / 4;
+ bool Prefix = (Style == HexPrintStyle::PrefixLower ||
+ Style == HexPrintStyle::PrefixUpper);
+ bool Upper =
+ (Style == HexPrintStyle::Upper || Style == HexPrintStyle::PrefixUpper);
+ unsigned PrefixChars = Prefix ? 2 : 0;
+ unsigned NumChars =
+ std::max(static_cast<unsigned>(W), std::max(1u, Nibbles) + PrefixChars);
+
+ char NumberBuffer[kMaxWidth];
+ ::memset(NumberBuffer, '0', llvm::array_lengthof(NumberBuffer));
+ if (Prefix)
+ NumberBuffer[1] = 'x';
+ char *EndPtr = NumberBuffer + NumChars;
+ char *CurPtr = EndPtr;
+ while (N) {
+ unsigned char x = static_cast<unsigned char>(N) % 16;
+ *--CurPtr = hexdigit(x, !Upper);
+ N /= 16;
+ }
+
+ S.write(NumberBuffer, NumChars);
+}
+
+void llvm::write_double(raw_ostream &S, double N, FloatStyle Style,
+ Optional<size_t> Precision) {
+ size_t Prec = Precision.getValueOr(getDefaultPrecision(Style));
+
+ if (std::isnan(N)) {
+ S << "nan";
+ return;
+ } else if (std::isinf(N)) {
+ S << "INF";
+ return;
+ }
+
+ char Letter;
+ if (Style == FloatStyle::Exponent)
+ Letter = 'e';
+ else if (Style == FloatStyle::ExponentUpper)
+ Letter = 'E';
+ else
+ Letter = 'f';
+
+ SmallString<8> Spec;
+ llvm::raw_svector_ostream Out(Spec);
+ Out << "%." << Prec << Letter;
+
+ if (Style == FloatStyle::Exponent || Style == FloatStyle::ExponentUpper) {
+#ifdef _WIN32
+// On MSVCRT and compatible, output of %e is incompatible to Posix
+// by default. Number of exponent digits should be at least 2. "%+03d"
+// FIXME: Implement our formatter to here or Support/Format.h!
+#if defined(__MINGW32__)
+ // FIXME: It should be generic to C++11.
+ if (N == 0.0 && std::signbit(N)) {
+ char NegativeZero[] = "-0.000000e+00";
+ if (Style == FloatStyle::ExponentUpper)
+ NegativeZero[strlen(NegativeZero) - 4] = 'E';
+ S << NegativeZero;
+ return;
+ }
+#else
+ int fpcl = _fpclass(N);
+
+ // negative zero
+ if (fpcl == _FPCLASS_NZ) {
+ char NegativeZero[] = "-0.000000e+00";
+ if (Style == FloatStyle::ExponentUpper)
+ NegativeZero[strlen(NegativeZero) - 4] = 'E';
+ S << NegativeZero;
+ return;
+ }
+#endif
+
+ char buf[32];
+ unsigned len;
+ len = format(Spec.c_str(), N).snprint(buf, sizeof(buf));
+ if (len <= sizeof(buf) - 2) {
+ if (len >= 5 && (buf[len - 5] == 'e' || buf[len - 5] == 'E') &&
+ buf[len - 3] == '0') {
+ int cs = buf[len - 4];
+ if (cs == '+' || cs == '-') {
+ int c1 = buf[len - 2];
+ int c0 = buf[len - 1];
+ if (isdigit(static_cast<unsigned char>(c1)) &&
+ isdigit(static_cast<unsigned char>(c0))) {
+ // Trim leading '0': "...e+012" -> "...e+12\0"
+ buf[len - 3] = c1;
+ buf[len - 2] = c0;
+ buf[--len] = 0;
+ }
+ }
+ }
+ S << buf;
+ return;
+ }
+#endif
+ }
+
+ if (Style == FloatStyle::Percent)
+ N *= 100.0;
+
+ char Buf[32];
+ format(Spec.c_str(), N).snprint(Buf, sizeof(Buf));
+ S << Buf;
+ if (Style == FloatStyle::Percent)
+ S << '%';
+}
+
+bool llvm::isPrefixedHexStyle(HexPrintStyle S) {
+ return (S == HexPrintStyle::PrefixLower || S == HexPrintStyle::PrefixUpper);
+}
+
+size_t llvm::getDefaultPrecision(FloatStyle Style) {
+ switch (Style) {
+ case FloatStyle::Exponent:
+ case FloatStyle::ExponentUpper:
+ return 6; // Number of decimal places.
+ case FloatStyle::Fixed:
+ case FloatStyle::Percent:
+ return 2; // Number of decimal places.
+ }
+ LLVM_BUILTIN_UNREACHABLE;
+}
diff --git a/contrib/llvm/lib/Support/Path.cpp b/contrib/llvm/lib/Support/Path.cpp
index f6355d1..4bb035e 100644
--- a/contrib/llvm/lib/Support/Path.cpp
+++ b/contrib/llvm/lib/Support/Path.cpp
@@ -571,6 +571,16 @@ void native(SmallVectorImpl<char> &Path) {
#endif
}
+std::string convert_to_slash(StringRef path) {
+#ifdef LLVM_ON_WIN32
+ std::string s = path.str();
+ std::replace(s.begin(), s.end(), '\\', '/');
+ return s;
+#else
+ return path;
+#endif
+}
+
StringRef filename(StringRef path) {
return *rbegin(path);
}
@@ -707,12 +717,14 @@ static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot) {
for (StringRef C : llvm::make_range(path::begin(rel), path::end(rel))) {
if (C == ".")
continue;
- if (remove_dot_dot) {
- if (C == "..") {
- if (!components.empty())
- components.pop_back();
+ // Leading ".." will remain in the path unless it's at the root.
+ if (remove_dot_dot && C == "..") {
+ if (!components.empty() && components.back() != "..") {
+ components.pop_back();
continue;
}
+ if (path::is_absolute(path))
+ continue;
}
components.push_back(C);
}
@@ -978,62 +990,59 @@ void directory_entry::replace_filename(const Twine &filename, file_status st) {
Status = st;
}
+template <size_t N>
+static bool startswith(StringRef Magic, const char (&S)[N]) {
+ return Magic.startswith(StringRef(S, N - 1));
+}
+
/// @brief Identify the magic in magic.
file_magic identify_magic(StringRef Magic) {
if (Magic.size() < 4)
return file_magic::unknown;
switch ((unsigned char)Magic[0]) {
case 0x00: {
- // COFF bigobj or short import library file
- if (Magic[1] == (char)0x00 && Magic[2] == (char)0xff &&
- Magic[3] == (char)0xff) {
+ // COFF bigobj, CL.exe's LTO object file, or short import library file
+ if (startswith(Magic, "\0\0\xFF\xFF")) {
size_t MinSize = offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic);
if (Magic.size() < MinSize)
return file_magic::coff_import_library;
- int BigObjVersion = read16le(
- Magic.data() + offsetof(COFF::BigObjHeader, Version));
- if (BigObjVersion < COFF::BigObjHeader::MinBigObjectVersion)
- return file_magic::coff_import_library;
-
const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
- if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) != 0)
- return file_magic::coff_import_library;
- return file_magic::coff_object;
+ if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) == 0)
+ return file_magic::coff_object;
+ if (memcmp(Start, COFF::ClGlObjMagic, sizeof(COFF::BigObjMagic)) == 0)
+ return file_magic::coff_cl_gl_object;
+ return file_magic::coff_import_library;
}
// Windows resource file
- const char Expected[] = { 0, 0, 0, 0, '\x20', 0, 0, 0, '\xff' };
- if (Magic.size() >= sizeof(Expected) &&
- memcmp(Magic.data(), Expected, sizeof(Expected)) == 0)
+ if (startswith(Magic, "\0\0\0\0\x20\0\0\0\xFF"))
return file_magic::windows_resource;
// 0x0000 = COFF unknown machine type
if (Magic[1] == 0)
return file_magic::coff_object;
+ if (startswith(Magic, "\0asm"))
+ return file_magic::wasm_object;
break;
}
case 0xDE: // 0x0B17C0DE = BC wraper
- if (Magic[1] == (char)0xC0 && Magic[2] == (char)0x17 &&
- Magic[3] == (char)0x0B)
+ if (startswith(Magic, "\xDE\xC0\x17\x0B"))
return file_magic::bitcode;
break;
case 'B':
- if (Magic[1] == 'C' && Magic[2] == (char)0xC0 && Magic[3] == (char)0xDE)
+ if (startswith(Magic, "BC\xC0\xDE"))
return file_magic::bitcode;
break;
case '!':
- if (Magic.size() >= 8)
- if (memcmp(Magic.data(), "!<arch>\n", 8) == 0 ||
- memcmp(Magic.data(), "!<thin>\n", 8) == 0)
- return file_magic::archive;
+ if (startswith(Magic, "!<arch>\n") || startswith(Magic, "!<thin>\n"))
+ return file_magic::archive;
break;
case '\177':
- if (Magic.size() >= 18 && Magic[1] == 'E' && Magic[2] == 'L' &&
- Magic[3] == 'F') {
+ if (startswith(Magic, "\177ELF") && Magic.size() >= 18) {
bool Data2MSB = Magic[5] == 2;
unsigned high = Data2MSB ? 16 : 17;
unsigned low = Data2MSB ? 17 : 16;
- if (Magic[high] == 0)
+ if (Magic[high] == 0) {
switch (Magic[low]) {
default: return file_magic::elf;
case 1: return file_magic::elf_relocatable;
@@ -1041,15 +1050,15 @@ file_magic identify_magic(StringRef Magic) {
case 3: return file_magic::elf_shared_object;
case 4: return file_magic::elf_core;
}
- else
- // It's still some type of ELF file.
- return file_magic::elf;
+ }
+ // It's still some type of ELF file.
+ return file_magic::elf;
}
break;
case 0xCA:
- if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
- (Magic[3] == char(0xBE) || Magic[3] == char(0xBF))) {
+ if (startswith(Magic, "\xCA\xFE\xBA\xBE") ||
+ startswith(Magic, "\xCA\xFE\xBA\xBF")) {
// This is complicated by an overlap with Java class files.
// See the Mach-O section in /usr/share/file/magic for details.
if (Magic.size() >= 8 && Magic[7] < 43)
@@ -1064,9 +1073,8 @@ file_magic identify_magic(StringRef Magic) {
case 0xCE:
case 0xCF: {
uint16_t type = 0;
- if (Magic[0] == char(0xFE) && Magic[1] == char(0xED) &&
- Magic[2] == char(0xFA) &&
- (Magic[3] == char(0xCE) || Magic[3] == char(0xCF))) {
+ if (startswith(Magic, "\xFE\xED\xFA\xCE") ||
+ startswith(Magic, "\xFE\xED\xFA\xCF")) {
/* Native endian */
size_t MinSize;
if (Magic[3] == char(0xCE))
@@ -1075,9 +1083,8 @@ file_magic identify_magic(StringRef Magic) {
MinSize = sizeof(MachO::mach_header_64);
if (Magic.size() >= MinSize)
type = Magic[12] << 24 | Magic[13] << 12 | Magic[14] << 8 | Magic[15];
- } else if ((Magic[0] == char(0xCE) || Magic[0] == char(0xCF)) &&
- Magic[1] == char(0xFA) && Magic[2] == char(0xED) &&
- Magic[3] == char(0xFE)) {
+ } else if (startswith(Magic, "\xCE\xFA\xED\xFE") ||
+ startswith(Magic, "\xCF\xFA\xED\xFE")) {
/* Reverse endian */
size_t MinSize;
if (Magic[0] == char(0xCE))
@@ -1120,7 +1127,7 @@ file_magic identify_magic(StringRef Magic) {
break;
case 'M': // Possible MS-DOS stub on Windows PE file
- if (Magic[1] == 'Z') {
+ if (startswith(Magic, "MZ")) {
uint32_t off = read32le(Magic.data() + 0x3c);
// PE/COFF file, either EXE or DLL.
if (off < Magic.size() &&
diff --git a/contrib/llvm/lib/Support/PrettyStackTrace.cpp b/contrib/llvm/lib/Support/PrettyStackTrace.cpp
index ebad67b..5b079ff 100644
--- a/contrib/llvm/lib/Support/PrettyStackTrace.cpp
+++ b/contrib/llvm/lib/Support/PrettyStackTrace.cpp
@@ -21,6 +21,7 @@
#include "llvm/Support/Watchdog.h"
#include "llvm/Support/raw_ostream.h"
+#include <cstdarg>
#include <tuple>
#ifdef HAVE_CRASHREPORTERCLIENT_H
@@ -32,7 +33,7 @@ using namespace llvm;
// If backtrace support is not enabled, compile out support for pretty stack
// traces. This has the secondary effect of not requiring thread local storage
// when backtrace support is disabled.
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
// We need a thread local pointer to manage the stack of our stack trace
// objects, but we *really* cannot tolerate destructors running and do not want
@@ -79,7 +80,7 @@ static void PrintCurStackTrace(raw_ostream &OS) {
}
// Integrate with crash reporter libraries.
-#if defined (__APPLE__) && HAVE_CRASHREPORTERCLIENT_H
+#if defined (__APPLE__) && defined(HAVE_CRASHREPORTERCLIENT_H)
// If any clients of llvm try to link to libCrashReporterClient.a themselves,
// only one crash info struct will be used.
extern "C" {
@@ -88,12 +89,12 @@ struct crashreporter_annotations_t gCRAnnotations
__attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
= { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
}
-#elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO
-static const char *__crashreporter_info__ = 0;
+#elif defined(__APPLE__) && HAVE_CRASHREPORTER_INFO
+extern "C" const char *__crashreporter_info__
+ __attribute__((visibility("hidden"))) = 0;
asm(".desc ___crashreporter_info__, 0x10");
#endif
-
/// CrashHandler - This callback is run if a fatal signal is delivered to the
/// process, it prints the pretty stack trace.
static void CrashHandler(void *) {
@@ -122,11 +123,11 @@ static void CrashHandler(void *) {
#endif
}
-// defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+// defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
#endif
PrettyStackTraceEntry::PrettyStackTraceEntry() {
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
// Link ourselves.
NextEntry = PrettyStackTraceHead;
PrettyStackTraceHead = this;
@@ -134,17 +135,33 @@ PrettyStackTraceEntry::PrettyStackTraceEntry() {
}
PrettyStackTraceEntry::~PrettyStackTraceEntry() {
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
assert(PrettyStackTraceHead == this &&
"Pretty stack trace entry destruction is out of order");
PrettyStackTraceHead = NextEntry;
#endif
}
-void PrettyStackTraceString::print(raw_ostream &OS) const {
- OS << Str << "\n";
+void PrettyStackTraceString::print(raw_ostream &OS) const { OS << Str << "\n"; }
+
+PrettyStackTraceFormat::PrettyStackTraceFormat(const char *Format, ...) {
+ va_list AP;
+ va_start(AP, Format);
+ const int SizeOrError = vsnprintf(nullptr, 0, Format, AP);
+ va_end(AP);
+ if (SizeOrError < 0) {
+ return;
+ }
+
+ const int Size = SizeOrError + 1; // '\0'
+ Str.resize(Size);
+ va_start(AP, Format);
+ vsnprintf(Str.data(), Size, Format, AP);
+ va_end(AP);
}
+void PrettyStackTraceFormat::print(raw_ostream &OS) const { OS << Str << "\n"; }
+
void PrettyStackTraceProgram::print(raw_ostream &OS) const {
OS << "Program arguments: ";
// Print the argument list.
@@ -153,7 +170,7 @@ void PrettyStackTraceProgram::print(raw_ostream &OS) const {
OS << '\n';
}
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
static bool RegisterCrashPrinter() {
sys::AddSignalHandler(CrashHandler, nullptr);
return false;
@@ -161,7 +178,7 @@ static bool RegisterCrashPrinter() {
#endif
void llvm::EnablePrettyStackTrace() {
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
// The first time this is called, we register the crash printer.
static bool HandlerRegistered = RegisterCrashPrinter();
(void)HandlerRegistered;
@@ -169,7 +186,7 @@ void llvm::EnablePrettyStackTrace() {
}
const void *llvm::SavePrettyStackState() {
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
return PrettyStackTraceHead;
#else
return nullptr;
@@ -177,7 +194,7 @@ const void *llvm::SavePrettyStackState() {
}
void llvm::RestorePrettyStackState(const void *Top) {
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES
PrettyStackTraceHead =
static_cast<PrettyStackTraceEntry *>(const_cast<void *>(Top));
#endif
diff --git a/contrib/llvm/lib/Support/RandomNumberGenerator.cpp b/contrib/llvm/lib/Support/RandomNumberGenerator.cpp
index 81d0411..8ea02d7 100644
--- a/contrib/llvm/lib/Support/RandomNumberGenerator.cpp
+++ b/contrib/llvm/lib/Support/RandomNumberGenerator.cpp
@@ -17,6 +17,11 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
+#ifdef LLVM_ON_WIN32
+#include "Windows/WindowsSupport.h"
+#else
+#include "Unix/Unix.h"
+#endif
using namespace llvm;
@@ -42,16 +47,45 @@ RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) {
// are using a 64-bit RNG. This isn't a problem since the Mersenne
// twister constructor copies these correctly into its initial state.
std::vector<uint32_t> Data;
- Data.reserve(2 + Salt.size());
- Data.push_back(Seed);
- Data.push_back(Seed >> 32);
+ Data.resize(2 + Salt.size());
+ Data[0] = Seed;
+ Data[1] = Seed >> 32;
- std::copy(Salt.begin(), Salt.end(), Data.end());
+ std::copy(Salt.begin(), Salt.end(), Data.begin() + 2);
std::seed_seq SeedSeq(Data.begin(), Data.end());
Generator.seed(SeedSeq);
}
-uint_fast64_t RandomNumberGenerator::operator()() {
+RandomNumberGenerator::result_type RandomNumberGenerator::operator()() {
return Generator();
}
+
+// Get random vector of specified size
+std::error_code llvm::getRandomBytes(void *Buffer, size_t Size) {
+#ifdef LLVM_ON_WIN32
+ HCRYPTPROV hProvider;
+ if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ ScopedCryptContext ScopedHandle(hProvider);
+ if (CryptGenRandom(hProvider, Size, static_cast<BYTE *>(Buffer)))
+ return std::error_code();
+ }
+ return std::error_code(GetLastError(), std::system_category());
+#else
+ int Fd = open("/dev/urandom", O_RDONLY);
+ if (Fd != -1) {
+ std::error_code Ret;
+ ssize_t BytesRead = read(Fd, Buffer, Size);
+ if (BytesRead == -1)
+ Ret = std::error_code(errno, std::system_category());
+ else if (BytesRead != static_cast<ssize_t>(Size))
+ Ret = std::error_code(EIO, std::system_category());
+ if (close(Fd) == -1)
+ Ret = std::error_code(errno, std::system_category());
+
+ return Ret;
+ }
+ return std::error_code(errno, std::system_category());
+#endif
+}
diff --git a/contrib/llvm/lib/Support/Regex.cpp b/contrib/llvm/lib/Support/Regex.cpp
index e8344ef..68ba79e 100644
--- a/contrib/llvm/lib/Support/Regex.cpp
+++ b/contrib/llvm/lib/Support/Regex.cpp
@@ -19,6 +19,8 @@
#include <string>
using namespace llvm;
+Regex::Regex() : preg(nullptr), error(REG_BADPAT) {}
+
Regex::Regex(StringRef regex, unsigned Flags) {
unsigned flags = 0;
preg = new llvm_regex();
@@ -32,6 +34,13 @@ Regex::Regex(StringRef regex, unsigned Flags) {
error = llvm_regcomp(preg, regex.data(), flags|REG_PEND);
}
+Regex::Regex(Regex &&regex) {
+ preg = regex.preg;
+ error = regex.error;
+ regex.preg = nullptr;
+ regex.error = REG_BADPAT;
+}
+
Regex::~Regex() {
if (preg) {
llvm_regfree(preg);
@@ -57,6 +66,9 @@ unsigned Regex::getNumMatches() const {
}
bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches){
+ if (error)
+ return false;
+
unsigned nmatch = Matches ? preg->re_nsub+1 : 0;
// pmatch needs to have at least one element.
diff --git a/contrib/llvm/lib/Support/SHA1.cpp b/contrib/llvm/lib/Support/SHA1.cpp
index a461d1e..0eefd99 100644
--- a/contrib/llvm/lib/Support/SHA1.cpp
+++ b/contrib/llvm/lib/Support/SHA1.cpp
@@ -6,8 +6,10 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
// This code is taken from public domain
-// (http://oauth.googlecode.com/svn/code/c/liboauth/src/sha1.c)
+// (http://oauth.googlecode.com/svn/code/c/liboauth/src/sha1.c and
+// http://cvsweb.netbsd.org/bsdweb.cgi/src/common/lib/libc/hash/sha1/sha1.c?rev=1.6)
// and modified by wrapping it in a C++ interface for LLVM,
// and removing unnecessary code.
//
@@ -25,6 +27,49 @@ using namespace llvm;
#define SHA_BIG_ENDIAN
#endif
+static uint32_t rol(uint32_t Number, int Bits) {
+ return (Number << Bits) | (Number >> (32 - Bits));
+}
+
+static uint32_t blk0(uint32_t *Buf, int I) { return Buf[I]; }
+
+static uint32_t blk(uint32_t *Buf, int I) {
+ Buf[I & 15] = rol(Buf[(I + 13) & 15] ^ Buf[(I + 8) & 15] ^ Buf[(I + 2) & 15] ^
+ Buf[I & 15],
+ 1);
+ return Buf[I & 15];
+}
+
+static void r0(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
+ int I, uint32_t *Buf) {
+ E += ((B & (C ^ D)) ^ D) + blk0(Buf, I) + 0x5A827999 + rol(A, 5);
+ B = rol(B, 30);
+}
+
+static void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
+ int I, uint32_t *Buf) {
+ E += ((B & (C ^ D)) ^ D) + blk(Buf, I) + 0x5A827999 + rol(A, 5);
+ B = rol(B, 30);
+}
+
+static void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
+ int I, uint32_t *Buf) {
+ E += (B ^ C ^ D) + blk(Buf, I) + 0x6ED9EBA1 + rol(A, 5);
+ B = rol(B, 30);
+}
+
+static void r3(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
+ int I, uint32_t *Buf) {
+ E += (((B | C) & D) | (B & C)) + blk(Buf, I) + 0x8F1BBCDC + rol(A, 5);
+ B = rol(B, 30);
+}
+
+static void r4(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E,
+ int I, uint32_t *Buf) {
+ E += (B ^ C ^ D) + blk(Buf, I) + 0xCA62C1D6 + rol(A, 5);
+ B = rol(B, 30);
+}
+
/* code */
#define SHA1_K0 0x5a827999
#define SHA1_K20 0x6ed9eba1
@@ -47,56 +92,112 @@ void SHA1::init() {
InternalState.BufferOffset = 0;
}
-static uint32_t rol32(uint32_t number, uint8_t bits) {
- return ((number << bits) | (number >> (32 - bits)));
-}
-
void SHA1::hashBlock() {
- uint8_t i;
- uint32_t a, b, c, d, e, t;
-
- a = InternalState.State[0];
- b = InternalState.State[1];
- c = InternalState.State[2];
- d = InternalState.State[3];
- e = InternalState.State[4];
- for (i = 0; i < 80; i++) {
- if (i >= 16) {
- t = InternalState.Buffer[(i + 13) & 15] ^
- InternalState.Buffer[(i + 8) & 15] ^
- InternalState.Buffer[(i + 2) & 15] ^ InternalState.Buffer[i & 15];
- InternalState.Buffer[i & 15] = rol32(t, 1);
- }
- if (i < 20) {
- t = (d ^ (b & (c ^ d))) + SHA1_K0;
- } else if (i < 40) {
- t = (b ^ c ^ d) + SHA1_K20;
- } else if (i < 60) {
- t = ((b & c) | (d & (b | c))) + SHA1_K40;
- } else {
- t = (b ^ c ^ d) + SHA1_K60;
- }
- t += rol32(a, 5) + e + InternalState.Buffer[i & 15];
- e = d;
- d = c;
- c = rol32(b, 30);
- b = a;
- a = t;
- }
- InternalState.State[0] += a;
- InternalState.State[1] += b;
- InternalState.State[2] += c;
- InternalState.State[3] += d;
- InternalState.State[4] += e;
+ uint32_t A = InternalState.State[0];
+ uint32_t B = InternalState.State[1];
+ uint32_t C = InternalState.State[2];
+ uint32_t D = InternalState.State[3];
+ uint32_t E = InternalState.State[4];
+
+ // 4 rounds of 20 operations each. Loop unrolled.
+ r0(A, B, C, D, E, 0, InternalState.Buffer.L);
+ r0(E, A, B, C, D, 1, InternalState.Buffer.L);
+ r0(D, E, A, B, C, 2, InternalState.Buffer.L);
+ r0(C, D, E, A, B, 3, InternalState.Buffer.L);
+ r0(B, C, D, E, A, 4, InternalState.Buffer.L);
+ r0(A, B, C, D, E, 5, InternalState.Buffer.L);
+ r0(E, A, B, C, D, 6, InternalState.Buffer.L);
+ r0(D, E, A, B, C, 7, InternalState.Buffer.L);
+ r0(C, D, E, A, B, 8, InternalState.Buffer.L);
+ r0(B, C, D, E, A, 9, InternalState.Buffer.L);
+ r0(A, B, C, D, E, 10, InternalState.Buffer.L);
+ r0(E, A, B, C, D, 11, InternalState.Buffer.L);
+ r0(D, E, A, B, C, 12, InternalState.Buffer.L);
+ r0(C, D, E, A, B, 13, InternalState.Buffer.L);
+ r0(B, C, D, E, A, 14, InternalState.Buffer.L);
+ r0(A, B, C, D, E, 15, InternalState.Buffer.L);
+ r1(E, A, B, C, D, 16, InternalState.Buffer.L);
+ r1(D, E, A, B, C, 17, InternalState.Buffer.L);
+ r1(C, D, E, A, B, 18, InternalState.Buffer.L);
+ r1(B, C, D, E, A, 19, InternalState.Buffer.L);
+
+ r2(A, B, C, D, E, 20, InternalState.Buffer.L);
+ r2(E, A, B, C, D, 21, InternalState.Buffer.L);
+ r2(D, E, A, B, C, 22, InternalState.Buffer.L);
+ r2(C, D, E, A, B, 23, InternalState.Buffer.L);
+ r2(B, C, D, E, A, 24, InternalState.Buffer.L);
+ r2(A, B, C, D, E, 25, InternalState.Buffer.L);
+ r2(E, A, B, C, D, 26, InternalState.Buffer.L);
+ r2(D, E, A, B, C, 27, InternalState.Buffer.L);
+ r2(C, D, E, A, B, 28, InternalState.Buffer.L);
+ r2(B, C, D, E, A, 29, InternalState.Buffer.L);
+ r2(A, B, C, D, E, 30, InternalState.Buffer.L);
+ r2(E, A, B, C, D, 31, InternalState.Buffer.L);
+ r2(D, E, A, B, C, 32, InternalState.Buffer.L);
+ r2(C, D, E, A, B, 33, InternalState.Buffer.L);
+ r2(B, C, D, E, A, 34, InternalState.Buffer.L);
+ r2(A, B, C, D, E, 35, InternalState.Buffer.L);
+ r2(E, A, B, C, D, 36, InternalState.Buffer.L);
+ r2(D, E, A, B, C, 37, InternalState.Buffer.L);
+ r2(C, D, E, A, B, 38, InternalState.Buffer.L);
+ r2(B, C, D, E, A, 39, InternalState.Buffer.L);
+
+ r3(A, B, C, D, E, 40, InternalState.Buffer.L);
+ r3(E, A, B, C, D, 41, InternalState.Buffer.L);
+ r3(D, E, A, B, C, 42, InternalState.Buffer.L);
+ r3(C, D, E, A, B, 43, InternalState.Buffer.L);
+ r3(B, C, D, E, A, 44, InternalState.Buffer.L);
+ r3(A, B, C, D, E, 45, InternalState.Buffer.L);
+ r3(E, A, B, C, D, 46, InternalState.Buffer.L);
+ r3(D, E, A, B, C, 47, InternalState.Buffer.L);
+ r3(C, D, E, A, B, 48, InternalState.Buffer.L);
+ r3(B, C, D, E, A, 49, InternalState.Buffer.L);
+ r3(A, B, C, D, E, 50, InternalState.Buffer.L);
+ r3(E, A, B, C, D, 51, InternalState.Buffer.L);
+ r3(D, E, A, B, C, 52, InternalState.Buffer.L);
+ r3(C, D, E, A, B, 53, InternalState.Buffer.L);
+ r3(B, C, D, E, A, 54, InternalState.Buffer.L);
+ r3(A, B, C, D, E, 55, InternalState.Buffer.L);
+ r3(E, A, B, C, D, 56, InternalState.Buffer.L);
+ r3(D, E, A, B, C, 57, InternalState.Buffer.L);
+ r3(C, D, E, A, B, 58, InternalState.Buffer.L);
+ r3(B, C, D, E, A, 59, InternalState.Buffer.L);
+
+ r4(A, B, C, D, E, 60, InternalState.Buffer.L);
+ r4(E, A, B, C, D, 61, InternalState.Buffer.L);
+ r4(D, E, A, B, C, 62, InternalState.Buffer.L);
+ r4(C, D, E, A, B, 63, InternalState.Buffer.L);
+ r4(B, C, D, E, A, 64, InternalState.Buffer.L);
+ r4(A, B, C, D, E, 65, InternalState.Buffer.L);
+ r4(E, A, B, C, D, 66, InternalState.Buffer.L);
+ r4(D, E, A, B, C, 67, InternalState.Buffer.L);
+ r4(C, D, E, A, B, 68, InternalState.Buffer.L);
+ r4(B, C, D, E, A, 69, InternalState.Buffer.L);
+ r4(A, B, C, D, E, 70, InternalState.Buffer.L);
+ r4(E, A, B, C, D, 71, InternalState.Buffer.L);
+ r4(D, E, A, B, C, 72, InternalState.Buffer.L);
+ r4(C, D, E, A, B, 73, InternalState.Buffer.L);
+ r4(B, C, D, E, A, 74, InternalState.Buffer.L);
+ r4(A, B, C, D, E, 75, InternalState.Buffer.L);
+ r4(E, A, B, C, D, 76, InternalState.Buffer.L);
+ r4(D, E, A, B, C, 77, InternalState.Buffer.L);
+ r4(C, D, E, A, B, 78, InternalState.Buffer.L);
+ r4(B, C, D, E, A, 79, InternalState.Buffer.L);
+
+ InternalState.State[0] += A;
+ InternalState.State[1] += B;
+ InternalState.State[2] += C;
+ InternalState.State[3] += D;
+ InternalState.State[4] += E;
}
-void SHA1::addUncounted(uint8_t data) {
- uint8_t *const b = (uint8_t *)InternalState.Buffer;
+void SHA1::addUncounted(uint8_t Data) {
#ifdef SHA_BIG_ENDIAN
- b[InternalState.BufferOffset] = data;
+ InternalState.Buffer.C[InternalState.BufferOffset] = Data;
#else
- b[InternalState.BufferOffset ^ 3] = data;
+ InternalState.Buffer.C[InternalState.BufferOffset ^ 3] = Data;
#endif
+
InternalState.BufferOffset++;
if (InternalState.BufferOffset == BLOCK_LENGTH) {
hashBlock();
@@ -104,9 +205,9 @@ void SHA1::addUncounted(uint8_t data) {
}
}
-void SHA1::writebyte(uint8_t data) {
+void SHA1::writebyte(uint8_t Data) {
++InternalState.ByteCount;
- addUncounted(data);
+ addUncounted(Data);
}
void SHA1::update(ArrayRef<uint8_t> Data) {
@@ -168,3 +269,13 @@ StringRef SHA1::result() {
// Return pointer to hash (20 characters)
return Hash;
}
+
+std::array<uint8_t, 20> SHA1::hash(ArrayRef<uint8_t> Data) {
+ SHA1 Hash;
+ Hash.update(Data);
+ StringRef S = Hash.final();
+
+ std::array<uint8_t, 20> Arr;
+ memcpy(Arr.data(), S.data(), S.size());
+ return Arr;
+}
diff --git a/contrib/llvm/lib/Support/ScaledNumber.cpp b/contrib/llvm/lib/Support/ScaledNumber.cpp
index b9432d4..807c9fa 100644
--- a/contrib/llvm/lib/Support/ScaledNumber.cpp
+++ b/contrib/llvm/lib/Support/ScaledNumber.cpp
@@ -183,7 +183,7 @@ static std::string toStringAPFloat(uint64_t D, int E, unsigned Precision) {
// Build the float and print it.
uint64_t RawBits[2] = {D, AdjustedE};
- APFloat Float(APFloat::x87DoubleExtended, APInt(80, RawBits));
+ APFloat Float(APFloat::x87DoubleExtended(), APInt(80, RawBits));
SmallVector<char, 24> Chars;
Float.toString(Chars, Precision, 0);
return std::string(Chars.begin(), Chars.end());
diff --git a/contrib/llvm/lib/Support/ScopedPrinter.cpp b/contrib/llvm/lib/Support/ScopedPrinter.cpp
index 0225f01..d8ee1ef 100644
--- a/contrib/llvm/lib/Support/ScopedPrinter.cpp
+++ b/contrib/llvm/lib/Support/ScopedPrinter.cpp
@@ -27,45 +27,18 @@ void ScopedPrinter::printBinaryImpl(StringRef Label, StringRef Str,
if (Block) {
startLine() << Label;
- if (Str.size() > 0)
+ if (!Str.empty())
OS << ": " << Str;
OS << " (\n";
- for (size_t addr = 0, end = Data.size(); addr < end; addr += 16) {
- startLine() << format(" %04" PRIX64 ": ", uint64_t(addr));
- // Dump line of hex.
- for (size_t i = 0; i < 16; ++i) {
- if (i != 0 && i % 4 == 0)
- OS << ' ';
- if (addr + i < end)
- OS << hexdigit((Data[addr + i] >> 4) & 0xF, false)
- << hexdigit(Data[addr + i] & 0xF, false);
- else
- OS << " ";
- }
- // Print ascii.
- OS << " |";
- for (std::size_t i = 0; i < 16 && addr + i < end; ++i) {
- if (std::isprint(Data[addr + i] & 0xFF))
- OS << Data[addr + i];
- else
- OS << ".";
- }
- OS << "|\n";
- }
-
+ if (!Data.empty())
+ OS << format_bytes_with_ascii(Data, 0, 16, 4, (IndentLevel + 1) * 2, true)
+ << "\n";
startLine() << ")\n";
} else {
startLine() << Label << ":";
- if (Str.size() > 0)
+ if (!Str.empty())
OS << " " << Str;
- OS << " (";
- for (size_t i = 0; i < Data.size(); ++i) {
- if (i > 0)
- OS << " ";
-
- OS << format("%02X", static_cast<int>(Data[i]));
- }
- OS << ")\n";
+ OS << " (" << format_bytes(Data, None, Data.size(), 1, 0, true) << ")\n";
}
}
diff --git a/contrib/llvm/lib/Support/SmallPtrSet.cpp b/contrib/llvm/lib/Support/SmallPtrSet.cpp
index 539b4eb..aa12e85 100644
--- a/contrib/llvm/lib/Support/SmallPtrSet.cpp
+++ b/contrib/llvm/lib/Support/SmallPtrSet.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
+#include <cassert>
#include <cstdlib>
using namespace llvm;
@@ -60,38 +61,13 @@ SmallPtrSetImplBase::insert_imp_big(const void *Ptr) {
return std::make_pair(Bucket, true);
}
-bool SmallPtrSetImplBase::erase_imp(const void * Ptr) {
- if (isSmall()) {
- // Check to see if it is in the set.
- for (const void **APtr = CurArray, **E = CurArray + NumNonEmpty; APtr != E;
- ++APtr)
- if (*APtr == Ptr) {
- // If it is in the set, replace this element.
- *APtr = getTombstoneMarker();
- ++NumTombstones;
- return true;
- }
-
- return false;
- }
-
- // Okay, we know we have space. Find a hash bucket.
- void **Bucket = const_cast<void**>(FindBucketFor(Ptr));
- if (*Bucket != Ptr) return false; // Not in the set?
-
- // Set this as a tombstone.
- *Bucket = getTombstoneMarker();
- ++NumTombstones;
- return true;
-}
-
const void * const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const {
unsigned Bucket = DenseMapInfo<void *>::getHashValue(Ptr) & (CurArraySize-1);
unsigned ArraySize = CurArraySize;
unsigned ProbeAmt = 1;
const void *const *Array = CurArray;
const void *const *Tombstone = nullptr;
- while (1) {
+ while (true) {
// If we found an empty bucket, the pointer doesn't exist in the set.
// Return a tombstone if we've seen one so far, or the empty bucket if
// not.
diff --git a/contrib/llvm/lib/Support/SourceMgr.cpp b/contrib/llvm/lib/Support/SourceMgr.cpp
index 6d44a4d..4cb9b2f 100644
--- a/contrib/llvm/lib/Support/SourceMgr.cpp
+++ b/contrib/llvm/lib/Support/SourceMgr.cpp
@@ -14,6 +14,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/SourceMgr.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Locale.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -25,8 +26,8 @@ static const size_t TabStop = 8;
namespace {
struct LineNoCacheTy {
- unsigned LastQueryBufferID;
const char *LastQuery;
+ unsigned LastQueryBufferID;
unsigned LineNoOfQuery;
};
}
@@ -141,7 +142,7 @@ SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
// location to pull out the source line.
SmallVector<std::pair<unsigned, unsigned>, 4> ColRanges;
std::pair<unsigned, unsigned> LineAndCol;
- const char *BufferID = "<unknown>";
+ StringRef BufferID = "<unknown>";
std::string LineStr;
if (Loc.isValid()) {
@@ -395,8 +396,7 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &S, bool ShowColors,
// map like Clang's TextDiagnostic. For now, we'll just handle tabs by
// expanding them later, and bail out rather than show incorrect ranges and
// misaligned fixits for any other odd characters.
- if (std::find_if(LineContents.begin(), LineContents.end(), isNonASCII) !=
- LineContents.end()) {
+ if (find_if(LineContents, isNonASCII) != LineContents.end()) {
printSourceLine(S, LineContents);
return;
}
diff --git a/contrib/llvm/lib/Support/SpecialCaseList.cpp b/contrib/llvm/lib/Support/SpecialCaseList.cpp
index 0ffe444..df524b3 100644
--- a/contrib/llvm/lib/Support/SpecialCaseList.cpp
+++ b/contrib/llvm/lib/Support/SpecialCaseList.cpp
@@ -15,6 +15,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/SpecialCaseList.h"
+#include "llvm/Support/TrigramIndex.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSet.h"
@@ -32,15 +33,16 @@ namespace llvm {
/// reason for doing so is efficiency; StringSet is much faster at matching
/// literal strings than Regex.
struct SpecialCaseList::Entry {
- Entry() {}
- Entry(Entry &&Other)
- : Strings(std::move(Other.Strings)), RegEx(std::move(Other.RegEx)) {}
-
StringSet<> Strings;
+ TrigramIndex Trigrams;
std::unique_ptr<Regex> RegEx;
bool match(StringRef Query) const {
- return Strings.count(Query) || (RegEx && RegEx->match(Query));
+ if (Strings.count(Query))
+ return true;
+ if (Trigrams.isDefinitelyOut(Query))
+ return false;
+ return RegEx && RegEx->match(Query);
}
};
@@ -108,13 +110,15 @@ bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
StringRef Category = SplitRegexp.second;
// See if we can store Regexp in Strings.
+ auto &Entry = Entries[Prefix][Category];
if (Regex::isLiteralERE(Regexp)) {
- Entries[Prefix][Category].Strings.insert(Regexp);
+ Entry.Strings.insert(Regexp);
continue;
}
+ Entry.Trigrams.insert(Regexp);
// Replace * with .*
- for (size_t pos = 0; (pos = Regexp.find("*", pos)) != std::string::npos;
+ for (size_t pos = 0; (pos = Regexp.find('*', pos)) != std::string::npos;
pos += strlen(".*")) {
Regexp.replace(pos, strlen("*"), ".*");
}
diff --git a/contrib/llvm/lib/Support/Statistic.cpp b/contrib/llvm/lib/Support/Statistic.cpp
index cdd3679..0c50dfd 100644
--- a/contrib/llvm/lib/Support/Statistic.cpp
+++ b/contrib/llvm/lib/Support/Statistic.cpp
@@ -29,7 +29,9 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/YAMLTraits.h"
#include <algorithm>
#include <cstring>
using namespace llvm;
@@ -37,15 +39,16 @@ using namespace llvm;
/// -stats - Command line option to cause transformations to emit stats about
/// what they did.
///
-static cl::opt<bool>
-Enabled(
- "stats",
+static cl::opt<bool> Stats("stats",
cl::desc("Enable statistics output from program (available with Asserts)"));
static cl::opt<bool> StatsAsJSON("stats-json",
cl::desc("Display statistics as json data"));
+static bool Enabled;
+static bool PrintOnExit;
+
namespace {
/// StatisticInfo - This class is used in a ManagedStatic so that it is created
/// on demand (when the first statistic is bumped) and destroyed only when
@@ -59,6 +62,7 @@ class StatisticInfo {
/// Sort statistics by debugtype,name,description.
void sort();
public:
+ StatisticInfo();
~StatisticInfo();
void addStatistic(const Statistic *S) {
@@ -77,7 +81,7 @@ void Statistic::RegisterStatistic() {
// printed.
sys::SmartScopedLock<true> Writer(*StatLock);
if (!Initialized) {
- if (Enabled)
+ if (Stats || Enabled)
StatInfo->addStatistic(this);
TsanHappensBefore(this);
@@ -89,17 +93,24 @@ void Statistic::RegisterStatistic() {
}
}
+StatisticInfo::StatisticInfo() {
+ // Ensure timergroup lists are created first so they are destructed after us.
+ TimerGroup::ConstructTimerLists();
+}
+
// Print information when destroyed, iff command line option is specified.
StatisticInfo::~StatisticInfo() {
- llvm::PrintStatistics();
+ if (::Stats || PrintOnExit)
+ llvm::PrintStatistics();
}
-void llvm::EnableStatistics() {
- Enabled.setValue(true);
+void llvm::EnableStatistics(bool PrintOnExit) {
+ Enabled = true;
+ ::PrintOnExit = PrintOnExit;
}
bool llvm::AreStatisticsEnabled() {
- return Enabled;
+ return Enabled || Stats;
}
void StatisticInfo::sort() {
@@ -145,17 +156,6 @@ void llvm::PrintStatistics(raw_ostream &OS) {
OS.flush();
}
-static void write_json_string_escaped(raw_ostream &OS, const char *string) {
- // Out current usage should not need any escaping. Keep it simple and just
- // check that the input is pure ASCII without special characers.
-#ifndef NDEBUG
- for (const unsigned char *c = (const unsigned char*)string; *c != '\0'; ++c) {
- assert(*c != '\\' && *c != '\"' && *c >= 0x20 && *c < 0x80);
- }
-#endif
- OS << string;
-}
-
void llvm::PrintStatisticsJSON(raw_ostream &OS) {
StatisticInfo &Stats = *StatInfo;
@@ -166,13 +166,16 @@ void llvm::PrintStatisticsJSON(raw_ostream &OS) {
const char *delim = "";
for (const Statistic *Stat : Stats.Stats) {
OS << delim;
- OS << "\t\"";
- write_json_string_escaped(OS, Stat->getDebugType());
- OS << '.';
- write_json_string_escaped(OS, Stat->getName());
- OS << "\": " << Stat->getValue();
+ assert(!yaml::needsQuotes(Stat->getDebugType()) &&
+ "Statistic group/type name is simple.");
+ assert(!yaml::needsQuotes(Stat->getName()) && "Statistic name is simple");
+ OS << "\t\"" << Stat->getDebugType() << '.' << Stat->getName() << "\": "
+ << Stat->getValue();
delim = ",\n";
}
+ // Print timers.
+ TimerGroup::printAllJSONValues(OS, delim);
+
OS << "\n}\n";
OS.flush();
}
@@ -195,7 +198,7 @@ void llvm::PrintStatistics() {
// Check if the -stats option is set instead of checking
// !Stats.Stats.empty(). In release builds, Statistics operators
// do nothing, so stats are never Registered.
- if (Enabled) {
+ if (Stats) {
// Get the stream to write to.
std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile();
(*OutStream) << "Statistics are disabled. "
diff --git a/contrib/llvm/lib/Support/StreamingMemoryObject.cpp b/contrib/llvm/lib/Support/StreamingMemoryObject.cpp
deleted file mode 100644
index fb56617..0000000
--- a/contrib/llvm/lib/Support/StreamingMemoryObject.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-//===- StreamingMemoryObject.cpp - Streamable data interface -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/StreamingMemoryObject.h"
-#include <cassert>
-#include <cstddef>
-#include <cstring>
-using namespace llvm;
-
-namespace {
-
-class RawMemoryObject : public MemoryObject {
-public:
- RawMemoryObject(const unsigned char *Start, const unsigned char *End) :
- FirstChar(Start), LastChar(End) {
- assert(LastChar >= FirstChar && "Invalid start/end range");
- }
-
- uint64_t getExtent() const override {
- return LastChar - FirstChar;
- }
- uint64_t readBytes(uint8_t *Buf, uint64_t Size,
- uint64_t Address) const override;
- const uint8_t *getPointer(uint64_t address, uint64_t size) const override;
- bool isValidAddress(uint64_t address) const override {
- return validAddress(address);
- }
-
-private:
- const uint8_t* const FirstChar;
- const uint8_t* const LastChar;
-
- // These are implemented as inline functions here to avoid multiple virtual
- // calls per public function
- bool validAddress(uint64_t address) const {
- return static_cast<std::ptrdiff_t>(address) < LastChar - FirstChar;
- }
-
- RawMemoryObject(const RawMemoryObject&) = delete;
- void operator=(const RawMemoryObject&) = delete;
-};
-
-uint64_t RawMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
- uint64_t Address) const {
- uint64_t BufferSize = LastChar - FirstChar;
- if (Address >= BufferSize)
- return 0;
-
- uint64_t End = Address + Size;
- if (End > BufferSize)
- End = BufferSize;
-
- assert(static_cast<int64_t>(End - Address) >= 0);
- Size = End - Address;
- memcpy(Buf, Address + FirstChar, Size);
- return Size;
-}
-
-const uint8_t *RawMemoryObject::getPointer(uint64_t address,
- uint64_t size) const {
- return FirstChar + address;
-}
-} // anonymous namespace
-
-namespace llvm {
-// If the bitcode has a header, then its size is known, and we don't have to
-// block until we actually want to read it.
-bool StreamingMemoryObject::isValidAddress(uint64_t address) const {
- if (ObjectSize && address < ObjectSize) return true;
- return fetchToPos(address);
-}
-
-uint64_t StreamingMemoryObject::getExtent() const {
- if (ObjectSize) return ObjectSize;
- size_t pos = BytesRead + kChunkSize;
- // keep fetching until we run out of bytes
- while (fetchToPos(pos)) pos += kChunkSize;
- return ObjectSize;
-}
-
-uint64_t StreamingMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
- uint64_t Address) const {
- fetchToPos(Address + Size - 1);
- // Note: For wrapped bitcode files will set ObjectSize after the
- // first call to fetchToPos. In such cases, ObjectSize can be
- // smaller than BytesRead.
- size_t MaxAddress =
- (ObjectSize && ObjectSize < BytesRead) ? ObjectSize : BytesRead;
- if (Address >= MaxAddress)
- return 0;
-
- uint64_t End = Address + Size;
- if (End > MaxAddress)
- End = MaxAddress;
- assert(End >= Address);
- Size = End - Address;
- memcpy(Buf, &Bytes[Address + BytesSkipped], Size);
- return Size;
-}
-
-const uint8_t *StreamingMemoryObject::getPointer(uint64_t Address,
- uint64_t Size) const {
- fetchToPos(Address + Size - 1);
- return &Bytes[Address + BytesSkipped];
-}
-
-bool StreamingMemoryObject::dropLeadingBytes(size_t s) {
- if (BytesRead < s) return true;
- BytesSkipped = s;
- BytesRead -= s;
- return false;
-}
-
-void StreamingMemoryObject::setKnownObjectSize(size_t size) {
- ObjectSize = size;
- Bytes.reserve(size);
- if (ObjectSize <= BytesRead)
- EOFReached = true;
-}
-
-MemoryObject *getNonStreamedMemoryObject(const unsigned char *Start,
- const unsigned char *End) {
- return new RawMemoryObject(Start, End);
-}
-
-StreamingMemoryObject::StreamingMemoryObject(
- std::unique_ptr<DataStreamer> Streamer)
- : Bytes(kChunkSize), Streamer(std::move(Streamer)), BytesRead(0),
- BytesSkipped(0), ObjectSize(0), EOFReached(false) {
- BytesRead = this->Streamer->GetBytes(&Bytes[0], kChunkSize);
-}
-}
diff --git a/contrib/llvm/lib/Support/StringMap.cpp b/contrib/llvm/lib/Support/StringMap.cpp
index 7da9ccb..d2315966 100644
--- a/contrib/llvm/lib/Support/StringMap.cpp
+++ b/contrib/llvm/lib/Support/StringMap.cpp
@@ -14,7 +14,9 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MathExtras.h"
#include <cassert>
+
using namespace llvm;
/// Returns the number of buckets to allocate to ensure that the DenseMap can
@@ -63,7 +65,6 @@ void StringMapImpl::init(unsigned InitSize) {
TheTable[NumBuckets] = (StringMapEntryBase*)2;
}
-
/// LookupBucketFor - Look up the bucket that the specified string should end
/// up in. If it already exists as a key in the map, the Item pointer for the
/// specified bucket will be non-null. Otherwise, it will be null. In either
@@ -81,7 +82,7 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
unsigned ProbeAmt = 1;
int FirstTombstone = -1;
- while (1) {
+ while (true) {
StringMapEntryBase *BucketItem = TheTable[BucketNo];
// If we found an empty bucket, this key isn't in the table yet, return it.
if (LLVM_LIKELY(!BucketItem)) {
@@ -123,7 +124,6 @@ unsigned StringMapImpl::LookupBucketFor(StringRef Name) {
}
}
-
/// FindKey - Look up the bucket that contains the specified key. If it exists
/// in the map, return the bucket number of the key. Otherwise return -1.
/// This does not modify the map.
@@ -135,7 +135,7 @@ int StringMapImpl::FindKey(StringRef Key) const {
unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1);
unsigned ProbeAmt = 1;
- while (1) {
+ while (true) {
StringMapEntryBase *BucketItem = TheTable[BucketNo];
// If we found an empty bucket, this key isn't in the table yet, return.
if (LLVM_LIKELY(!BucketItem))
@@ -191,8 +191,6 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
return Result;
}
-
-
/// RehashTable - Grow the table, redistributing values into the buckets with
/// the appropriate mod-of-hashtable-size.
unsigned StringMapImpl::RehashTable(unsigned BucketNo) {
diff --git a/contrib/llvm/lib/Support/StringRef.cpp b/contrib/llvm/lib/Support/StringRef.cpp
index 8a9da5e..d81250e 100644
--- a/contrib/llvm/lib/Support/StringRef.cpp
+++ b/contrib/llvm/lib/Support/StringRef.cpp
@@ -69,6 +69,11 @@ bool StringRef::endswith_lower(StringRef Suffix) const {
ascii_strncasecmp(end() - Suffix.Length, Suffix.Data, Suffix.Length) == 0;
}
+size_t StringRef::find_lower(char C, size_t From) const {
+ char L = ascii_tolower(C);
+ return find_if([L](char D) { return ascii_tolower(D) == L; }, From);
+}
+
/// compare_numeric - Compare strings, handle embedded numbers.
int StringRef::compare_numeric(StringRef RHS) const {
for (size_t I = 0, E = std::min(Length, RHS.Length); I != E; ++I) {
@@ -143,16 +148,20 @@ size_t StringRef::find(StringRef Str, size_t From) const {
if (From > Length)
return npos;
+ const char *Start = Data + From;
+ size_t Size = Length - From;
+
const char *Needle = Str.data();
size_t N = Str.size();
if (N == 0)
return From;
-
- size_t Size = Length - From;
if (Size < N)
return npos;
+ if (N == 1) {
+ const char *Ptr = (const char *)::memchr(Start, Needle[0], Size);
+ return Ptr == nullptr ? npos : Ptr - Data;
+ }
- const char *Start = Data + From;
const char *Stop = Start + (Size - N + 1);
// For short haystacks or unsupported needles fall back to the naive algorithm
@@ -172,16 +181,40 @@ size_t StringRef::find(StringRef Str, size_t From) const {
BadCharSkip[(uint8_t)Str[i]] = N-1-i;
do {
- if (std::memcmp(Start, Needle, N) == 0)
- return Start - Data;
+ uint8_t Last = Start[N - 1];
+ if (LLVM_UNLIKELY(Last == (uint8_t)Needle[N - 1]))
+ if (std::memcmp(Start, Needle, N - 1) == 0)
+ return Start - Data;
// Otherwise skip the appropriate number of bytes.
- Start += BadCharSkip[(uint8_t)Start[N-1]];
+ Start += BadCharSkip[Last];
} while (Start < Stop);
return npos;
}
+size_t StringRef::find_lower(StringRef Str, size_t From) const {
+ StringRef This = substr(From);
+ while (This.size() >= Str.size()) {
+ if (This.startswith_lower(Str))
+ return From;
+ This = This.drop_front();
+ ++From;
+ }
+ return npos;
+}
+
+size_t StringRef::rfind_lower(char C, size_t From) const {
+ From = std::min(From, Length);
+ size_t i = From;
+ while (i != 0) {
+ --i;
+ if (ascii_tolower(Data[i]) == ascii_tolower(C))
+ return i;
+ }
+ return npos;
+}
+
/// rfind - Search for the last string \arg Str in the string.
///
/// \return - The index of the last occurrence of \arg Str, or npos if not
@@ -198,6 +231,18 @@ size_t StringRef::rfind(StringRef Str) const {
return npos;
}
+size_t StringRef::rfind_lower(StringRef Str) const {
+ size_t N = Str.size();
+ if (N > Length)
+ return npos;
+ for (size_t i = Length - N + 1, e = 0; i != e;) {
+ --i;
+ if (substr(i, N).equals_lower(Str))
+ return i;
+ }
+ return npos;
+}
+
/// find_first_of - Find the first character in the string that is in \arg
/// Chars, or npos if not found.
///
@@ -351,6 +396,9 @@ size_t StringRef::count(StringRef Str) const {
}
static unsigned GetAutoSenseRadix(StringRef &Str) {
+ if (Str.empty())
+ return 10;
+
if (Str.startswith("0x") || Str.startswith("0X")) {
Str = Str.substr(2);
return 16;
@@ -366,17 +414,16 @@ static unsigned GetAutoSenseRadix(StringRef &Str) {
return 8;
}
- if (Str.startswith("0"))
+ if (Str[0] == '0' && Str.size() > 1 && ascii_isdigit(Str[1])) {
+ Str = Str.substr(1);
return 8;
-
+ }
+
return 10;
}
-
-/// GetAsUnsignedInteger - Workhorse method that converts a integer character
-/// sequence of radix up to 36 to an unsigned long long value.
-bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
- unsigned long long &Result) {
+bool llvm::consumeUnsignedInteger(StringRef &Str, unsigned Radix,
+ unsigned long long &Result) {
// Autosense radix if not specified.
if (Radix == 0)
Radix = GetAutoSenseRadix(Str);
@@ -385,44 +432,51 @@ bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
if (Str.empty()) return true;
// Parse all the bytes of the string given this radix. Watch for overflow.
+ StringRef Str2 = Str;
Result = 0;
- while (!Str.empty()) {
+ while (!Str2.empty()) {
unsigned CharVal;
- if (Str[0] >= '0' && Str[0] <= '9')
- CharVal = Str[0]-'0';
- else if (Str[0] >= 'a' && Str[0] <= 'z')
- CharVal = Str[0]-'a'+10;
- else if (Str[0] >= 'A' && Str[0] <= 'Z')
- CharVal = Str[0]-'A'+10;
+ if (Str2[0] >= '0' && Str2[0] <= '9')
+ CharVal = Str2[0] - '0';
+ else if (Str2[0] >= 'a' && Str2[0] <= 'z')
+ CharVal = Str2[0] - 'a' + 10;
+ else if (Str2[0] >= 'A' && Str2[0] <= 'Z')
+ CharVal = Str2[0] - 'A' + 10;
else
- return true;
+ break;
- // If the parsed value is larger than the integer radix, the string is
- // invalid.
+ // If the parsed value is larger than the integer radix, we cannot
+ // consume any more characters.
if (CharVal >= Radix)
- return true;
+ break;
// Add in this character.
unsigned long long PrevResult = Result;
- Result = Result*Radix+CharVal;
+ Result = Result * Radix + CharVal;
// Check for overflow by shifting back and seeing if bits were lost.
- if (Result/Radix < PrevResult)
+ if (Result / Radix < PrevResult)
return true;
- Str = Str.substr(1);
+ Str2 = Str2.substr(1);
}
+ // We consider the operation a failure if no characters were consumed
+ // successfully.
+ if (Str.size() == Str2.size())
+ return true;
+
+ Str = Str2;
return false;
}
-bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
- long long &Result) {
+bool llvm::consumeSignedInteger(StringRef &Str, unsigned Radix,
+ long long &Result) {
unsigned long long ULLVal;
// Handle positive strings first.
if (Str.empty() || Str.front() != '-') {
- if (getAsUnsignedInteger(Str, Radix, ULLVal) ||
+ if (consumeUnsignedInteger(Str, Radix, ULLVal) ||
// Check for value so large it overflows a signed value.
(long long)ULLVal < 0)
return true;
@@ -431,17 +485,41 @@ bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
}
// Get the positive part of the value.
- if (getAsUnsignedInteger(Str.substr(1), Radix, ULLVal) ||
+ StringRef Str2 = Str.drop_front(1);
+ if (consumeUnsignedInteger(Str2, Radix, ULLVal) ||
// Reject values so large they'd overflow as negative signed, but allow
// "-0". This negates the unsigned so that the negative isn't undefined
// on signed overflow.
(long long)-ULLVal > 0)
return true;
+ Str = Str2;
Result = -ULLVal;
return false;
}
+/// GetAsUnsignedInteger - Workhorse method that converts a integer character
+/// sequence of radix up to 36 to an unsigned long long value.
+bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
+ unsigned long long &Result) {
+ if (consumeUnsignedInteger(Str, Radix, Result))
+ return true;
+
+ // For getAsUnsignedInteger, we require the whole string to be consumed or
+ // else we consider it a failure.
+ return !Str.empty();
+}
+
+bool llvm::getAsSignedInteger(StringRef Str, unsigned Radix,
+ long long &Result) {
+ if (consumeSignedInteger(Str, Radix, Result))
+ return true;
+
+ // For getAsSignedInteger, we require the whole string to be consumed or else
+ // we consider it a failure.
+ return !Str.empty();
+}
+
bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const {
StringRef Str = *this;
diff --git a/contrib/llvm/lib/Support/StringSaver.cpp b/contrib/llvm/lib/Support/StringSaver.cpp
index bbc1fd2..335fce3 100644
--- a/contrib/llvm/lib/Support/StringSaver.cpp
+++ b/contrib/llvm/lib/Support/StringSaver.cpp
@@ -11,9 +11,9 @@
using namespace llvm;
-const char *StringSaver::save(StringRef S) {
+StringRef StringSaver::save(StringRef S) {
char *P = Alloc.Allocate<char>(S.size() + 1);
memcpy(P, S.data(), S.size());
P[S.size()] = '\0';
- return P;
+ return StringRef(P, S.size());
}
diff --git a/contrib/llvm/lib/Support/TarWriter.cpp b/contrib/llvm/lib/Support/TarWriter.cpp
new file mode 100644
index 0000000..f06abf4
--- /dev/null
+++ b/contrib/llvm/lib/Support/TarWriter.cpp
@@ -0,0 +1,189 @@
+//===-- TarWriter.cpp - Tar archive file creator --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// TarWriter class provides a feature to create a tar archive file.
+//
+// I put emphasis on simplicity over comprehensiveness when implementing this
+// class because we don't need a full-fledged archive file generator in LLVM
+// at the moment.
+//
+// The filename field in the Unix V7 tar header is 100 bytes. Longer filenames
+// are stored using the PAX extension. The PAX header is standardized in
+// POSIX.1-2001.
+//
+// The struct definition of UstarHeader is copied from
+// https://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/TarWriter.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Path.h"
+
+using namespace llvm;
+
+// Each file in an archive must be aligned to this block size.
+static const int BlockSize = 512;
+
+struct UstarHeader {
+ char Name[100];
+ char Mode[8];
+ char Uid[8];
+ char Gid[8];
+ char Size[12];
+ char Mtime[12];
+ char Checksum[8];
+ char TypeFlag;
+ char Linkname[100];
+ char Magic[6];
+ char Version[2];
+ char Uname[32];
+ char Gname[32];
+ char DevMajor[8];
+ char DevMinor[8];
+ char Prefix[155];
+ char Pad[12];
+};
+static_assert(sizeof(UstarHeader) == BlockSize, "invalid Ustar header");
+
+static UstarHeader makeUstarHeader() {
+ UstarHeader Hdr = {};
+ memcpy(Hdr.Magic, "ustar", 5); // Ustar magic
+ memcpy(Hdr.Version, "00", 2); // Ustar version
+ return Hdr;
+}
+
+// A PAX attribute is in the form of "<length> <key>=<value>\n"
+// where <length> is the length of the entire string including
+// the length field itself. An example string is this.
+//
+// 25 ctime=1084839148.1212\n
+//
+// This function create such string.
+static std::string formatPax(StringRef Key, StringRef Val) {
+ int Len = Key.size() + Val.size() + 3; // +3 for " ", "=" and "\n"
+
+ // We need to compute total size twice because appending
+ // a length field could change total size by one.
+ int Total = Len + Twine(Len).str().size();
+ Total = Len + Twine(Total).str().size();
+ return (Twine(Total) + " " + Key + "=" + Val + "\n").str();
+}
+
+// Headers in tar files must be aligned to 512 byte boundaries.
+// This function forwards the current file position to the next boundary.
+static void pad(raw_fd_ostream &OS) {
+ uint64_t Pos = OS.tell();
+ OS.seek(alignTo(Pos, BlockSize));
+}
+
+// Computes a checksum for a tar header.
+static void computeChecksum(UstarHeader &Hdr) {
+ // Before computing a checksum, checksum field must be
+ // filled with space characters.
+ memset(Hdr.Checksum, ' ', sizeof(Hdr.Checksum));
+
+ // Compute a checksum and set it to the checksum field.
+ unsigned Chksum = 0;
+ for (size_t I = 0; I < sizeof(Hdr); ++I)
+ Chksum += reinterpret_cast<uint8_t *>(&Hdr)[I];
+ snprintf(Hdr.Checksum, sizeof(Hdr.Checksum), "%06o", Chksum);
+}
+
+// Create a tar header and write it to a given output stream.
+static void writePaxHeader(raw_fd_ostream &OS, StringRef Path) {
+ // A PAX header consists of a 512-byte header followed
+ // by key-value strings. First, create key-value strings.
+ std::string PaxAttr = formatPax("path", Path);
+
+ // Create a 512-byte header.
+ UstarHeader Hdr = makeUstarHeader();
+ snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", PaxAttr.size());
+ Hdr.TypeFlag = 'x'; // PAX magic
+ computeChecksum(Hdr);
+
+ // Write them down.
+ OS << StringRef(reinterpret_cast<char *>(&Hdr), sizeof(Hdr));
+ OS << PaxAttr;
+ pad(OS);
+}
+
+// In the Ustar header, a path can be split at any '/' to store
+// a path into UstarHeader::Name and UstarHeader::Prefix. This
+// function splits a given path for that purpose.
+static std::pair<StringRef, StringRef> splitPath(StringRef Path) {
+ if (Path.size() <= sizeof(UstarHeader::Name))
+ return {"", Path};
+ size_t Sep = Path.rfind('/', sizeof(UstarHeader::Prefix) + 1);
+ if (Sep == StringRef::npos)
+ return {"", Path};
+ return {Path.substr(0, Sep), Path.substr(Sep + 1)};
+}
+
+// Returns true if a given path can be stored to a Ustar header
+// without the PAX extension.
+static bool fitsInUstar(StringRef Path) {
+ StringRef Prefix;
+ StringRef Name;
+ std::tie(Prefix, Name) = splitPath(Path);
+ return Name.size() <= sizeof(UstarHeader::Name);
+}
+
+// The PAX header is an extended format, so a PAX header needs
+// to be followed by a "real" header.
+static void writeUstarHeader(raw_fd_ostream &OS, StringRef Path, size_t Size) {
+ StringRef Prefix;
+ StringRef Name;
+ std::tie(Prefix, Name) = splitPath(Path);
+
+ UstarHeader Hdr = makeUstarHeader();
+ memcpy(Hdr.Name, Name.data(), Name.size());
+ memcpy(Hdr.Mode, "0000664", 8);
+ snprintf(Hdr.Size, sizeof(Hdr.Size), "%011zo", Size);
+ memcpy(Hdr.Prefix, Prefix.data(), Prefix.size());
+ computeChecksum(Hdr);
+ OS << StringRef(reinterpret_cast<char *>(&Hdr), sizeof(Hdr));
+}
+
+// Creates a TarWriter instance and returns it.
+Expected<std::unique_ptr<TarWriter>> TarWriter::create(StringRef OutputPath,
+ StringRef BaseDir) {
+ int FD;
+ if (std::error_code EC = openFileForWrite(OutputPath, FD, sys::fs::F_None))
+ return make_error<StringError>("cannot open " + OutputPath, EC);
+ return std::unique_ptr<TarWriter>(new TarWriter(FD, BaseDir));
+}
+
+TarWriter::TarWriter(int FD, StringRef BaseDir)
+ : OS(FD, /*shouldClose=*/true, /*unbuffered=*/false), BaseDir(BaseDir) {}
+
+// Append a given file to an archive.
+void TarWriter::append(StringRef Path, StringRef Data) {
+ // Write Path and Data.
+ std::string S = BaseDir + "/" + sys::path::convert_to_slash(Path) + "\0";
+ if (fitsInUstar(S)) {
+ writeUstarHeader(OS, S, Data.size());
+ } else {
+ writePaxHeader(OS, S);
+ writeUstarHeader(OS, "", Data.size());
+ }
+
+ OS << Data;
+ pad(OS);
+
+ // POSIX requires tar archives end with two null blocks.
+ // Here, we write the terminator and then seek back, so that
+ // the file being output is terminated correctly at any moment.
+ uint64_t Pos = OS.tell();
+ OS << std::string(BlockSize * 2, '\0');
+ OS.seek(Pos);
+ OS.flush();
+}
diff --git a/contrib/llvm/lib/Support/TargetParser.cpp b/contrib/llvm/lib/Support/TargetParser.cpp
index c3f8613..42fab67 100644
--- a/contrib/llvm/lib/Support/TargetParser.cpp
+++ b/contrib/llvm/lib/Support/TargetParser.cpp
@@ -52,7 +52,7 @@ static const struct {
// of the triples and are not conforming with their official names.
// Check to see if the expectation should be changed.
// FIXME: TableGen this.
-static const struct {
+template <typename T> struct ArchNames {
const char *NameCStr;
size_t NameLength;
const char *CPUAttrCStr;
@@ -61,7 +61,7 @@ static const struct {
size_t SubArchLength;
unsigned DefaultFPU;
unsigned ArchBaseExtensions;
- ARM::ArchKind ID;
+ T ID;
ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
StringRef getName() const { return StringRef(NameCStr, NameLength); }
@@ -71,18 +71,22 @@ static const struct {
// Sub-Arch name.
StringRef getSubArch() const { return StringRef(SubArchCStr, SubArchLength); }
-} ARCHNames[] = {
+};
+ArchNames<ARM::ArchKind> ARCHNames[] = {
#define ARM_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
{NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR},
#include "llvm/Support/ARMTargetParser.def"
-},AArch64ARCHNames[] = {
-#define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
- {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
- sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, ID, ARCH_ATTR},
-#include "llvm/Support/AArch64TargetParser.def"
};
+ArchNames<AArch64::ArchKind> AArch64ARCHNames[] = {
+ #define AARCH64_ARCH(NAME, ID, CPU_ATTR, SUB_ARCH, ARCH_ATTR, ARCH_FPU, ARCH_BASE_EXT) \
+ {NAME, sizeof(NAME) - 1, CPU_ATTR, sizeof(CPU_ATTR) - 1, SUB_ARCH, \
+ sizeof(SUB_ARCH) - 1, ARCH_FPU, ARCH_BASE_EXT, AArch64::ArchKind::ID, ARCH_ATTR},
+ #include "llvm/Support/AArch64TargetParser.def"
+ };
+
+
// List of Arch Extension names.
// FIXME: TableGen this.
static const struct {
@@ -122,24 +126,27 @@ static const struct {
// When finding the Arch for a CPU, first-found prevails. Sort them accordingly.
// When this becomes table-generated, we'd probably need two tables.
// FIXME: TableGen this.
-static const struct {
+template <typename T> struct CpuNames {
const char *NameCStr;
size_t NameLength;
- ARM::ArchKind ArchID;
+ T ArchID;
bool Default; // is $Name the default CPU for $ArchID ?
unsigned DefaultExtensions;
StringRef getName() const { return StringRef(NameCStr, NameLength); }
-} CPUNames[] = {
+};
+CpuNames<ARM::ArchKind> CPUNames[] = {
#define ARM_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
{ NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT },
#include "llvm/Support/ARMTargetParser.def"
-},AArch64CPUNames[] = {
-#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
- { NAME, sizeof(NAME) - 1, ID, IS_DEFAULT, DEFAULT_EXT },
-#include "llvm/Support/AArch64TargetParser.def"
};
+CpuNames<AArch64::ArchKind> AArch64CPUNames[] = {
+ #define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
+ { NAME, sizeof(NAME) - 1, AArch64::ArchKind::ID, IS_DEFAULT, DEFAULT_EXT },
+ #include "llvm/Support/AArch64TargetParser.def"
+ };
+
} // namespace
// ======================================================= //
@@ -193,7 +200,7 @@ unsigned llvm::ARM::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
}
bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
- std::vector<const char *> &Features) {
+ std::vector<StringRef> &Features) {
if (HWDivKind == ARM::AEK_INVALID)
return false;
@@ -212,7 +219,7 @@ bool llvm::ARM::getHWDivFeatures(unsigned HWDivKind,
}
bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
- std::vector<const char *> &Features) {
+ std::vector<StringRef> &Features) {
if (Extensions == ARM::AEK_INVALID)
return false;
@@ -231,7 +238,7 @@ bool llvm::ARM::getExtensionFeatures(unsigned Extensions,
}
bool llvm::ARM::getFPUFeatures(unsigned FPUKind,
- std::vector<const char *> &Features) {
+ std::vector<StringRef> &Features) {
if (FPUKind >= ARM::FK_LAST || FPUKind == ARM::FK_INVALID)
return false;
@@ -344,20 +351,20 @@ StringRef llvm::ARM::getArchExtName(unsigned ArchExtKind) {
return StringRef();
}
-const char *llvm::ARM::getArchExtFeature(StringRef ArchExt) {
+StringRef llvm::ARM::getArchExtFeature(StringRef ArchExt) {
if (ArchExt.startswith("no")) {
StringRef ArchExtBase(ArchExt.substr(2));
for (const auto AE : ARCHExtNames) {
if (AE.NegFeature && ArchExtBase == AE.getName())
- return AE.NegFeature;
+ return StringRef(AE.NegFeature);
}
}
for (const auto AE : ARCHExtNames) {
if (AE.Feature && ArchExt == AE.getName())
- return AE.Feature;
+ return StringRef(AE.Feature);
}
- return nullptr;
+ return StringRef();
}
StringRef llvm::ARM::getHWDivName(unsigned HWDivKind) {
@@ -416,13 +423,13 @@ unsigned llvm::AArch64::getDefaultExtensions(StringRef CPU, unsigned ArchKind) {
return StringSwitch<unsigned>(CPU)
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT) \
- .Case(NAME, AArch64ARCHNames[ID].ArchBaseExtensions | DEFAULT_EXT)
+ .Case(NAME, DEFAULT_EXT)
#include "llvm/Support/AArch64TargetParser.def"
.Default(AArch64::AEK_INVALID);
}
bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
- std::vector<const char *> &Features) {
+ std::vector<StringRef> &Features) {
if (Extensions == AArch64::AEK_INVALID)
return false;
@@ -446,81 +453,77 @@ bool llvm::AArch64::getExtensionFeatures(unsigned Extensions,
}
bool llvm::AArch64::getFPUFeatures(unsigned FPUKind,
- std::vector<const char *> &Features) {
+ std::vector<StringRef> &Features) {
return ARM::getFPUFeatures(FPUKind, Features);
}
bool llvm::AArch64::getArchFeatures(unsigned ArchKind,
- std::vector<const char *> &Features) {
- if (ArchKind == ARM::AK_INVALID || ArchKind >= ARM::AK_LAST)
- return false;
-
- if (ArchKind == ARM::AK_ARMV8_1A)
+ std::vector<StringRef> &Features) {
+ if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_1A))
Features.push_back("+v8.1a");
- if (ArchKind == ARM::AK_ARMV8_2A)
+ if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_ARMV8_2A))
Features.push_back("+v8.2a");
- return true;
+ return ArchKind > static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) &&
+ ArchKind < static_cast<unsigned>(AArch64::ArchKind::AK_LAST);
}
StringRef llvm::AArch64::getArchName(unsigned ArchKind) {
- for (const auto &AI : AArch64ARCHNames)
- if (AI.ID == ArchKind)
- return AI.getName();
- return StringRef();
+ if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
+ return StringRef();
+ return AArch64ARCHNames[ArchKind].getName();
}
StringRef llvm::AArch64::getCPUAttr(unsigned ArchKind) {
- for (const auto &AI : AArch64ARCHNames)
- if (AI.ID == ArchKind)
- return AI.getCPUAttr();
- return StringRef();
+ if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
+ ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
+ return StringRef();
+ return AArch64ARCHNames[ArchKind].getCPUAttr();
}
StringRef llvm::AArch64::getSubArch(unsigned ArchKind) {
- for (const auto &AI : AArch64ARCHNames)
- if (AI.ID == ArchKind)
- return AI.getSubArch();
- return StringRef();
+ if (ArchKind == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID) ||
+ ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
+ return StringRef();
+ return AArch64ARCHNames[ArchKind].getSubArch();
}
unsigned llvm::AArch64::getArchAttr(unsigned ArchKind) {
- for (const auto &AI : AArch64ARCHNames)
- if (AI.ID == ArchKind)
- return AI.ArchAttr;
- return ARMBuildAttrs::CPUArch::v8_A;
+ if (ArchKind >= static_cast<unsigned>(AArch64::ArchKind::AK_LAST))
+ return ARMBuildAttrs::CPUArch::v8_A;
+ return AArch64ARCHNames[ArchKind].ArchAttr;
}
-StringRef llvm::AArch64::getArchExtName(unsigned AArchExtKind) {
+StringRef llvm::AArch64::getArchExtName(unsigned ArchExtKind) {
for (const auto &AE : AArch64ARCHExtNames)
- if (AArchExtKind == AE.ID)
+ if (ArchExtKind == AE.ID)
return AE.getName();
return StringRef();
}
-const char *llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
+StringRef llvm::AArch64::getArchExtFeature(StringRef ArchExt) {
if (ArchExt.startswith("no")) {
StringRef ArchExtBase(ArchExt.substr(2));
for (const auto &AE : AArch64ARCHExtNames) {
if (AE.NegFeature && ArchExtBase == AE.getName())
- return AE.NegFeature;
+ return StringRef(AE.NegFeature);
}
}
for (const auto &AE : AArch64ARCHExtNames)
if (AE.Feature && ArchExt == AE.getName())
- return AE.Feature;
- return nullptr;
+ return StringRef(AE.Feature);
+ return StringRef();
}
StringRef llvm::AArch64::getDefaultCPU(StringRef Arch) {
unsigned AK = parseArch(Arch);
- if (AK == ARM::AK_INVALID)
+ if (AK == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
return StringRef();
// Look for multiple AKs to find the default for pair AK+Name.
for (const auto &CPU : AArch64CPUNames)
- if (CPU.ArchID == AK && CPU.Default)
+ if (static_cast<unsigned>(CPU.ArchID) == AK && CPU.Default)
return CPU.getName();
// If we can't find a default then target the architecture instead
@@ -575,6 +578,7 @@ static StringRef getArchSynonym(StringRef Arch) {
.Cases("v8", "v8a", "aarch64", "arm64", "v8-a")
.Case("v8.1a", "v8.1-a")
.Case("v8.2a", "v8.2-a")
+ .Case("v8r", "v8-r")
.Case("v8m.base", "v8-m.base")
.Case("v8m.main", "v8-m.main")
.Default(Arch);
@@ -685,7 +689,7 @@ unsigned llvm::ARM::parseArchISA(StringRef Arch) {
.StartsWith("arm64", ARM::IK_AARCH64)
.StartsWith("thumb", ARM::IK_THUMB)
.StartsWith("arm", ARM::IK_ARM)
- .Default(ARM::EK_INVALID);
+ .Default(ARM::IK_INVALID);
}
// Little/Big endian
@@ -718,6 +722,7 @@ unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
case ARM::AK_ARMV8MBaseline:
return ARM::PK_M;
case ARM::AK_ARMV7R:
+ case ARM::AK_ARMV8R:
return ARM::PK_R;
case ARM::AK_ARMV7A:
case ARM::AK_ARMV7K:
@@ -765,6 +770,7 @@ unsigned llvm::ARM::parseArchVersion(StringRef Arch) {
case ARM::AK_ARMV8A:
case ARM::AK_ARMV8_1A:
case ARM::AK_ARMV8_2A:
+ case ARM::AK_ARMV8R:
case ARM::AK_ARMV8MBaseline:
case ARM::AK_ARMV8MMainline:
return 8;
@@ -784,14 +790,14 @@ unsigned llvm::AArch64::parseFPU(StringRef FPU) {
unsigned llvm::AArch64::parseArch(StringRef Arch) {
Arch = getCanonicalArchName(Arch);
if (checkArchVersion(Arch) < 8)
- return ARM::AK_INVALID;
+ return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
StringRef Syn = getArchSynonym(Arch);
for (const auto A : AArch64ARCHNames) {
if (A.getName().endswith(Syn))
- return A.ID;
+ return static_cast<unsigned>(A.ID);
}
- return ARM::AK_INVALID;
+ return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
}
unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) {
@@ -805,9 +811,9 @@ unsigned llvm::AArch64::parseArchExt(StringRef ArchExt) {
unsigned llvm::AArch64::parseCPUArch(StringRef CPU) {
for (const auto C : AArch64CPUNames) {
if (CPU == C.getName())
- return C.ArchID;
+ return static_cast<unsigned>(C.ArchID);
}
- return ARM::AK_INVALID;
+ return static_cast<unsigned>(AArch64::ArchKind::AK_INVALID);
}
// ARM, Thumb, AArch64
diff --git a/contrib/llvm/lib/Support/TargetRegistry.cpp b/contrib/llvm/lib/Support/TargetRegistry.cpp
index 02a6d33..bed9ed6 100644
--- a/contrib/llvm/lib/Support/TargetRegistry.cpp
+++ b/contrib/llvm/lib/Support/TargetRegistry.cpp
@@ -30,8 +30,7 @@ const Target *TargetRegistry::lookupTarget(const std::string &ArchName,
// name, because it might be a backend that has no mapping to a target triple.
const Target *TheTarget = nullptr;
if (!ArchName.empty()) {
- auto I =
- std::find_if(targets().begin(), targets().end(),
+ auto I = find_if(targets(),
[&](const Target &T) { return ArchName == T.getName(); });
if (I == targets().end()) {
@@ -70,7 +69,7 @@ const Target *TargetRegistry::lookupTarget(const std::string &TT,
}
Triple::ArchType Arch = Triple(TT).getArch();
auto ArchMatch = [&](const Target &T) { return T.ArchMatchFn(Arch); };
- auto I = std::find_if(targets().begin(), targets().end(), ArchMatch);
+ auto I = find_if(targets(), ArchMatch);
if (I == targets().end()) {
Error = "No available targets are compatible with this triple.";
diff --git a/contrib/llvm/lib/Support/Threading.cpp b/contrib/llvm/lib/Support/Threading.cpp
index e8f5622..760f9e2 100644
--- a/contrib/llvm/lib/Support/Threading.cpp
+++ b/contrib/llvm/lib/Support/Threading.cpp
@@ -15,6 +15,7 @@
#include "llvm/Support/Threading.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Atomic.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/thread.h"
#include <cassert>
@@ -116,3 +117,13 @@ void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
}
#endif
+
+unsigned llvm::heavyweight_hardware_concurrency() {
+#if !LLVM_ENABLE_THREADS
+ return 1;
+#endif
+ int NumPhysical = sys::getHostNumPhysicalCores();
+ if (NumPhysical == -1)
+ return thread::hardware_concurrency();
+ return NumPhysical;
+}
diff --git a/contrib/llvm/lib/Support/TimeValue.cpp b/contrib/llvm/lib/Support/TimeValue.cpp
deleted file mode 100644
index 94a4c01..0000000
--- a/contrib/llvm/lib/Support/TimeValue.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- TimeValue.cpp - Implement OS TimeValue Concept ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the operating system TimeValue concept.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/TimeValue.h"
-#include "llvm/Config/config.h"
-
-namespace llvm {
-
-using namespace sys;
-
-const TimeValue::SecondsType
- TimeValue::PosixZeroTimeSeconds = -946684800;
-const TimeValue::SecondsType
- TimeValue::Win32ZeroTimeSeconds = -12591158400ULL;
-
-void TimeValue::normalize() {
- if ( nanos_ >= NANOSECONDS_PER_SECOND ) {
- do {
- seconds_++;
- nanos_ -= NANOSECONDS_PER_SECOND;
- } while ( nanos_ >= NANOSECONDS_PER_SECOND );
- } else if (nanos_ <= -NANOSECONDS_PER_SECOND ) {
- do {
- seconds_--;
- nanos_ += NANOSECONDS_PER_SECOND;
- } while (nanos_ <= -NANOSECONDS_PER_SECOND);
- }
-
- if (seconds_ >= 1 && nanos_ < 0) {
- seconds_--;
- nanos_ += NANOSECONDS_PER_SECOND;
- } else if (seconds_ < 0 && nanos_ > 0) {
- seconds_++;
- nanos_ -= NANOSECONDS_PER_SECOND;
- }
-}
-
-} // namespace llvm
-
-/// Include the platform-specific portion of TimeValue class
-#ifdef LLVM_ON_UNIX
-#include "Unix/TimeValue.inc"
-#endif
-#ifdef LLVM_ON_WIN32
-#include "Windows/TimeValue.inc"
-#endif
diff --git a/contrib/llvm/lib/Support/Timer.cpp b/contrib/llvm/lib/Support/Timer.cpp
index 49bd39e..fbd73d0 100644
--- a/contrib/llvm/lib/Support/Timer.cpp
+++ b/contrib/llvm/lib/Support/Timer.cpp
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
//
-// Interval Timing implementation.
+/// \file Interval Timing implementation.
//
//===----------------------------------------------------------------------===//
@@ -21,16 +21,16 @@
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/YAMLTraits.h"
using namespace llvm;
-// getLibSupportInfoOutputFilename - This ugly hack is brought to you courtesy
-// of constructor/destructor ordering being unspecified by C++. Basically the
-// problem is that a Statistic object gets destroyed, which ends up calling
-// 'GetLibSupportInfoOutputFile()' (below), which calls this function.
-// LibSupportInfoOutputFilename used to be a global variable, but sometimes it
-// would get destroyed before the Statistic, causing havoc to ensue. We "fix"
-// this by creating the string the first time it is needed and never destroying
-// it.
+// This ugly hack is brought to you courtesy of constructor/destructor ordering
+// being unspecified by C++. Basically the problem is that a Statistic object
+// gets destroyed, which ends up calling 'GetLibSupportInfoOutputFile()'
+// (below), which calls this function. LibSupportInfoOutputFilename used to be
+// a global variable, but sometimes it would get destroyed before the Statistic,
+// causing havoc to ensue. We "fix" this by creating the string the first time
+// it is needed and never destroying it.
static ManagedStatic<std::string> LibSupportInfoOutputFilename;
static std::string &getLibSupportInfoOutputFilename() {
return *LibSupportInfoOutputFilename;
@@ -50,7 +50,6 @@ namespace {
cl::Hidden, cl::location(getLibSupportInfoOutputFilename()));
}
-// Return a file stream to print our output on.
std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() {
const std::string &OutputFilename = getLibSupportInfoOutputFilename();
if (OutputFilename.empty())
@@ -83,7 +82,7 @@ static TimerGroup *getDefaultTimerGroup() {
sys::SmartScopedLock<true> Lock(*TimerLock);
tmp = DefaultTimerGroup;
if (!tmp) {
- tmp = new TimerGroup("Miscellaneous Ungrouped Timers");
+ tmp = new TimerGroup("misc", "Miscellaneous Ungrouped Timers");
sys::MemoryFence();
DefaultTimerGroup = tmp;
}
@@ -95,13 +94,14 @@ static TimerGroup *getDefaultTimerGroup() {
// Timer Implementation
//===----------------------------------------------------------------------===//
-void Timer::init(StringRef N) {
- init(N, *getDefaultTimerGroup());
+void Timer::init(StringRef Name, StringRef Description) {
+ init(Name, Description, *getDefaultTimerGroup());
}
-void Timer::init(StringRef N, TimerGroup &tg) {
+void Timer::init(StringRef Name, StringRef Description, TimerGroup &tg) {
assert(!TG && "Timer already initialized");
- Name.assign(N.begin(), N.end());
+ this->Name.assign(Name.begin(), Name.end());
+ this->Description.assign(Description.begin(), Description.end());
Running = Triggered = false;
TG = &tg;
TG->addTimer(*this);
@@ -118,8 +118,10 @@ static inline size_t getMemUsage() {
}
TimeRecord TimeRecord::getCurrentTime(bool Start) {
+ using Seconds = std::chrono::duration<double, std::ratio<1>>;
TimeRecord Result;
- sys::TimeValue now(0,0), user(0,0), sys(0,0);
+ sys::TimePoint<> now;
+ std::chrono::nanoseconds user, sys;
if (Start) {
Result.MemUsed = getMemUsage();
@@ -129,9 +131,9 @@ TimeRecord TimeRecord::getCurrentTime(bool Start) {
Result.MemUsed = getMemUsage();
}
- Result.WallTime = now.seconds() + now.microseconds() / 1000000.0;
- Result.UserTime = user.seconds() + user.microseconds() / 1000000.0;
- Result.SystemTime = sys.seconds() + sys.microseconds() / 1000000.0;
+ Result.WallTime = Seconds(now.time_since_epoch()).count();
+ Result.UserTime = Seconds(user).count();
+ Result.SystemTime = Seconds(sys).count();
return Result;
}
@@ -193,54 +195,44 @@ public:
delete I->second.first;
}
- Timer &get(StringRef Name, StringRef GroupName) {
+ Timer &get(StringRef Name, StringRef Description, StringRef GroupName,
+ StringRef GroupDescription) {
sys::SmartScopedLock<true> L(*TimerLock);
std::pair<TimerGroup*, Name2TimerMap> &GroupEntry = Map[GroupName];
if (!GroupEntry.first)
- GroupEntry.first = new TimerGroup(GroupName);
+ GroupEntry.first = new TimerGroup(GroupName, GroupDescription);
Timer &T = GroupEntry.second[Name];
if (!T.isInitialized())
- T.init(Name, *GroupEntry.first);
+ T.init(Name, Description, *GroupEntry.first);
return T;
}
};
}
-static ManagedStatic<Name2TimerMap> NamedTimers;
static ManagedStatic<Name2PairMap> NamedGroupedTimers;
-static Timer &getNamedRegionTimer(StringRef Name) {
- sys::SmartScopedLock<true> L(*TimerLock);
-
- Timer &T = (*NamedTimers)[Name];
- if (!T.isInitialized())
- T.init(Name);
- return T;
-}
-
-NamedRegionTimer::NamedRegionTimer(StringRef Name,
- bool Enabled)
- : TimeRegion(!Enabled ? nullptr : &getNamedRegionTimer(Name)) {}
-
-NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef GroupName,
- bool Enabled)
- : TimeRegion(!Enabled ? nullptr : &NamedGroupedTimers->get(Name, GroupName)){}
+NamedRegionTimer::NamedRegionTimer(StringRef Name, StringRef Description,
+ StringRef GroupName,
+ StringRef GroupDescription, bool Enabled)
+ : TimeRegion(!Enabled ? nullptr
+ : &NamedGroupedTimers->get(Name, Description, GroupName,
+ GroupDescription)) {}
//===----------------------------------------------------------------------===//
// TimerGroup Implementation
//===----------------------------------------------------------------------===//
-/// TimerGroupList - This is the global list of TimerGroups, maintained by the
-/// TimerGroup ctor/dtor and is protected by the TimerLock lock.
+/// This is the global list of TimerGroups, maintained by the TimerGroup
+/// ctor/dtor and is protected by the TimerLock lock.
static TimerGroup *TimerGroupList = nullptr;
-TimerGroup::TimerGroup(StringRef name)
- : Name(name.begin(), name.end()), FirstTimer(nullptr) {
-
+TimerGroup::TimerGroup(StringRef Name, StringRef Description)
+ : Name(Name.begin(), Name.end()),
+ Description(Description.begin(), Description.end()) {
// Add the group to TimerGroupList.
sys::SmartScopedLock<true> L(*TimerLock);
if (TimerGroupList)
@@ -269,7 +261,7 @@ void TimerGroup::removeTimer(Timer &T) {
// If the timer was started, move its data to TimersToPrint.
if (T.hasTriggered())
- TimersToPrint.emplace_back(T.Time, T.Name);
+ TimersToPrint.emplace_back(T.Time, T.Name, T.Description);
T.TG = nullptr;
@@ -303,15 +295,15 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
std::sort(TimersToPrint.begin(), TimersToPrint.end());
TimeRecord Total;
- for (auto &RecordNamePair : TimersToPrint)
- Total += RecordNamePair.first;
+ for (const PrintRecord &Record : TimersToPrint)
+ Total += Record.Time;
// Print out timing header.
OS << "===" << std::string(73, '-') << "===\n";
// Figure out how many spaces to indent TimerGroup name.
- unsigned Padding = (80-Name.length())/2;
+ unsigned Padding = (80-Description.length())/2;
if (Padding > 80) Padding = 0; // Don't allow "negative" numbers
- OS.indent(Padding) << Name << '\n';
+ OS.indent(Padding) << Description << '\n';
OS << "===" << std::string(73, '-') << "===\n";
// If this is not an collection of ungrouped times, print the total time.
@@ -334,10 +326,10 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
OS << " --- Name ---\n";
// Loop through all of the timing data, printing it out.
- for (unsigned i = 0, e = TimersToPrint.size(); i != e; ++i) {
- const std::pair<TimeRecord, std::string> &Entry = TimersToPrint[e-i-1];
- Entry.first.print(Total, OS);
- OS << Entry.second << '\n';
+ for (const PrintRecord &Record : make_range(TimersToPrint.rbegin(),
+ TimersToPrint.rend())) {
+ Record.Time.print(Total, OS);
+ OS << Record.Description << '\n';
}
Total.print(Total, OS);
@@ -347,29 +339,66 @@ void TimerGroup::PrintQueuedTimers(raw_ostream &OS) {
TimersToPrint.clear();
}
-/// print - Print any started timers in this group and zero them.
-void TimerGroup::print(raw_ostream &OS) {
- sys::SmartScopedLock<true> L(*TimerLock);
-
+void TimerGroup::prepareToPrintList() {
// See if any of our timers were started, if so add them to TimersToPrint and
// reset them.
for (Timer *T = FirstTimer; T; T = T->Next) {
if (!T->hasTriggered()) continue;
- TimersToPrint.emplace_back(T->Time, T->Name);
-
+ TimersToPrint.emplace_back(T->Time, T->Name, T->Description);
+
// Clear out the time.
T->clear();
}
+}
+
+void TimerGroup::print(raw_ostream &OS) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+
+ prepareToPrintList();
// If any timers were started, print the group.
if (!TimersToPrint.empty())
PrintQueuedTimers(OS);
}
-/// printAll - This static method prints all timers and clears them all out.
void TimerGroup::printAll(raw_ostream &OS) {
sys::SmartScopedLock<true> L(*TimerLock);
for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
TG->print(OS);
}
+
+void TimerGroup::printJSONValue(raw_ostream &OS, const PrintRecord &R,
+ const char *suffix, double Value) {
+ assert(!yaml::needsQuotes(Name) && "TimerGroup name needs no quotes");
+ assert(!yaml::needsQuotes(R.Name) && "Timer name needs no quotes");
+ OS << "\t\"time." << Name << '.' << R.Name << suffix << "\": " << Value;
+}
+
+const char *TimerGroup::printJSONValues(raw_ostream &OS, const char *delim) {
+ prepareToPrintList();
+ for (const PrintRecord &R : TimersToPrint) {
+ OS << delim;
+ delim = ",\n";
+
+ const TimeRecord &T = R.Time;
+ printJSONValue(OS, R, ".wall", T.getWallTime());
+ OS << delim;
+ printJSONValue(OS, R, ".user", T.getUserTime());
+ OS << delim;
+ printJSONValue(OS, R, ".sys", T.getSystemTime());
+ }
+ TimersToPrint.clear();
+ return delim;
+}
+
+const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) {
+ sys::SmartScopedLock<true> L(*TimerLock);
+ for (TimerGroup *TG = TimerGroupList; TG; TG = TG->Next)
+ delim = TG->printJSONValues(OS, delim);
+ return delim;
+}
+
+void TimerGroup::ConstructTimerLists() {
+ (void)*NamedGroupedTimers;
+}
diff --git a/contrib/llvm/lib/Support/TrigramIndex.cpp b/contrib/llvm/lib/Support/TrigramIndex.cpp
new file mode 100644
index 0000000..85ab528
--- /dev/null
+++ b/contrib/llvm/lib/Support/TrigramIndex.cpp
@@ -0,0 +1,111 @@
+//===-- TrigramIndex.cpp - a heuristic for SpecialCaseList ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// TrigramIndex implements a heuristic for SpecialCaseList that allows to
+// filter out ~99% incoming queries when all regular expressions in the
+// SpecialCaseList are simple wildcards with '*' and '.'. If rules are more
+// complicated, the check is defeated and it will always pass the queries to a
+// full regex.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/TrigramIndex.h"
+#include "llvm/ADT/SmallVector.h"
+
+#include <unordered_map>
+#include <set>
+#include <string>
+
+using namespace llvm;
+
+static const char RegexAdvancedMetachars[] = "()^$|+?[]\\{}";
+
+static bool isAdvancedMetachar(unsigned Char) {
+ return strchr(RegexAdvancedMetachars, Char) != nullptr;
+}
+
+void TrigramIndex::insert(std::string Regex) {
+ if (Defeated) return;
+ std::set<unsigned> Was;
+ unsigned Cnt = 0;
+ unsigned Tri = 0;
+ unsigned Len = 0;
+ bool Escaped = false;
+ for (unsigned Char : Regex) {
+ if (!Escaped) {
+ // Regular expressions allow escaping symbols by preceding it with '\'.
+ if (Char == '\\') {
+ Escaped = true;
+ continue;
+ }
+ if (isAdvancedMetachar(Char)) {
+ // This is a more complicated regex than we can handle here.
+ Defeated = true;
+ return;
+ }
+ if (Char == '.' || Char == '*') {
+ Tri = 0;
+ Len = 0;
+ continue;
+ }
+ }
+ if (Escaped && Char >= '1' && Char <= '9') {
+ Defeated = true;
+ return;
+ }
+ // We have already handled escaping and can reset the flag.
+ Escaped = false;
+ Tri = ((Tri << 8) + Char) & 0xFFFFFF;
+ Len++;
+ if (Len < 3)
+ continue;
+ // We don't want the index to grow too much for the popular trigrams,
+ // as they are weak signals. It's ok to still require them for the
+ // rules we have already processed. It's just a small additional
+ // computational cost.
+ if (Index[Tri].size() >= 4)
+ continue;
+ Cnt++;
+ if (!Was.count(Tri)) {
+ // Adding the current rule to the index.
+ Index[Tri].push_back(Counts.size());
+ Was.insert(Tri);
+ }
+ }
+ if (!Cnt) {
+ // This rule does not have remarkable trigrams to rely on.
+ // We have to always call the full regex chain.
+ Defeated = true;
+ return;
+ }
+ Counts.push_back(Cnt);
+}
+
+bool TrigramIndex::isDefinitelyOut(StringRef Query) const {
+ if (Defeated)
+ return false;
+ std::vector<unsigned> CurCounts(Counts.size());
+ unsigned Tri = 0;
+ for (size_t I = 0; I < Query.size(); I++) {
+ Tri = ((Tri << 8) + Query[I]) & 0xFFFFFF;
+ if (I < 2)
+ continue;
+ const auto &II = Index.find(Tri);
+ if (II == Index.end())
+ continue;
+ for (size_t J : II->second) {
+ CurCounts[J]++;
+ // If we have reached a desired limit, we have to look at the query
+ // more closely by running a full regex.
+ if (CurCounts[J] >= Counts[J])
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/contrib/llvm/lib/Support/Triple.cpp b/contrib/llvm/lib/Support/Triple.cpp
index 2bac2a3..6783b40 100644
--- a/contrib/llvm/lib/Support/Triple.cpp
+++ b/contrib/llvm/lib/Support/Triple.cpp
@@ -17,7 +17,7 @@
#include <cstring>
using namespace llvm;
-const char *Triple::getArchTypeName(ArchType Kind) {
+StringRef Triple::getArchTypeName(ArchType Kind) {
switch (Kind) {
case UnknownArch: return "unknown";
@@ -39,11 +39,14 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case ppc: return "powerpc";
case r600: return "r600";
case amdgcn: return "amdgcn";
+ case riscv32: return "riscv32";
+ case riscv64: return "riscv64";
case sparc: return "sparc";
case sparcv9: return "sparcv9";
case sparcel: return "sparcel";
case systemz: return "s390x";
case tce: return "tce";
+ case tcele: return "tcele";
case thumb: return "thumb";
case thumbeb: return "thumbeb";
case x86: return "i386";
@@ -71,10 +74,10 @@ const char *Triple::getArchTypeName(ArchType Kind) {
llvm_unreachable("Invalid ArchType!");
}
-const char *Triple::getArchTypePrefix(ArchType Kind) {
+StringRef Triple::getArchTypePrefix(ArchType Kind) {
switch (Kind) {
default:
- return nullptr;
+ return StringRef();
case aarch64:
case aarch64_be: return "aarch64";
@@ -134,10 +137,13 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case shave: return "shave";
case wasm32:
case wasm64: return "wasm";
+
+ case riscv32:
+ case riscv64: return "riscv";
}
}
-const char *Triple::getVendorTypeName(VendorType Kind) {
+StringRef Triple::getVendorTypeName(VendorType Kind) {
switch (Kind) {
case UnknownVendor: return "unknown";
@@ -160,7 +166,7 @@ const char *Triple::getVendorTypeName(VendorType Kind) {
llvm_unreachable("Invalid VendorType!");
}
-const char *Triple::getOSTypeName(OSType Kind) {
+StringRef Triple::getOSTypeName(OSType Kind) {
switch (Kind) {
case UnknownOS: return "unknown";
@@ -168,6 +174,7 @@ const char *Triple::getOSTypeName(OSType Kind) {
case Darwin: return "darwin";
case DragonFly: return "dragonfly";
case FreeBSD: return "freebsd";
+ case Fuchsia: return "fuchsia";
case IOS: return "ios";
case KFreeBSD: return "kfreebsd";
case Linux: return "linux";
@@ -192,12 +199,13 @@ const char *Triple::getOSTypeName(OSType Kind) {
case TvOS: return "tvos";
case WatchOS: return "watchos";
case Mesa3D: return "mesa3d";
+ case Contiki: return "contiki";
}
llvm_unreachable("Invalid OSType");
}
-const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
+StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) {
switch (Kind) {
case UnknownEnvironment: return "unknown";
case GNU: return "gnu";
@@ -217,6 +225,7 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
case Cygnus: return "cygnus";
case AMDOpenCL: return "amdopencl";
case CoreCLR: return "coreclr";
+ case OpenCL: return "opencl";
}
llvm_unreachable("Invalid EnvironmentType!");
@@ -258,12 +267,15 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("ppc64le", ppc64le)
.Case("r600", r600)
.Case("amdgcn", amdgcn)
+ .Case("riscv32", riscv32)
+ .Case("riscv64", riscv64)
.Case("hexagon", hexagon)
.Case("sparc", sparc)
.Case("sparcel", sparcel)
.Case("sparcv9", sparcv9)
.Case("systemz", systemz)
.Case("tce", tce)
+ .Case("tcele", tcele)
.Case("thumb", thumb)
.Case("thumbeb", thumbeb)
.Case("x86", x86)
@@ -373,12 +385,15 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("mips64el", Triple::mips64el)
.Case("r600", Triple::r600)
.Case("amdgcn", Triple::amdgcn)
+ .Case("riscv32", Triple::riscv32)
+ .Case("riscv64", Triple::riscv64)
.Case("hexagon", Triple::hexagon)
.Cases("s390x", "systemz", Triple::systemz)
.Case("sparc", Triple::sparc)
.Case("sparcel", Triple::sparcel)
.Cases("sparcv9", "sparc64", Triple::sparcv9)
.Case("tce", Triple::tce)
+ .Case("tcele", Triple::tcele)
.Case("xcore", Triple::xcore)
.Case("nvptx", Triple::nvptx)
.Case("nvptx64", Triple::nvptx64)
@@ -437,6 +452,7 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("darwin", Triple::Darwin)
.StartsWith("dragonfly", Triple::DragonFly)
.StartsWith("freebsd", Triple::FreeBSD)
+ .StartsWith("fuchsia", Triple::Fuchsia)
.StartsWith("ios", Triple::IOS)
.StartsWith("kfreebsd", Triple::KFreeBSD)
.StartsWith("linux", Triple::Linux)
@@ -462,6 +478,7 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("tvos", Triple::TvOS)
.StartsWith("watchos", Triple::WatchOS)
.StartsWith("mesa3d", Triple::Mesa3D)
+ .StartsWith("contiki", Triple::Contiki)
.Default(Triple::UnknownOS);
}
@@ -484,6 +501,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
.StartsWith("cygnus", Triple::Cygnus)
.StartsWith("amdopencl", Triple::AMDOpenCL)
.StartsWith("coreclr", Triple::CoreCLR)
+ .StartsWith("opencl", Triple::OpenCL)
.Default(Triple::UnknownEnvironment);
}
@@ -546,6 +564,8 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
return Triple::ARMSubArch_v8_1a;
case ARM::AK_ARMV8_2A:
return Triple::ARMSubArch_v8_2a;
+ case ARM::AK_ARMV8R:
+ return Triple::ARMSubArch_v8r;
case ARM::AK_ARMV8MBaseline:
return Triple::ARMSubArch_v8m_baseline;
case ARM::AK_ARMV8MMainline:
@@ -555,7 +575,7 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
}
}
-static const char *getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
+static StringRef getObjectFormatTypeName(Triple::ObjectFormatType Kind) {
switch (Kind) {
case Triple::UnknownObjectFormat: return "";
case Triple::COFF: return "coff";
@@ -605,6 +625,8 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::r600:
case Triple::renderscript32:
case Triple::renderscript64:
+ case Triple::riscv32:
+ case Triple::riscv64:
case Triple::shave:
case Triple::sparc:
case Triple::sparcel:
@@ -613,6 +635,7 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) {
case Triple::spir64:
case Triple::systemz:
case Triple::tce:
+ case Triple::tcele:
case Triple::thumbeb:
case Triple::wasm32:
case Triple::wasm64:
@@ -1132,9 +1155,11 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::nvptx:
case llvm::Triple::ppc:
case llvm::Triple::r600:
+ case llvm::Triple::riscv32:
case llvm::Triple::sparc:
case llvm::Triple::sparcel:
case llvm::Triple::tce:
+ case llvm::Triple::tcele:
case llvm::Triple::thumb:
case llvm::Triple::thumbeb:
case llvm::Triple::x86:
@@ -1160,6 +1185,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::nvptx64:
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
+ case llvm::Triple::riscv64:
case llvm::Triple::sparcv9:
case llvm::Triple::systemz:
case llvm::Triple::x86_64:
@@ -1212,9 +1238,11 @@ Triple Triple::get32BitArchVariant() const {
case Triple::nvptx:
case Triple::ppc:
case Triple::r600:
+ case Triple::riscv32:
case Triple::sparc:
case Triple::sparcel:
case Triple::tce:
+ case Triple::tcele:
case Triple::thumb:
case Triple::thumbeb:
case Triple::x86:
@@ -1234,6 +1262,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::nvptx64: T.setArch(Triple::nvptx); break;
case Triple::ppc64: T.setArch(Triple::ppc); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
+ case Triple::riscv64: T.setArch(Triple::riscv32); break;
case Triple::x86_64: T.setArch(Triple::x86); break;
case Triple::amdil64: T.setArch(Triple::amdil); break;
case Triple::hsail64: T.setArch(Triple::hsail); break;
@@ -1255,6 +1284,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::msp430:
case Triple::r600:
case Triple::tce:
+ case Triple::tcele:
case Triple::xcore:
case Triple::sparcel:
case Triple::shave:
@@ -1275,6 +1305,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::nvptx64:
case Triple::ppc64:
case Triple::ppc64le:
+ case Triple::riscv64:
case Triple::sparcv9:
case Triple::systemz:
case Triple::x86_64:
@@ -1291,6 +1322,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::nvptx: T.setArch(Triple::nvptx64); break;
case Triple::ppc: T.setArch(Triple::ppc64); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
+ case Triple::riscv32: T.setArch(Triple::riscv64); break;
case Triple::x86: T.setArch(Triple::x86_64); break;
case Triple::amdil: T.setArch(Triple::amdil64); break;
case Triple::hsail: T.setArch(Triple::hsail64); break;
@@ -1324,6 +1356,8 @@ Triple Triple::getBigEndianArchVariant() const {
case Triple::nvptx64:
case Triple::nvptx:
case Triple::r600:
+ case Triple::riscv32:
+ case Triple::riscv64:
case Triple::shave:
case Triple::spir64:
case Triple::spir:
@@ -1342,6 +1376,7 @@ Triple Triple::getBigEndianArchVariant() const {
T.setArch(UnknownArch);
break;
+ case Triple::tcele: T.setArch(Triple::tce); break;
case Triple::aarch64: T.setArch(Triple::aarch64_be); break;
case Triple::bpfel: T.setArch(Triple::bpfeb); break;
case Triple::mips64el:T.setArch(Triple::mips64); break;
@@ -1365,7 +1400,6 @@ Triple Triple::getLittleEndianArchVariant() const {
case Triple::ppc:
case Triple::sparcv9:
case Triple::systemz:
- case Triple::tce:
// ARM is intentionally unsupported here, changing the architecture would
// drop any arch suffixes.
@@ -1374,6 +1408,7 @@ Triple Triple::getLittleEndianArchVariant() const {
T.setArch(UnknownArch);
break;
+ case Triple::tce: T.setArch(Triple::tcele); break;
case Triple::aarch64_be: T.setArch(Triple::aarch64); break;
case Triple::bpfeb: T.setArch(Triple::bpfel); break;
case Triple::mips64: T.setArch(Triple::mips64el); break;
@@ -1408,6 +1443,8 @@ bool Triple::isLittleEndian() const {
case Triple::nvptx:
case Triple::ppc64le:
case Triple::r600:
+ case Triple::riscv32:
+ case Triple::riscv64:
case Triple::shave:
case Triple::sparcel:
case Triple::spir64:
@@ -1418,6 +1455,7 @@ bool Triple::isLittleEndian() const {
case Triple::x86:
case Triple::x86_64:
case Triple::xcore:
+ case Triple::tcele:
case Triple::renderscript32:
case Triple::renderscript64:
return true;
diff --git a/contrib/llvm/lib/Support/Twine.cpp b/contrib/llvm/lib/Support/Twine.cpp
index 5e989fb..465c6e6 100644
--- a/contrib/llvm/lib/Support/Twine.cpp
+++ b/contrib/llvm/lib/Support/Twine.cpp
@@ -10,6 +10,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -18,6 +19,11 @@ std::string Twine::str() const {
if (LHSKind == StdStringKind && RHSKind == EmptyKind)
return *LHS.stdString;
+ // If we're storing a formatv_object, we can avoid an extra copy by formatting
+ // it immediately and returning the result.
+ if (LHSKind == FormatvObjectKind && RHSKind == EmptyKind)
+ return LHS.formatvObject->str();
+
// Otherwise, flatten and copy the contents first.
SmallString<256> Vec;
return toStringRef(Vec).str();
@@ -68,6 +74,9 @@ void Twine::printOneChild(raw_ostream &OS, Child Ptr,
case Twine::SmallStringKind:
OS << *Ptr.smallString;
break;
+ case Twine::FormatvObjectKind:
+ OS << *Ptr.formatvObject;
+ break;
case Twine::CharKind:
OS << Ptr.character;
break;
@@ -121,6 +130,9 @@ void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
case Twine::SmallStringKind:
OS << "smallstring:\"" << *Ptr.smallString << "\"";
break;
+ case Twine::FormatvObjectKind:
+ OS << "formatv:\"" << *Ptr.formatvObject << "\"";
+ break;
case Twine::CharKind:
OS << "char:\"" << Ptr.character << "\"";
break;
diff --git a/contrib/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm/lib/Support/Unix/Memory.inc
index f3463e5..edbc793 100644
--- a/contrib/llvm/lib/Support/Unix/Memory.inc
+++ b/contrib/llvm/lib/Support/Unix/Memory.inc
@@ -91,17 +91,9 @@ Memory::allocateMappedMemory(size_t NumBytes,
const size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
-#ifdef NEED_DEV_ZERO_FOR_MMAP
- static int zero_fd = open("/dev/zero", O_RDWR);
- if (zero_fd == -1) {
- EC = std::error_code(errno, std::generic_category());
- return MemoryBlock();
- }
- fd = zero_fd;
-#endif
int MMFlags = MAP_PRIVATE |
-#ifdef HAVE_MMAP_ANONYMOUS
+#ifdef MAP_ANONYMOUS
MAP_ANONYMOUS
#else
MAP_ANON
@@ -161,7 +153,10 @@ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
int Protect = getPosixProtectionFlags(Flags);
- int Result = ::mprotect((void*)((uintptr_t)M.Address & ~(PageSize-1)), PageSize*((M.Size+PageSize-1)/PageSize), Protect);
+ uintptr_t Start = alignAddr((uint8_t *)M.Address - PageSize + 1, PageSize);
+ uintptr_t End = alignAddr((uint8_t *)M.Address + M.Size, PageSize);
+ int Result = ::mprotect((void *)Start, End - Start, Protect);
+
if (Result != 0)
return std::error_code(errno, std::generic_category());
@@ -185,17 +180,9 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
-#ifdef NEED_DEV_ZERO_FOR_MMAP
- static int zero_fd = open("/dev/zero", O_RDWR);
- if (zero_fd == -1) {
- MakeErrMsg(ErrMsg, "Can't open /dev/zero device");
- return MemoryBlock();
- }
- fd = zero_fd;
-#endif
int flags = MAP_PRIVATE |
-#ifdef HAVE_MMAP_ANONYMOUS
+#ifdef MAP_ANONYMOUS
MAP_ANONYMOUS
#else
MAP_ANON
diff --git a/contrib/llvm/lib/Support/Unix/Path.inc b/contrib/llvm/lib/Support/Unix/Path.inc
index 84aafcb..e0b11aa 100644
--- a/contrib/llvm/lib/Support/Unix/Path.inc
+++ b/contrib/llvm/lib/Support/Unix/Path.inc
@@ -53,7 +53,7 @@
#include <sys/attr.h>
#endif
-// Both stdio.h and cstdio are included via different pathes and
+// Both stdio.h and cstdio are included via different paths and
// stdcxx's cstdio doesn't include stdio.h, so it doesn't #undef the macros
// either.
#undef ferror
@@ -90,7 +90,8 @@ namespace sys {
namespace fs {
#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \
- defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__)
+ defined(__linux__) || defined(__CYGWIN__) || defined(__DragonFly__) || \
+ defined(_AIX)
static int
test_dir(char ret[PATH_MAX], const char *dir, const char *bin)
{
@@ -161,7 +162,7 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
}
#elif defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
defined(__OpenBSD__) || defined(__minix) || defined(__DragonFly__) || \
- defined(__FreeBSD_kernel__)
+ defined(__FreeBSD_kernel__) || defined(_AIX)
char exe_path[PATH_MAX];
if (getprogpath(exe_path, argv0) != NULL)
@@ -197,16 +198,12 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
return "";
}
-TimeValue file_status::getLastAccessedTime() const {
- TimeValue Ret;
- Ret.fromEpochTime(fs_st_atime);
- return Ret;
+TimePoint<> file_status::getLastAccessedTime() const {
+ return toTimePoint(fs_st_atime);
}
-TimeValue file_status::getLastModificationTime() const {
- TimeValue Ret;
- Ret.fromEpochTime(fs_st_mtime);
- return Ret;
+TimePoint<> file_status::getLastModificationTime() const {
+ return toTimePoint(fs_st_mtime);
}
UniqueID file_status::getUniqueID() const {
@@ -288,6 +285,19 @@ std::error_code create_link(const Twine &to, const Twine &from) {
return std::error_code();
}
+std::error_code create_hard_link(const Twine &to, const Twine &from) {
+ // Get arguments.
+ SmallString<128> from_storage;
+ SmallString<128> to_storage;
+ StringRef f = from.toNullTerminatedStringRef(from_storage);
+ StringRef t = to.toNullTerminatedStringRef(to_storage);
+
+ if (::link(t.begin(), f.begin()) == -1)
+ return std::error_code(errno, std::generic_category());
+
+ return std::error_code();
+}
+
std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
SmallString<128> path_storage;
StringRef p = path.toNullTerminatedStringRef(path_storage);
@@ -329,8 +339,17 @@ std::error_code rename(const Twine &from, const Twine &to) {
}
std::error_code resize_file(int FD, uint64_t Size) {
+#if defined(HAVE_POSIX_FALLOCATE)
+ // If we have posix_fallocate use it. Unlike ftruncate it always allocates
+ // space, so we get an error if the disk is full.
+ if (int Err = ::posix_fallocate(FD, 0, Size))
+ return std::error_code(Err, std::generic_category());
+#else
+ // Use ftruncate as a fallback. It may or may not allocate space. At least on
+ // OS X with HFS+ it does.
if (::ftruncate(FD, Size) == -1)
return std::error_code(errno, std::generic_category());
+#endif
return std::error_code();
}
@@ -436,20 +455,17 @@ std::error_code status(int FD, file_status &Result) {
return fillStatus(StatRet, Status, Result);
}
-std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
+std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
#if defined(HAVE_FUTIMENS)
timespec Times[2];
- Times[0].tv_sec = Time.toEpochTime();
- Times[0].tv_nsec = 0;
- Times[1] = Times[0];
+ Times[0] = Times[1] = sys::toTimeSpec(Time);
if (::futimens(FD, Times))
return std::error_code(errno, std::generic_category());
return std::error_code();
#elif defined(HAVE_FUTIMES)
timeval Times[2];
- Times[0].tv_sec = Time.toEpochTime();
- Times[0].tv_usec = 0;
- Times[1] = Times[0];
+ Times[0] = Times[1] = sys::toTimeVal(
+ std::chrono::time_point_cast<std::chrono::microseconds>(Time));
if (::futimes(FD, Times))
return std::error_code(errno, std::generic_category());
return std::error_code();
diff --git a/contrib/llvm/lib/Support/Unix/Process.inc b/contrib/llvm/lib/Support/Unix/Process.inc
index d81836b..16f8f5a 100644
--- a/contrib/llvm/lib/Support/Unix/Process.inc
+++ b/contrib/llvm/lib/Support/Unix/Process.inc
@@ -17,7 +17,6 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
-#include "llvm/Support/TimeValue.h"
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
@@ -60,22 +59,14 @@
using namespace llvm;
using namespace sys;
-static std::pair<TimeValue, TimeValue> getRUsageTimes() {
+static std::pair<std::chrono::microseconds, std::chrono::microseconds> getRUsageTimes() {
#if defined(HAVE_GETRUSAGE)
struct rusage RU;
::getrusage(RUSAGE_SELF, &RU);
- return std::make_pair(
- TimeValue(
- static_cast<TimeValue::SecondsType>(RU.ru_utime.tv_sec),
- static_cast<TimeValue::NanoSecondsType>(
- RU.ru_utime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)),
- TimeValue(
- static_cast<TimeValue::SecondsType>(RU.ru_stime.tv_sec),
- static_cast<TimeValue::NanoSecondsType>(
- RU.ru_stime.tv_usec * TimeValue::NANOSECONDS_PER_MICROSECOND)));
+ return { toDuration(RU.ru_utime), toDuration(RU.ru_stime) };
#else
#warning Cannot get usage times on this platform
- return std::make_pair(TimeValue(), TimeValue());
+ return { std::chrono::microseconds::zero(), std::chrono::microseconds::zero() };
#endif
}
@@ -121,9 +112,9 @@ size_t Process::GetMallocUsage() {
#endif
}
-void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
- TimeValue &sys_time) {
- elapsed = TimeValue::now();
+void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
+ std::chrono::nanoseconds &sys_time) {
+ elapsed = std::chrono::system_clock::now();
std::tie(user_time, sys_time) = getRUsageTimes();
}
@@ -429,7 +420,7 @@ const char *Process::ResetColor() {
return "\033[0m";
}
-#if !defined(HAVE_DECL_ARC4RANDOM) || !HAVE_DECL_ARC4RANDOM
+#if !HAVE_DECL_ARC4RANDOM
static unsigned GetRandomNumberSeed() {
// Attempt to get the initial seed from /dev/urandom, if possible.
int urandomFD = open("/dev/urandom", O_RDONLY);
@@ -449,13 +440,13 @@ static unsigned GetRandomNumberSeed() {
// Otherwise, swizzle the current time and the process ID to form a reasonable
// seed.
- TimeValue Now = TimeValue::now();
- return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
+ const auto Now = std::chrono::high_resolution_clock::now();
+ return hash_combine(Now.time_since_epoch().count(), ::getpid());
}
#endif
unsigned llvm::sys::Process::GetRandomNumber() {
-#if defined(HAVE_DECL_ARC4RANDOM) && HAVE_DECL_ARC4RANDOM
+#if HAVE_DECL_ARC4RANDOM
return arc4random();
#else
static int x = (static_cast<void>(::srand(GetRandomNumberSeed())), 0);
diff --git a/contrib/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm/lib/Support/Unix/Signals.inc
index 55fd76d..9752b70 100644
--- a/contrib/llvm/lib/Support/Unix/Signals.inc
+++ b/contrib/llvm/lib/Support/Unix/Signals.inc
@@ -14,6 +14,7 @@
#include "Unix.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Demangle/Demangle.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
@@ -33,9 +34,6 @@
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
-#if HAVE_CXXABI_H
-#include <cxxabi.h>
-#endif
#if HAVE_DLFCN_H
#include <dlfcn.h>
#endif
@@ -45,7 +43,7 @@
#if HAVE_LINK_H
#include <link.h>
#endif
-#if HAVE_UNWIND_BACKTRACE
+#ifdef HAVE__UNWIND_BACKTRACE
// FIXME: We should be able to use <unwind.h> for any target that has an
// _Unwind_Backtrace function, but on FreeBSD the configure test passes
// despite the function not existing, and on Android, <unwind.h> conflicts
@@ -53,7 +51,7 @@
#ifdef __GLIBC__
#include <unwind.h>
#else
-#undef HAVE_UNWIND_BACKTRACE
+#undef HAVE__UNWIND_BACKTRACE
#endif
#endif
@@ -120,14 +118,15 @@ static void RegisterHandler(int Signal) {
}
#if defined(HAVE_SIGALTSTACK)
-// Hold onto the old alternate signal stack so that it's not reported as a leak.
-// We don't make any attempt to remove our alt signal stack if we remove our
-// signal handlers; that can't be done reliably if someone else is also trying
-// to do the same thing.
+// Hold onto both the old and new alternate signal stack so that it's not
+// reported as a leak. We don't make any attempt to remove our alt signal
+// stack if we remove our signal handlers; that can't be done reliably if
+// someone else is also trying to do the same thing.
static stack_t OldAltStack;
+static void* NewAltStackPointer;
static void CreateSigAltStack() {
- const size_t AltStackSize = MINSIGSTKSZ + 8192;
+ const size_t AltStackSize = MINSIGSTKSZ + 64 * 1024;
// If we're executing on the alternate stack, or we already have an alternate
// signal stack that we're happy with, there's nothing for us to do. Don't
@@ -140,6 +139,7 @@ static void CreateSigAltStack() {
stack_t AltStack = {};
AltStack.ss_sp = reinterpret_cast<char *>(malloc(AltStackSize));
+ NewAltStackPointer = AltStack.ss_sp; // Save to avoid reporting a leak.
AltStack.ss_size = AltStackSize;
if (sigaltstack(&AltStack, &OldAltStack) != 0)
free(AltStack.ss_sp);
@@ -284,7 +284,7 @@ bool llvm::sys::RemoveFileOnSignal(StringRef Filename,
void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) {
sys::SmartScopedLock<true> Guard(*SignalsMutex);
std::vector<std::string>::reverse_iterator RI =
- std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename);
+ find(reverse(*FilesToRemove), Filename);
std::vector<std::string>::iterator I = FilesToRemove->end();
if (RI != FilesToRemove->rend())
I = FilesToRemove->erase(RI.base()-1);
@@ -298,7 +298,7 @@ void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
RegisterHandlers();
}
-#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) && HAVE_LINK_H && \
+#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \
(defined(__linux__) || defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || defined(__NetBSD__))
struct DlIteratePhdrData {
@@ -353,9 +353,9 @@ static bool findModulesAndOffsets(void **StackTrace, int Depth,
StringSaver &StrPool) {
return false;
}
-#endif // defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) && ...
+#endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && ...
-#if defined(ENABLE_BACKTRACES) && defined(HAVE_UNWIND_BACKTRACE)
+#if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE)
static int unwindBacktrace(void **StackTrace, int MaxEntries) {
if (MaxEntries < 0)
return 0;
@@ -393,7 +393,7 @@ static int unwindBacktrace(void **StackTrace, int MaxEntries) {
// On glibc systems we have the 'backtrace' function, which works nicely, but
// doesn't demangle symbols.
void llvm::sys::PrintStackTrace(raw_ostream &OS) {
-#if defined(ENABLE_BACKTRACES)
+#if ENABLE_BACKTRACES
static void *StackTrace[256];
int depth = 0;
#if defined(HAVE_BACKTRACE)
@@ -401,7 +401,7 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS) {
if (!depth)
depth = backtrace(StackTrace, static_cast<int>(array_lengthof(StackTrace)));
#endif
-#if defined(HAVE_UNWIND_BACKTRACE)
+#if defined(HAVE__UNWIND_BACKTRACE)
// Try _Unwind_Backtrace() if backtrace() failed.
if (!depth)
depth = unwindBacktrace(StackTrace,
@@ -441,12 +441,8 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS) {
if (dlinfo.dli_sname != nullptr) {
OS << ' ';
-# if HAVE_CXXABI_H
int res;
- char* d = abi::__cxa_demangle(dlinfo.dli_sname, nullptr, nullptr, &res);
-# else
- char* d = NULL;
-# endif
+ char* d = itaniumDemangle(dlinfo.dli_sname, nullptr, nullptr, &res);
if (!d) OS << dlinfo.dli_sname;
else OS << d;
free(d);
@@ -479,7 +475,7 @@ void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
-#if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES)
+#if defined(__APPLE__) && ENABLE_CRASH_OVERRIDES
// Environment variable to disable any kind of crash dialog.
if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT")) {
mach_port_t self = mach_task_self();
diff --git a/contrib/llvm/lib/Support/Unix/TimeValue.inc b/contrib/llvm/lib/Support/Unix/TimeValue.inc
deleted file mode 100644
index 042e0da..0000000
--- a/contrib/llvm/lib/Support/Unix/TimeValue.inc
+++ /dev/null
@@ -1,54 +0,0 @@
-//===- Unix/TimeValue.cpp - Unix TimeValue Implementation -------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Unix specific portion of the TimeValue class.
-//
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only generic UNIX code that
-//=== is guaranteed to work on *all* UNIX variants.
-//===----------------------------------------------------------------------===//
-
-#include "Unix.h"
-
-namespace llvm {
- using namespace sys;
-
-std::string TimeValue::str() const {
- time_t OurTime = time_t(this->toEpochTime());
- struct tm Storage;
- struct tm *LT = ::localtime_r(&OurTime, &Storage);
- assert(LT);
- char Buffer1[sizeof("YYYY-MM-DD HH:MM:SS")];
- strftime(Buffer1, sizeof(Buffer1), "%Y-%m-%d %H:%M:%S", LT);
- char Buffer2[sizeof("YYYY-MM-DD HH:MM:SS.MMMUUUNNN")];
- snprintf(Buffer2, sizeof(Buffer2), "%s.%.9u", Buffer1, this->nanoseconds());
- return std::string(Buffer2);
-}
-
-TimeValue TimeValue::now() {
- struct timeval the_time;
- timerclear(&the_time);
- if (0 != ::gettimeofday(&the_time,nullptr)) {
- // This is *really* unlikely to occur because the only gettimeofday
- // errors concern the timezone parameter which we're passing in as 0.
- // In the unlikely case it does happen, just return MinTime, no error
- // message needed.
- return MinTime();
- }
-
- return TimeValue(
- static_cast<TimeValue::SecondsType>( the_time.tv_sec +
- PosixZeroTimeSeconds ),
- static_cast<TimeValue::NanoSecondsType>( the_time.tv_usec *
- NANOSECONDS_PER_MICROSECOND ) );
-}
-
-}
diff --git a/contrib/llvm/lib/Support/Unix/Unix.h b/contrib/llvm/lib/Support/Unix/Unix.h
index 871e612..239a6d6 100644
--- a/contrib/llvm/lib/Support/Unix/Unix.h
+++ b/contrib/llvm/lib/Support/Unix/Unix.h
@@ -19,7 +19,8 @@
//=== is guaranteed to work on all UNIX variants.
//===----------------------------------------------------------------------===//
-#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "llvm/Support/Chrono.h"
#include "llvm/Support/Errno.h"
#include <algorithm>
#include <assert.h>
@@ -48,6 +49,10 @@
# include <dlfcn.h>
#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
/// This function builds an error message into \p ErrMsg using the \p prefix
/// string and the Unix error number given by \p errnum. If errnum is -1, the
/// default then the value of errno is used.
@@ -65,4 +70,37 @@ static inline bool MakeErrMsg(
return true;
}
+namespace llvm {
+namespace sys {
+
+/// Convert a struct timeval to a duration. Note that timeval can be used both
+/// as a time point and a duration. Be sure to check what the input represents.
+inline std::chrono::microseconds toDuration(const struct timeval &TV) {
+ return std::chrono::seconds(TV.tv_sec) +
+ std::chrono::microseconds(TV.tv_usec);
+}
+
+/// Convert a time point to struct timespec.
+inline struct timespec toTimeSpec(TimePoint<> TP) {
+ using namespace std::chrono;
+
+ struct timespec RetVal;
+ RetVal.tv_sec = toTimeT(TP);
+ RetVal.tv_nsec = (TP.time_since_epoch() % seconds(1)).count();
+ return RetVal;
+}
+
+/// Convert a time point to struct timeval.
+inline struct timeval toTimeVal(TimePoint<std::chrono::microseconds> TP) {
+ using namespace std::chrono;
+
+ struct timeval RetVal;
+ RetVal.tv_sec = toTimeT(TP);
+ RetVal.tv_usec = (TP.time_since_epoch() % seconds(1)).count();
+ return RetVal;
+}
+
+} // namespace sys
+} // namespace llvm
+
#endif
diff --git a/contrib/llvm/lib/Support/Windows/Path.inc b/contrib/llvm/lib/Support/Windows/Path.inc
index fab6aec..27b250b 100644
--- a/contrib/llvm/lib/Support/Windows/Path.inc
+++ b/contrib/llvm/lib/Support/Windows/Path.inc
@@ -164,24 +164,18 @@ ErrorOr<space_info> disk_space(const Twine &Path) {
return SpaceInfo;
}
-TimeValue file_status::getLastAccessedTime() const {
- ULARGE_INTEGER UI;
- UI.LowPart = LastAccessedTimeLow;
- UI.HighPart = LastAccessedTimeHigh;
-
- TimeValue Ret;
- Ret.fromWin32Time(UI.QuadPart);
- return Ret;
+TimePoint<> file_status::getLastAccessedTime() const {
+ FILETIME Time;
+ Time.dwLowDateTime = LastAccessedTimeLow;
+ Time.dwHighDateTime = LastAccessedTimeHigh;
+ return toTimePoint(Time);
}
-TimeValue file_status::getLastModificationTime() const {
- ULARGE_INTEGER UI;
- UI.LowPart = LastWriteTimeLow;
- UI.HighPart = LastWriteTimeHigh;
-
- TimeValue Ret;
- Ret.fromWin32Time(UI.QuadPart);
- return Ret;
+TimePoint<> file_status::getLastModificationTime() const {
+ FILETIME Time;
+ Time.dwLowDateTime = LastWriteTimeLow;
+ Time.dwHighDateTime = LastWriteTimeHigh;
+ return toTimePoint(Time);
}
std::error_code current_path(SmallVectorImpl<char> &result) {
@@ -238,6 +232,10 @@ std::error_code create_link(const Twine &to, const Twine &from) {
return std::error_code();
}
+std::error_code create_hard_link(const Twine &to, const Twine &from) {
+ return create_link(to, from);
+}
+
std::error_code remove(const Twine &path, bool IgnoreNonExisting) {
SmallVector<wchar_t, 128> path_utf16;
@@ -513,12 +511,8 @@ std::error_code status(int FD, file_status &Result) {
return getStatus(FileHandle, Result);
}
-std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
- ULARGE_INTEGER UI;
- UI.QuadPart = Time.toWin32Time();
- FILETIME FT;
- FT.dwLowDateTime = UI.LowPart;
- FT.dwHighDateTime = UI.HighPart;
+std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time) {
+ FILETIME FT = toFILETIME(Time);
HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
if (!SetFileTime(FileHandle, NULL, &FT, &FT))
return mapWindowsError(::GetLastError());
diff --git a/contrib/llvm/lib/Support/Windows/Process.inc b/contrib/llvm/lib/Support/Windows/Process.inc
index b012991..8d646b3 100644
--- a/contrib/llvm/lib/Support/Windows/Process.inc
+++ b/contrib/llvm/lib/Support/Windows/Process.inc
@@ -49,18 +49,6 @@
using namespace llvm;
using namespace sys;
-static TimeValue getTimeValueFromFILETIME(FILETIME Time) {
- ULARGE_INTEGER TimeInteger;
- TimeInteger.LowPart = Time.dwLowDateTime;
- TimeInteger.HighPart = Time.dwHighDateTime;
-
- // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
- return TimeValue(
- static_cast<TimeValue::SecondsType>(TimeInteger.QuadPart / 10000000),
- static_cast<TimeValue::NanoSecondsType>(
- (TimeInteger.QuadPart % 10000000) * 100));
-}
-
// This function retrieves the page size using GetNativeSystemInfo() and is
// present solely so it can be called once to initialize the self_process member
// below.
@@ -93,17 +81,17 @@ Process::GetMallocUsage()
return size;
}
-void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
- TimeValue &sys_time) {
- elapsed = TimeValue::now();
+void Process::GetTimeUsage(TimePoint<> &elapsed, std::chrono::nanoseconds &user_time,
+ std::chrono::nanoseconds &sys_time) {
+ elapsed = std::chrono::system_clock::now();;
FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
&UserTime) == 0)
return;
- user_time = getTimeValueFromFILETIME(UserTime);
- sys_time = getTimeValueFromFILETIME(KernelTime);
+ user_time = toDuration(UserTime);
+ sys_time = toDuration(KernelTime);
}
// Some LLVM programs such as bugpoint produce core files as a normal part of
diff --git a/contrib/llvm/lib/Support/Windows/Signals.inc b/contrib/llvm/lib/Support/Windows/Signals.inc
index 1e2fa42..f739421 100644
--- a/contrib/llvm/lib/Support/Windows/Signals.inc
+++ b/contrib/llvm/lib/Support/Windows/Signals.inc
@@ -28,6 +28,7 @@
#ifdef __MINGW32__
#include <imagehlp.h>
#else
+ #include <crtdbg.h>
#include <dbghelp.h>
#endif
#include <psapi.h>
@@ -266,7 +267,7 @@ static BOOL CALLBACK findModuleCallback(PCSTR ModuleName,
continue;
intptr_t Addr = (intptr_t)Data->StackTrace[I];
if (Beg <= Addr && Addr < End) {
- Data->Modules[I] = Data->StrPool->save(ModuleName);
+ Data->Modules[I] = Data->StrPool->save(ModuleName).data();
Data->Offsets[I] = Addr - Beg;
}
}
@@ -470,7 +471,7 @@ void sys::DontRemoveFileOnSignal(StringRef Filename) {
RegisterHandler();
std::vector<std::string>::reverse_iterator I =
- std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename);
+ find(reverse(*FilesToRemove), Filename);
if (I != FilesToRemove->rend())
FilesToRemove->erase(I.base()-1);
diff --git a/contrib/llvm/lib/Support/Windows/TimeValue.inc b/contrib/llvm/lib/Support/Windows/TimeValue.inc
deleted file mode 100644
index b90b4f1..0000000
--- a/contrib/llvm/lib/Support/Windows/TimeValue.inc
+++ /dev/null
@@ -1,61 +0,0 @@
-//===- Win32/TimeValue.cpp - Win32 TimeValue Implementation -----*- 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 the Win32 implementation of the TimeValue class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "WindowsSupport.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cctype>
-#include <time.h>
-
-using namespace llvm;
-using namespace llvm::sys;
-
-//===----------------------------------------------------------------------===//
-//=== WARNING: Implementation here must contain only Win32 specific code.
-//===----------------------------------------------------------------------===//
-
-TimeValue TimeValue::now() {
- uint64_t ft;
- GetSystemTimeAsFileTime(reinterpret_cast<FILETIME *>(&ft));
-
- TimeValue t(0, 0);
- t.fromWin32Time(ft);
- return t;
-}
-
-std::string TimeValue::str() const {
- std::string S;
- struct tm *LT;
-#ifdef __MINGW32__
- // Old versions of mingw don't have _localtime64_s. Remove this once we drop support
- // for them.
- time_t OurTime = time_t(this->toEpochTime());
- LT = ::localtime(&OurTime);
- assert(LT);
-#else
- struct tm Storage;
- __time64_t OurTime = this->toEpochTime();
- int Error = ::_localtime64_s(&Storage, &OurTime);
- assert(!Error);
- (void)Error;
- LT = &Storage;
-#endif
-
- char Buffer[sizeof("YYYY-MM-DD HH:MM:SS")];
- strftime(Buffer, sizeof(Buffer), "%Y-%m-%d %H:%M:%S", LT);
- raw_string_ostream OS(S);
- OS << format("%s.%.9u", static_cast<const char *>(Buffer),
- this->nanoseconds());
- OS.flush();
- return S;
-}
diff --git a/contrib/llvm/lib/Support/Windows/WindowsSupport.h b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
index 18ecdf4e..c358b99 100644
--- a/contrib/llvm/lib/Support/Windows/WindowsSupport.h
+++ b/contrib/llvm/lib/Support/Windows/WindowsSupport.h
@@ -39,12 +39,13 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h" // Get build system configuration settings
+#include "llvm/Support/Chrono.h"
#include "llvm/Support/Compiler.h"
-#include <system_error>
-#include <windows.h>
-#include <wincrypt.h>
#include <cassert>
#include <string>
+#include <system_error>
+#include <windows.h>
+#include <wincrypt.h> // Must be included after windows.h
/// Determines if the program is running on Windows 8 or newer. This
/// reimplements one of the helpers in the Windows 8.1 SDK, which are intended
@@ -211,6 +212,39 @@ c_str(SmallVectorImpl<T> &str) {
}
namespace sys {
+
+inline std::chrono::nanoseconds toDuration(FILETIME Time) {
+ ULARGE_INTEGER TimeInteger;
+ TimeInteger.LowPart = Time.dwLowDateTime;
+ TimeInteger.HighPart = Time.dwHighDateTime;
+
+ // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
+ return std::chrono::nanoseconds(100 * TimeInteger.QuadPart);
+}
+
+inline TimePoint<> toTimePoint(FILETIME Time) {
+ ULARGE_INTEGER TimeInteger;
+ TimeInteger.LowPart = Time.dwLowDateTime;
+ TimeInteger.HighPart = Time.dwHighDateTime;
+
+ // Adjust for different epoch
+ TimeInteger.QuadPart -= 11644473600ll * 10000000;
+
+ // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
+ return TimePoint<>(std::chrono::nanoseconds(100 * TimeInteger.QuadPart));
+}
+
+inline FILETIME toFILETIME(TimePoint<> TP) {
+ ULARGE_INTEGER TimeInteger;
+ TimeInteger.QuadPart = TP.time_since_epoch().count() / 100;
+ TimeInteger.QuadPart += 11644473600ll * 10000000;
+
+ FILETIME Time;
+ Time.dwLowDateTime = TimeInteger.LowPart;
+ Time.dwHighDateTime = TimeInteger.HighPart;
+ return Time;
+}
+
namespace path {
std::error_code widenPath(const Twine &Path8,
SmallVectorImpl<wchar_t> &Path16);
diff --git a/contrib/llvm/lib/Support/YAMLParser.cpp b/contrib/llvm/lib/Support/YAMLParser.cpp
index 620841c..c17a6f6 100644
--- a/contrib/llvm/lib/Support/YAMLParser.cpp
+++ b/contrib/llvm/lib/Support/YAMLParser.cpp
@@ -12,12 +12,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/YAMLParser.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
+#include "llvm/ADT/AllocatorList.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
@@ -108,7 +108,7 @@ void SequenceNode::anchor() {}
void AliasNode::anchor() {}
/// Token - A single YAML token.
-struct Token : ilist_node<Token> {
+struct Token {
enum TokenKind {
TK_Error, // Uninitialized token.
TK_StreamStart,
@@ -147,40 +147,7 @@ struct Token : ilist_node<Token> {
}
}
-namespace llvm {
-template<>
-struct ilist_sentinel_traits<Token> {
- Token *createSentinel() const {
- return &Sentinel;
- }
- static void destroySentinel(Token*) {}
-
- Token *provideInitialHead() const { return createSentinel(); }
- Token *ensureHead(Token*) const { return createSentinel(); }
- static void noteHead(Token*, Token*) {}
-
-private:
- mutable Token Sentinel;
-};
-
-template<>
-struct ilist_node_traits<Token> {
- Token *createNode(const Token &V) {
- return new (Alloc.Allocate<Token>()) Token(V);
- }
- static void deleteNode(Token *V) { V->~Token(); }
-
- void addNodeToList(Token *) {}
- void removeNodeFromList(Token *) {}
- void transferNodesFromList(ilist_node_traits & /*SrcTraits*/,
- ilist_iterator<Token> /*first*/,
- ilist_iterator<Token> /*last*/) {}
-
- BumpPtrAllocator Alloc;
-};
-}
-
-typedef ilist<Token> TokenQueueT;
+typedef llvm::BumpPtrList<Token> TokenQueueT;
namespace {
/// @brief This struct is used to track simple keys.
@@ -265,8 +232,10 @@ namespace yaml {
/// @brief Scans YAML tokens from a MemoryBuffer.
class Scanner {
public:
- Scanner(StringRef Input, SourceMgr &SM, bool ShowColors = true);
- Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors = true);
+ Scanner(StringRef Input, SourceMgr &SM, bool ShowColors = true,
+ std::error_code *EC = nullptr);
+ Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors = true,
+ std::error_code *EC = nullptr);
/// @brief Parse the next token and return it without popping it.
Token &peekNext();
@@ -283,6 +252,10 @@ public:
if (Current >= End)
Current = End - 1;
+ // propagate the error if possible
+ if (EC)
+ *EC = make_error_code(std::errc::invalid_argument);
+
// Don't print out more errors after the first one we encounter. The rest
// are just the result of the first, and have no meaning.
if (!Failed)
@@ -393,10 +366,7 @@ private:
/// @brief Scan ns-uri-char[39]s starting at Cur.
///
/// This updates Cur and Column while scanning.
- ///
- /// @returns A StringRef starting at Cur which covers the longest contiguous
- /// sequence of ns-uri-char.
- StringRef scan_ns_uri_char();
+ void scan_ns_uri_char();
/// @brief Consume a minimal well-formed code unit subsequence starting at
/// \a Cur. Return false if it is not the same Unicode scalar value as
@@ -564,6 +534,8 @@ private:
/// @brief Potential simple keys.
SmallVector<SimpleKey, 4> SimpleKeys;
+
+ std::error_code *EC;
};
} // end namespace yaml
@@ -758,13 +730,15 @@ std::string yaml::escape(StringRef Input) {
return EscapedInput;
}
-Scanner::Scanner(StringRef Input, SourceMgr &sm, bool ShowColors)
- : SM(sm), ShowColors(ShowColors) {
+Scanner::Scanner(StringRef Input, SourceMgr &sm, bool ShowColors,
+ std::error_code *EC)
+ : SM(sm), ShowColors(ShowColors), EC(EC) {
init(MemoryBufferRef(Input, "YAML"));
}
-Scanner::Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors)
- : SM(SM_), ShowColors(ShowColors) {
+Scanner::Scanner(MemoryBufferRef Buffer, SourceMgr &SM_, bool ShowColors,
+ std::error_code *EC)
+ : SM(SM_), ShowColors(ShowColors), EC(EC) {
init(Buffer);
}
@@ -802,8 +776,7 @@ Token &Scanner::peekNext() {
removeStaleSimpleKeyCandidates();
SimpleKey SK;
SK.Tok = TokenQueue.begin();
- if (std::find(SimpleKeys.begin(), SimpleKeys.end(), SK)
- == SimpleKeys.end())
+ if (!is_contained(SimpleKeys, SK))
break;
else
NeedMore = true;
@@ -819,9 +792,8 @@ Token Scanner::getNext() {
// There cannot be any referenced Token's if the TokenQueue is empty. So do a
// quick deallocation of them all.
- if (TokenQueue.empty()) {
- TokenQueue.Alloc.Reset();
- }
+ if (TokenQueue.empty())
+ TokenQueue.resetAlloc();
return Ret;
}
@@ -918,8 +890,7 @@ static bool is_ns_word_char(const char C) {
|| (C >= 'A' && C <= 'Z');
}
-StringRef Scanner::scan_ns_uri_char() {
- StringRef::iterator Start = Current;
+void Scanner::scan_ns_uri_char() {
while (true) {
if (Current == End)
break;
@@ -935,7 +906,6 @@ StringRef Scanner::scan_ns_uri_char() {
} else
break;
}
- return StringRef(Start, Current - Start);
}
bool Scanner::consume(uint32_t Expected) {
@@ -1766,11 +1736,13 @@ bool Scanner::fetchMoreTokens() {
return false;
}
-Stream::Stream(StringRef Input, SourceMgr &SM, bool ShowColors)
- : scanner(new Scanner(Input, SM, ShowColors)), CurrentDoc() {}
+Stream::Stream(StringRef Input, SourceMgr &SM, bool ShowColors,
+ std::error_code *EC)
+ : scanner(new Scanner(Input, SM, ShowColors, EC)), CurrentDoc() {}
-Stream::Stream(MemoryBufferRef InputBuffer, SourceMgr &SM, bool ShowColors)
- : scanner(new Scanner(InputBuffer, SM, ShowColors)), CurrentDoc() {}
+Stream::Stream(MemoryBufferRef InputBuffer, SourceMgr &SM, bool ShowColors,
+ std::error_code *EC)
+ : scanner(new Scanner(InputBuffer, SM, ShowColors, EC)), CurrentDoc() {}
Stream::~Stream() {}
diff --git a/contrib/llvm/lib/Support/YAMLTraits.cpp b/contrib/llvm/lib/Support/YAMLTraits.cpp
index 75fac20..9849b3a 100644
--- a/contrib/llvm/lib/Support/YAMLTraits.cpp
+++ b/contrib/llvm/lib/Support/YAMLTraits.cpp
@@ -44,13 +44,10 @@ void IO::setContext(void *Context) {
// Input
//===----------------------------------------------------------------------===//
-Input::Input(StringRef InputContent,
- void *Ctxt,
- SourceMgr::DiagHandlerTy DiagHandler,
- void *DiagHandlerCtxt)
- : IO(Ctxt),
- Strm(new Stream(InputContent, SrcMgr)),
- CurrentNode(nullptr) {
+Input::Input(StringRef InputContent, void *Ctxt,
+ SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
+ : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)),
+ CurrentNode(nullptr) {
if (DiagHandler)
SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
DocIterator = Strm->begin();
@@ -121,6 +118,18 @@ void Input::beginMapping() {
}
}
+std::vector<StringRef> Input::keys() {
+ MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
+ std::vector<StringRef> Ret;
+ if (!MN) {
+ setError(CurrentNode, "not a mapping");
+ return Ret;
+ }
+ for (auto &P : MN->Mapping)
+ Ret.push_back(P.first());
+ return Ret;
+}
+
bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
void *&SaveInfo) {
UseDefault = false;
@@ -166,7 +175,7 @@ void Input::endMapping() {
if (!MN)
return;
for (const auto &NN : MN->Mapping) {
- if (!MN->isValidKey(NN.first())) {
+ if (!is_contained(MN->ValidKeys, NN.first())) {
setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
break;
}
@@ -376,14 +385,6 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
}
}
-bool Input::MapHNode::isValidKey(StringRef Key) {
- for (const char *K : ValidKeys) {
- if (Key.equals(K))
- return true;
- }
- return false;
-}
-
void Input::setError(const Twine &Message) {
this->setError(CurrentNode, Message);
}
@@ -454,6 +455,10 @@ void Output::endMapping() {
StateStack.pop_back();
}
+std::vector<StringRef> Output::keys() {
+ report_fatal_error("invalid call");
+}
+
bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
bool &UseDefault, void *&) {
UseDefault = false;
diff --git a/contrib/llvm/lib/Support/raw_ostream.cpp b/contrib/llvm/lib/Support/raw_ostream.cpp
index 275fe1d..d073802 100644
--- a/contrib/llvm/lib/Support/raw_ostream.cpp
+++ b/contrib/llvm/lib/Support/raw_ostream.cpp
@@ -20,11 +20,16 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/NativeFormatting.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
+#include <algorithm>
#include <cctype>
#include <cerrno>
+#include <cstdio>
+#include <iterator>
#include <sys/stat.h>
#include <system_error>
@@ -110,73 +115,28 @@ void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
}
raw_ostream &raw_ostream::operator<<(unsigned long N) {
- // Zero is a special case.
- if (N == 0)
- return *this << '0';
-
- char NumberBuffer[20];
- char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
- char *CurPtr = EndPtr;
-
- while (N) {
- *--CurPtr = '0' + char(N % 10);
- N /= 10;
- }
- return write(CurPtr, EndPtr-CurPtr);
+ write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
+ return *this;
}
raw_ostream &raw_ostream::operator<<(long N) {
- if (N < 0) {
- *this << '-';
- // Avoid undefined behavior on LONG_MIN with a cast.
- N = -(unsigned long)N;
- }
-
- return this->operator<<(static_cast<unsigned long>(N));
+ write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
+ return *this;
}
raw_ostream &raw_ostream::operator<<(unsigned long long N) {
- // Output using 32-bit div/mod when possible.
- if (N == static_cast<unsigned long>(N))
- return this->operator<<(static_cast<unsigned long>(N));
-
- char NumberBuffer[20];
- char *EndPtr = std::end(NumberBuffer);
- char *CurPtr = EndPtr;
-
- while (N) {
- *--CurPtr = '0' + char(N % 10);
- N /= 10;
- }
- return write(CurPtr, EndPtr-CurPtr);
+ write_integer(*this, static_cast<uint64_t>(N), 0, IntegerStyle::Integer);
+ return *this;
}
raw_ostream &raw_ostream::operator<<(long long N) {
- if (N < 0) {
- *this << '-';
- // Avoid undefined behavior on INT64_MIN with a cast.
- N = -(unsigned long long)N;
- }
-
- return this->operator<<(static_cast<unsigned long long>(N));
+ write_integer(*this, static_cast<int64_t>(N), 0, IntegerStyle::Integer);
+ return *this;
}
raw_ostream &raw_ostream::write_hex(unsigned long long N) {
- // Zero is a special case.
- if (N == 0)
- return *this << '0';
-
- char NumberBuffer[16];
- char *EndPtr = std::end(NumberBuffer);
- char *CurPtr = EndPtr;
-
- while (N) {
- unsigned char x = static_cast<unsigned char>(N) % 16;
- *--CurPtr = hexdigit(x, /*LowerCase*/true);
- N /= 16;
- }
-
- return write(CurPtr, EndPtr-CurPtr);
+ llvm::write_hex(*this, N, HexPrintStyle::Lower);
+ return *this;
}
raw_ostream &raw_ostream::write_escaped(StringRef Str,
@@ -220,54 +180,15 @@ raw_ostream &raw_ostream::write_escaped(StringRef Str,
}
raw_ostream &raw_ostream::operator<<(const void *P) {
- *this << '0' << 'x';
-
- return write_hex((uintptr_t) P);
+ llvm::write_hex(*this, (uintptr_t)P, HexPrintStyle::PrefixLower);
+ return *this;
}
raw_ostream &raw_ostream::operator<<(double N) {
-#ifdef _WIN32
- // On MSVCRT and compatible, output of %e is incompatible to Posix
- // by default. Number of exponent digits should be at least 2. "%+03d"
- // FIXME: Implement our formatter to here or Support/Format.h!
-#if defined(__MINGW32__)
- // FIXME: It should be generic to C++11.
- if (N == 0.0 && std::signbit(N))
- return *this << "-0.000000e+00";
-#else
- int fpcl = _fpclass(N);
-
- // negative zero
- if (fpcl == _FPCLASS_NZ)
- return *this << "-0.000000e+00";
-#endif
-
- char buf[16];
- unsigned len;
- len = format("%e", N).snprint(buf, sizeof(buf));
- if (len <= sizeof(buf) - 2) {
- if (len >= 5 && buf[len - 5] == 'e' && buf[len - 3] == '0') {
- int cs = buf[len - 4];
- if (cs == '+' || cs == '-') {
- int c1 = buf[len - 2];
- int c0 = buf[len - 1];
- if (isdigit(static_cast<unsigned char>(c1)) &&
- isdigit(static_cast<unsigned char>(c0))) {
- // Trim leading '0': "...e+012" -> "...e+12\0"
- buf[len - 3] = c1;
- buf[len - 2] = c0;
- buf[--len] = 0;
- }
- }
- }
- return this->operator<<(buf);
- }
-#endif
- return this->operator<<(format("%e", N));
+ llvm::write_double(*this, N, FloatStyle::Exponent);
+ return *this;
}
-
-
void raw_ostream::flush_nonempty() {
assert(OutBufCur > OutBufStart && "Invalid call to flush_nonempty.");
size_t Length = OutBufCur - OutBufStart;
@@ -344,10 +265,10 @@ void raw_ostream::copy_to_buffer(const char *Ptr, size_t Size) {
// Handle short strings specially, memcpy isn't very good at very short
// strings.
switch (Size) {
- case 4: OutBufCur[3] = Ptr[3]; // FALL THROUGH
- case 3: OutBufCur[2] = Ptr[2]; // FALL THROUGH
- case 2: OutBufCur[1] = Ptr[1]; // FALL THROUGH
- case 1: OutBufCur[0] = Ptr[0]; // FALL THROUGH
+ case 4: OutBufCur[3] = Ptr[3]; LLVM_FALLTHROUGH;
+ case 3: OutBufCur[2] = Ptr[2]; LLVM_FALLTHROUGH;
+ case 2: OutBufCur[1] = Ptr[1]; LLVM_FALLTHROUGH;
+ case 1: OutBufCur[0] = Ptr[0]; LLVM_FALLTHROUGH;
case 0: break;
default:
memcpy(OutBufCur, Ptr, Size);
@@ -382,7 +303,7 @@ raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
// space. Iterate until we win.
SmallVector<char, 128> V;
- while (1) {
+ while (true) {
V.resize(NextBufferSize);
// Try formatting into the SmallVector.
@@ -398,6 +319,12 @@ raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
}
}
+raw_ostream &raw_ostream::operator<<(const formatv_object_base &Obj) {
+ SmallString<128> S;
+ Obj.format(*this);
+ return *this;
+}
+
raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
unsigned Len = FS.Str.size();
int PadAmount = FS.Width - Len;
@@ -411,51 +338,99 @@ raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
if (FN.Hex) {
- unsigned Nibbles = (64 - countLeadingZeros(FN.HexValue)+3)/4;
- unsigned PrefixChars = FN.HexPrefix ? 2 : 0;
- unsigned Width = std::max(FN.Width, Nibbles + PrefixChars);
-
- char NumberBuffer[20] = "0x0000000000000000";
- if (!FN.HexPrefix)
- NumberBuffer[1] = '0';
- char *EndPtr = NumberBuffer+Width;
- char *CurPtr = EndPtr;
- unsigned long long N = FN.HexValue;
- while (N) {
- unsigned char x = static_cast<unsigned char>(N) % 16;
- *--CurPtr = hexdigit(x, !FN.Upper);
- N /= 16;
+ HexPrintStyle Style;
+ if (FN.Upper && FN.HexPrefix)
+ Style = HexPrintStyle::PrefixUpper;
+ else if (FN.Upper && !FN.HexPrefix)
+ Style = HexPrintStyle::Upper;
+ else if (!FN.Upper && FN.HexPrefix)
+ Style = HexPrintStyle::PrefixLower;
+ else
+ Style = HexPrintStyle::Lower;
+ llvm::write_hex(*this, FN.HexValue, Style, FN.Width);
+ } else {
+ llvm::SmallString<16> Buffer;
+ llvm::raw_svector_ostream Stream(Buffer);
+ llvm::write_integer(Stream, FN.DecValue, 0, IntegerStyle::Integer);
+ if (Buffer.size() < FN.Width)
+ indent(FN.Width - Buffer.size());
+ (*this) << Buffer;
+ }
+ return *this;
+}
+
+raw_ostream &raw_ostream::operator<<(const FormattedBytes &FB) {
+ if (FB.Bytes.empty())
+ return *this;
+
+ size_t LineIndex = 0;
+ auto Bytes = FB.Bytes;
+ const size_t Size = Bytes.size();
+ HexPrintStyle HPS = FB.Upper ? HexPrintStyle::Upper : HexPrintStyle::Lower;
+ uint64_t OffsetWidth = 0;
+ if (FB.FirstByteOffset.hasValue()) {
+ // Figure out how many nibbles are needed to print the largest offset
+ // represented by this data set, so that we can align the offset field
+ // to the right width.
+ size_t Lines = Size / FB.NumPerLine;
+ uint64_t MaxOffset = *FB.FirstByteOffset + Lines * FB.NumPerLine;
+ unsigned Power = 0;
+ if (MaxOffset > 0)
+ Power = llvm::Log2_64_Ceil(MaxOffset);
+ OffsetWidth = std::max<uint64_t>(4, llvm::alignTo(Power, 4) / 4);
+ }
+
+ // The width of a block of data including all spaces for group separators.
+ unsigned NumByteGroups =
+ alignTo(FB.NumPerLine, FB.ByteGroupSize) / FB.ByteGroupSize;
+ unsigned BlockCharWidth = FB.NumPerLine * 2 + NumByteGroups - 1;
+
+ while (!Bytes.empty()) {
+ indent(FB.IndentLevel);
+
+ if (FB.FirstByteOffset.hasValue()) {
+ uint64_t Offset = FB.FirstByteOffset.getValue();
+ llvm::write_hex(*this, Offset + LineIndex, HPS, OffsetWidth);
+ *this << ": ";
}
- return write(NumberBuffer, Width);
- } else {
- // Zero is a special case.
- if (FN.DecValue == 0) {
- this->indent(FN.Width-1);
- return *this << '0';
+ auto Line = Bytes.take_front(FB.NumPerLine);
+
+ size_t CharsPrinted = 0;
+ // Print the hex bytes for this line in groups
+ for (size_t I = 0; I < Line.size(); ++I, CharsPrinted += 2) {
+ if (I && (I % FB.ByteGroupSize) == 0) {
+ ++CharsPrinted;
+ *this << " ";
+ }
+ llvm::write_hex(*this, Line[I], HPS, 2);
}
- char NumberBuffer[32];
- char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
- char *CurPtr = EndPtr;
- bool Neg = (FN.DecValue < 0);
- uint64_t N = Neg ? -static_cast<uint64_t>(FN.DecValue) : FN.DecValue;
- while (N) {
- *--CurPtr = '0' + char(N % 10);
- N /= 10;
+
+ if (FB.ASCII) {
+ // Print any spaces needed for any bytes that we didn't print on this
+ // line so that the ASCII bytes are correctly aligned.
+ assert(BlockCharWidth >= CharsPrinted);
+ indent(BlockCharWidth - CharsPrinted + 2);
+ *this << "|";
+
+ // Print the ASCII char values for each byte on this line
+ for (uint8_t Byte : Line) {
+ if (isprint(Byte))
+ *this << static_cast<char>(Byte);
+ else
+ *this << '.';
+ }
+ *this << '|';
}
- int Len = EndPtr - CurPtr;
- int Pad = FN.Width - Len;
- if (Neg)
- --Pad;
- if (Pad > 0)
- this->indent(Pad);
- if (Neg)
- *this << '-';
- return write(CurPtr, Len);
+
+ Bytes = Bytes.drop_front(Line.size());
+ LineIndex += Line.size();
+ if (LineIndex < Size)
+ *this << '\n';
}
+ return *this;
}
-
/// indent - Insert 'NumSpaces' spaces.
raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
static const char Spaces[] = " "
@@ -475,7 +450,6 @@ raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
return *this;
}
-
//===----------------------------------------------------------------------===//
// Formatted Output
//===----------------------------------------------------------------------===//
@@ -563,7 +537,6 @@ raw_fd_ostream::~raw_fd_ostream() {
report_fatal_error("IO failure on output stream.", /*GenCrashDiag=*/false);
}
-
void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
assert(FD >= 0 && "File already closed.");
pos += Size;
@@ -625,7 +598,13 @@ void raw_fd_ostream::close() {
uint64_t raw_fd_ostream::seek(uint64_t off) {
assert(SupportsSeeking && "Stream does not support seeking!");
flush();
+#ifdef LLVM_ON_WIN32
+ pos = ::_lseeki64(FD, off, SEEK_SET);
+#elif defined(HAVE_LSEEK64)
+ pos = ::lseek64(FD, off, SEEK_SET);
+#else
pos = ::lseek(FD, off, SEEK_SET);
+#endif
if (pos == (uint64_t)-1)
error_detected();
return pos;
@@ -740,7 +719,6 @@ raw_ostream &llvm::nulls() {
return S;
}
-
//===----------------------------------------------------------------------===//
// raw_string_ostream
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm/lib/Support/xxhash.cpp b/contrib/llvm/lib/Support/xxhash.cpp
new file mode 100644
index 0000000..a7d990b
--- /dev/null
+++ b/contrib/llvm/lib/Support/xxhash.cpp
@@ -0,0 +1,134 @@
+/*
+* xxHash - Fast Hash algorithm
+* Copyright (C) 2012-2016, Yann Collet
+*
+* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* You can contact the author at :
+* - xxHash homepage: http://www.xxhash.com
+* - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+/* based on revision d2df04efcbef7d7f6886d345861e5dfda4edacc1 Removed
+ * everything but a simple interface for computing XXh64. */
+
+#include "llvm/Support/xxhash.h"
+#include "llvm/Support/Endian.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+using namespace llvm;
+using namespace support;
+
+static uint64_t rotl64(uint64_t X, size_t R) {
+ return (X << R) | (X >> (64 - R));
+}
+
+static const uint64_t PRIME64_1 = 11400714785074694791ULL;
+static const uint64_t PRIME64_2 = 14029467366897019727ULL;
+static const uint64_t PRIME64_3 = 1609587929392839161ULL;
+static const uint64_t PRIME64_4 = 9650029242287828579ULL;
+static const uint64_t PRIME64_5 = 2870177450012600261ULL;
+
+static uint64_t round(uint64_t Acc, uint64_t Input) {
+ Acc += Input * PRIME64_2;
+ Acc = rotl64(Acc, 31);
+ Acc *= PRIME64_1;
+ return Acc;
+}
+
+static uint64_t mergeRound(uint64_t Acc, uint64_t Val) {
+ Val = round(0, Val);
+ Acc ^= Val;
+ Acc = Acc * PRIME64_1 + PRIME64_4;
+ return Acc;
+}
+
+uint64_t llvm::xxHash64(StringRef Data) {
+ size_t Len = Data.size();
+ uint64_t Seed = 0;
+ const char *P = Data.data();
+ const char *const BEnd = P + Len;
+ uint64_t H64;
+
+ if (Len >= 32) {
+ const char *const Limit = BEnd - 32;
+ uint64_t V1 = Seed + PRIME64_1 + PRIME64_2;
+ uint64_t V2 = Seed + PRIME64_2;
+ uint64_t V3 = Seed + 0;
+ uint64_t V4 = Seed - PRIME64_1;
+
+ do {
+ V1 = round(V1, endian::read64le(P));
+ P += 8;
+ V2 = round(V2, endian::read64le(P));
+ P += 8;
+ V3 = round(V3, endian::read64le(P));
+ P += 8;
+ V4 = round(V4, endian::read64le(P));
+ P += 8;
+ } while (P <= Limit);
+
+ H64 = rotl64(V1, 1) + rotl64(V2, 7) + rotl64(V3, 12) + rotl64(V4, 18);
+ H64 = mergeRound(H64, V1);
+ H64 = mergeRound(H64, V2);
+ H64 = mergeRound(H64, V3);
+ H64 = mergeRound(H64, V4);
+
+ } else {
+ H64 = Seed + PRIME64_5;
+ }
+
+ H64 += (uint64_t)Len;
+
+ while (P + 8 <= BEnd) {
+ uint64_t const K1 = round(0, endian::read64le(P));
+ H64 ^= K1;
+ H64 = rotl64(H64, 27) * PRIME64_1 + PRIME64_4;
+ P += 8;
+ }
+
+ if (P + 4 <= BEnd) {
+ H64 ^= (uint64_t)(endian::read32le(P)) * PRIME64_1;
+ H64 = rotl64(H64, 23) * PRIME64_2 + PRIME64_3;
+ P += 4;
+ }
+
+ while (P < BEnd) {
+ H64 ^= (*P) * PRIME64_5;
+ H64 = rotl64(H64, 11) * PRIME64_1;
+ P++;
+ }
+
+ H64 ^= H64 >> 33;
+ H64 *= PRIME64_2;
+ H64 ^= H64 >> 29;
+ H64 *= PRIME64_3;
+ H64 ^= H64 >> 32;
+
+ return H64;
+}
OpenPOWER on IntegriCloud