aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp237
-rw-r--r--lib/Support/APInt.cpp4
-rw-r--r--lib/Support/Allocator.cpp2
-rw-r--r--lib/Support/Atomic.cpp14
-rw-r--r--lib/Support/CMakeLists.txt7
-rw-r--r--lib/Support/CommandLine.cpp42
-rw-r--r--lib/Support/ConstantRange.cpp2
-rw-r--r--lib/Support/CrashRecoveryContext.cpp4
-rw-r--r--lib/Support/DAGDeltaAlgorithm.cpp10
-rw-r--r--lib/Support/DataStream.cpp6
-rw-r--r--lib/Support/Debug.cpp4
-rw-r--r--lib/Support/DeltaAlgorithm.cpp14
-rw-r--r--lib/Support/Disassembler.cpp5
-rw-r--r--lib/Support/Dwarf.cpp18
-rw-r--r--lib/Support/DynamicLibrary.cpp6
-rw-r--r--lib/Support/Errno.cpp15
-rw-r--r--lib/Support/ErrorHandling.cpp8
-rw-r--r--lib/Support/FileOutputBuffer.cpp83
-rw-r--r--lib/Support/FileUtilities.cpp8
-rw-r--r--lib/Support/FoldingSet.cpp10
-rw-r--r--lib/Support/GraphWriter.cpp4
-rw-r--r--lib/Support/Host.cpp66
-rw-r--r--lib/Support/LocaleWindows.inc2
-rw-r--r--lib/Support/LocaleXlocale.inc2
-rw-r--r--lib/Support/LockFileManager.cpp2
-rw-r--r--lib/Support/Makefile3
-rw-r--r--lib/Support/Memory.cpp62
-rw-r--r--lib/Support/MemoryBuffer.cpp68
-rw-r--r--lib/Support/Path.cpp3
-rw-r--r--lib/Support/PathV2.cpp2
-rw-r--r--lib/Support/PluginLoader.cpp4
-rw-r--r--lib/Support/PrettyStackTrace.cpp6
-rw-r--r--lib/Support/Process.cpp60
-rw-r--r--lib/Support/Regex.cpp8
-rw-r--r--lib/Support/SourceMgr.cpp6
-rw-r--r--lib/Support/Statistic.cpp4
-rw-r--r--lib/Support/StreamableMemoryObject.cpp24
-rw-r--r--lib/Support/StringRef.cpp7
-rw-r--r--lib/Support/Threading.cpp2
-rw-r--r--lib/Support/Timer.cpp8
-rw-r--r--lib/Support/Triple.cpp67
-rw-r--r--lib/Support/Unix/Memory.inc220
-rw-r--r--lib/Support/Unix/Path.inc17
-rw-r--r--lib/Support/Unix/PathV2.inc11
-rw-r--r--lib/Support/Unix/Process.inc99
-rw-r--r--lib/Support/Unix/Program.inc27
-rw-r--r--lib/Support/Unix/Signals.inc34
-rw-r--r--lib/Support/Unix/Unix.h6
-rw-r--r--lib/Support/Windows/Memory.inc167
-rw-r--r--lib/Support/Windows/Path.inc2
-rw-r--r--lib/Support/Windows/PathV2.inc6
-rw-r--r--lib/Support/Windows/Process.inc87
-rw-r--r--lib/Support/Windows/Program.inc26
-rw-r--r--lib/Support/Windows/Signals.inc2
-rw-r--r--lib/Support/YAMLParser.cpp34
-rw-r--r--lib/Support/YAMLTraits.cpp827
-rw-r--r--lib/Support/raw_ostream.cpp10
-rw-r--r--lib/Support/regcomp.c30
-rw-r--r--lib/Support/system_error.cpp12
59 files changed, 1849 insertions, 677 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index f143e6d..0e3c619 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -19,8 +19,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
-#include <limits.h>
#include <cstring>
+#include <limits.h>
using namespace llvm;
@@ -46,22 +46,27 @@ namespace llvm {
/* Number of bits in the significand. This includes the integer
bit. */
unsigned int precision;
-
- /* True if arithmetic is supported. */
- unsigned int arithmeticOK;
};
- const fltSemantics APFloat::IEEEhalf = { 15, -14, 11, true };
- const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, true };
- const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true };
- const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true };
- const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, true };
- const fltSemantics APFloat::Bogus = { 0, 0, 0, true };
-
- // The PowerPC format consists of two doubles. It does not map cleanly
- // onto the usual format above. For now only storage of constants of
- // this type is supported, no arithmetic.
- const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106, false };
+ const fltSemantics APFloat::IEEEhalf = { 15, -14, 11 };
+ const fltSemantics APFloat::IEEEsingle = { 127, -126, 24 };
+ const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53 };
+ const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113 };
+ const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64 };
+ const fltSemantics APFloat::Bogus = { 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
+ mantissa bits. Note that for exponents near the double minimum,
+ we no longer can represent the full 106 mantissa bits, so those
+ will be treated as denormal numbers.
+
+ FIXME: While this approximation is equivalent to what GCC uses for
+ 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 };
/* A tight upper bound on number of parts required to hold the value
pow(5, power) is
@@ -116,12 +121,6 @@ hexDigitValue(unsigned int c)
return -1U;
}
-static inline void
-assertArithmeticOK(const llvm::fltSemantics &semantics) {
- assert(semantics.arithmeticOK &&
- "Compile-time arithmetic does not support these semantics");
-}
-
/* Return the value of a decimal exponent of the form
[+-]ddddddd.
@@ -612,8 +611,6 @@ APFloat::assign(const APFloat &rhs)
sign = rhs.sign;
category = rhs.category;
exponent = rhs.exponent;
- sign2 = rhs.sign2;
- exponent2 = rhs.exponent2;
if (category == fcNormal || category == fcNaN)
copySignificand(rhs);
}
@@ -700,6 +697,13 @@ APFloat::operator=(const APFloat &rhs)
}
bool
+APFloat::isDenormal() const {
+ return isNormal() && (exponent == semantics->minExponent) &&
+ (APInt::tcExtractBit(significandParts(),
+ semantics->precision - 1) == 0);
+}
+
+bool
APFloat::bitwiseIsEqual(const APFloat &rhs) const {
if (this == &rhs)
return true;
@@ -707,16 +711,10 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
category != rhs.category ||
sign != rhs.sign)
return false;
- if (semantics==(const llvm::fltSemantics*)&PPCDoubleDouble &&
- sign2 != rhs.sign2)
- return false;
if (category==fcZero || category==fcInfinity)
return true;
else if (category==fcNormal && exponent!=rhs.exponent)
return false;
- else if (semantics==(const llvm::fltSemantics*)&PPCDoubleDouble &&
- exponent2!=rhs.exponent2)
- return false;
else {
int i= partCount();
const integerPart* p=significandParts();
@@ -729,9 +727,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
}
}
-APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
- : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
initialize(&ourSemantics);
sign = 0;
zeroSignificand();
@@ -740,24 +736,19 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
normalize(rmNearestTiesToEven, lfExactlyZero);
}
-APFloat::APFloat(const fltSemantics &ourSemantics) : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+APFloat::APFloat(const fltSemantics &ourSemantics) {
initialize(&ourSemantics);
category = fcZero;
sign = false;
}
-APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag)
- : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
// Allocates storage if necessary but does not initialize it.
initialize(&ourSemantics);
}
APFloat::APFloat(const fltSemantics &ourSemantics,
- fltCategory ourCategory, bool negative)
- : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+ fltCategory ourCategory, bool negative) {
initialize(&ourSemantics);
category = ourCategory;
sign = negative;
@@ -767,14 +758,12 @@ APFloat::APFloat(const fltSemantics &ourSemantics,
makeNaN();
}
-APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text)
- : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) {
initialize(&ourSemantics);
convertFromString(text, rmNearestTiesToEven);
}
-APFloat::APFloat(const APFloat &rhs) : exponent2(0), sign2(0) {
+APFloat::APFloat(const APFloat &rhs) {
initialize(rhs.semantics);
assign(rhs);
}
@@ -1561,8 +1550,6 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
{
opStatus fs;
- assertArithmeticOK(*semantics);
-
fs = addOrSubtractSpecials(rhs, subtract);
/* This return code means it was not a simple case. */
@@ -1607,7 +1594,6 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
- assertArithmeticOK(*semantics);
sign ^= rhs.sign;
fs = multiplySpecials(rhs);
@@ -1627,7 +1613,6 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
- assertArithmeticOK(*semantics);
sign ^= rhs.sign;
fs = divideSpecials(rhs);
@@ -1649,7 +1634,6 @@ APFloat::remainder(const APFloat &rhs)
APFloat V = *this;
unsigned int origSign = sign;
- assertArithmeticOK(*semantics);
fs = V.divide(rhs, rmNearestTiesToEven);
if (fs == opDivByZero)
return fs;
@@ -1684,7 +1668,6 @@ APFloat::opStatus
APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
- assertArithmeticOK(*semantics);
fs = modSpecials(rhs);
if (category == fcNormal && rhs.category == fcNormal) {
@@ -1728,8 +1711,6 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
{
opStatus fs;
- assertArithmeticOK(*semantics);
-
/* Post-multiplication sign, before addition. */
sign ^= multiplicand.sign;
@@ -1770,12 +1751,11 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
/* Rounding-mode corrrect round to integral value. */
APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) {
opStatus fs;
- assertArithmeticOK(*semantics);
// If the exponent is large enough, we know that this value is already
// integral, and the arithmetic below would potentially cause it to saturate
// to +/-Inf. Bail out early instead.
- if (exponent+1 >= (int)semanticsPrecision(*semantics))
+ if (category == fcNormal && exponent+1 >= (int)semanticsPrecision(*semantics))
return opOK;
// The algorithm here is quite simple: we add 2^(p-1), where p is the
@@ -1817,7 +1797,6 @@ APFloat::compare(const APFloat &rhs) const
{
cmpResult result;
- assertArithmeticOK(*semantics);
assert(semantics == rhs.semantics);
switch (convolve(category, rhs.category)) {
@@ -1902,8 +1881,6 @@ APFloat::convert(const fltSemantics &toSemantics,
int shift;
const fltSemantics &fromSemantics = *semantics;
- assertArithmeticOK(fromSemantics);
- assertArithmeticOK(toSemantics);
lostFraction = lfExactlyZero;
newPartCount = partCountForBits(toSemantics.precision + 1);
oldPartCount = partCount();
@@ -1988,8 +1965,6 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
const integerPart *src;
unsigned int dstPartsCount, truncatedBits;
- assertArithmeticOK(*semantics);
-
*isExact = false;
/* Handle the three special cases first. */
@@ -2151,7 +2126,6 @@ APFloat::convertFromUnsignedParts(const integerPart *src,
integerPart *dst;
lostFraction lost_fraction;
- assertArithmeticOK(*semantics);
category = fcNormal;
omsb = APInt::tcMSB(src, srcCount) + 1;
dst = significandParts();
@@ -2202,7 +2176,6 @@ APFloat::convertFromSignExtendedInteger(const integerPart *src,
{
opStatus status;
- assertArithmeticOK(*semantics);
if (isSigned &&
APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
integerPart *copy;
@@ -2336,7 +2309,7 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
roundingMode rounding_mode)
{
unsigned int parts, pow5PartCount;
- fltSemantics calcSemantics = { 32767, -32767, 0, true };
+ fltSemantics calcSemantics = { 32767, -32767, 0 };
integerPart pow5Parts[maxPowerOfFiveParts];
bool isNearest;
@@ -2528,7 +2501,6 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
APFloat::opStatus
APFloat::convertFromString(StringRef str, roundingMode rounding_mode)
{
- assertArithmeticOK(*semantics);
assert(!str.empty() && "Invalid string length");
/* Handle a leading minus sign. */
@@ -2580,8 +2552,6 @@ APFloat::convertToHexString(char *dst, unsigned int hexDigits,
{
char *p;
- assertArithmeticOK(*semantics);
-
p = dst;
if (sign)
*dst++ = '-';
@@ -2790,42 +2760,48 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble);
assert(partCount()==2);
- uint64_t myexponent, mysignificand, myexponent2, mysignificand2;
-
- if (category==fcNormal) {
- myexponent = exponent + 1023; //bias
- myexponent2 = exponent2 + 1023;
- mysignificand = significandParts()[0];
- mysignificand2 = significandParts()[1];
- if (myexponent==1 && !(mysignificand & 0x10000000000000LL))
- myexponent = 0; // denormal
- if (myexponent2==1 && !(mysignificand2 & 0x10000000000000LL))
- myexponent2 = 0; // denormal
- } else if (category==fcZero) {
- myexponent = 0;
- mysignificand = 0;
- myexponent2 = 0;
- mysignificand2 = 0;
- } else if (category==fcInfinity) {
- myexponent = 0x7ff;
- myexponent2 = 0;
- mysignificand = 0;
- mysignificand2 = 0;
+ uint64_t words[2];
+ opStatus fs;
+ bool losesInfo;
+
+ // Convert number to double. To avoid spurious underflows, we re-
+ // normalize against the "double" minExponent first, and only *then*
+ // truncate the mantissa. The result of that second conversion
+ // may be inexact, but should never underflow.
+ // 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);
+ fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ APFloat u(extended);
+ fs = u.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK || fs == opInexact);
+ (void)fs;
+ words[0] = *u.convertDoubleAPFloatToAPInt().getRawData();
+
+ // If conversion was exact or resulted in a special case, we're done;
+ // just set the second double to zero. Otherwise, re-convert back to
+ // the extended format and compute the difference. This now should
+ // convert exactly to double.
+ if (u.category == fcNormal && losesInfo) {
+ fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ APFloat v(extended);
+ v.subtract(u, rmNearestTiesToEven);
+ fs = v.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+ words[1] = *v.convertDoubleAPFloatToAPInt().getRawData();
} else {
- assert(category == fcNaN && "Unknown category");
- myexponent = 0x7ff;
- mysignificand = significandParts()[0];
- myexponent2 = exponent2;
- mysignificand2 = significandParts()[1];
+ words[1] = 0;
}
- uint64_t words[2];
- words[0] = ((uint64_t)(sign & 1) << 63) |
- ((myexponent & 0x7ff) << 52) |
- (mysignificand & 0xfffffffffffffLL);
- words[1] = ((uint64_t)(sign2 & 1) << 63) |
- ((myexponent2 & 0x7ff) << 52) |
- (mysignificand2 & 0xfffffffffffffLL);
return APInt(128, words);
}
@@ -3045,47 +3021,23 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
assert(api.getBitWidth()==128);
uint64_t i1 = api.getRawData()[0];
uint64_t i2 = api.getRawData()[1];
- uint64_t myexponent = (i1 >> 52) & 0x7ff;
- uint64_t mysignificand = i1 & 0xfffffffffffffLL;
- uint64_t myexponent2 = (i2 >> 52) & 0x7ff;
- uint64_t mysignificand2 = i2 & 0xfffffffffffffLL;
+ opStatus fs;
+ bool losesInfo;
- initialize(&APFloat::PPCDoubleDouble);
- assert(partCount()==2);
+ // Get the first double and convert to our format.
+ initFromDoubleAPInt(APInt(64, i1));
+ fs = convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
- sign = static_cast<unsigned int>(i1>>63);
- sign2 = static_cast<unsigned int>(i2>>63);
- if (myexponent==0 && mysignificand==0) {
- // exponent, significand meaningless
- // exponent2 and significand2 are required to be 0; we don't check
- category = fcZero;
- } else if (myexponent==0x7ff && mysignificand==0) {
- // exponent, significand meaningless
- // exponent2 and significand2 are required to be 0; we don't check
- category = fcInfinity;
- } else if (myexponent==0x7ff && mysignificand!=0) {
- // exponent meaningless. So is the whole second word, but keep it
- // for determinism.
- category = fcNaN;
- exponent2 = myexponent2;
- significandParts()[0] = mysignificand;
- significandParts()[1] = mysignificand2;
- } else {
- category = fcNormal;
- // Note there is no category2; the second word is treated as if it is
- // fcNormal, although it might be something else considered by itself.
- exponent = myexponent - 1023;
- exponent2 = myexponent2 - 1023;
- significandParts()[0] = mysignificand;
- significandParts()[1] = mysignificand2;
- if (myexponent==0) // denormal
- exponent = -1022;
- else
- significandParts()[0] |= 0x10000000000000LL; // integer bit
- if (myexponent2==0)
- exponent2 = -1022;
- else
- significandParts()[1] |= 0x10000000000000LL; // integer bit
+ // Unless we have a special case, add in second double.
+ if (category == fcNormal) {
+ APFloat v(APInt(64, i2));
+ fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ add(v, rmNearestTiesToEven);
}
}
@@ -3311,15 +3263,15 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
return Val;
}
-APFloat::APFloat(const APInt& api, bool isIEEE) : exponent2(0), sign2(0) {
+APFloat::APFloat(const APInt& api, bool isIEEE) {
initFromAPInt(api, isIEEE);
}
-APFloat::APFloat(float f) : exponent2(0), sign2(0) {
+APFloat::APFloat(float f) {
initFromAPInt(APInt::floatToBits(f));
}
-APFloat::APFloat(double d) : exponent2(0), sign2(0) {
+APFloat::APFloat(double d) {
initFromAPInt(APInt::doubleToBits(d));
}
@@ -3610,11 +3562,6 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
}
bool APFloat::getExactInverse(APFloat *inv) const {
- // We can only guarantee the existence of an exact inverse for IEEE floats.
- if (semantics != &IEEEhalf && semantics != &IEEEsingle &&
- semantics != &IEEEdouble && semantics != &IEEEquad)
- return false;
-
// Special floats and denormals have no exact inverse.
if (category != fcNormal)
return false;
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 38cfaed..61e503b 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -23,9 +23,9 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cmath>
-#include <limits>
-#include <cstring>
#include <cstdlib>
+#include <cstring>
+#include <limits>
using namespace llvm;
/// A utility function for allocating memory, checking for allocation failures,
diff --git a/lib/Support/Allocator.cpp b/lib/Support/Allocator.cpp
index b897830..28f4e64 100644
--- a/lib/Support/Allocator.cpp
+++ b/lib/Support/Allocator.cpp
@@ -13,9 +13,9 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Memory.h"
#include "llvm/Support/Recycler.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Memory.h"
#include <cstring>
namespace llvm {
diff --git a/lib/Support/Atomic.cpp b/lib/Support/Atomic.cpp
index 58497b9..13d16d4 100644
--- a/lib/Support/Atomic.cpp
+++ b/lib/Support/Atomic.cpp
@@ -24,11 +24,15 @@ using namespace llvm;
#undef MemoryFence
#endif
+#if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210)
+#define GNU_ATOMICS
+#endif
+
void sys::MemoryFence() {
#if LLVM_HAS_ATOMICS == 0
return;
#else
-# if defined(__GNUC__)
+# if defined(GNU_ATOMICS)
__sync_synchronize();
# elif defined(_MSC_VER)
MemoryBarrier();
@@ -49,7 +53,7 @@ sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
#elif defined(ANDROID_TARGET_BUILD)
return android_atomic_cmpxchg((int32_t)old_value, (int32_t)new_value,
(volatile int*)ptr);
-#elif defined(__GNUC__)
+#elif defined(GNU_ATOMICS)
return __sync_val_compare_and_swap(ptr, old_value, new_value);
#elif defined(_MSC_VER)
return InterlockedCompareExchange(ptr, new_value, old_value);
@@ -64,7 +68,7 @@ sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) {
return *ptr;
#elif defined(ANDROID_TARGET_BUILD)
return android_atomic_inc((volatile int*)ptr);
-#elif defined(__GNUC__)
+#elif defined(GNU_ATOMICS)
return __sync_add_and_fetch(ptr, 1);
#elif defined(_MSC_VER)
return InterlockedIncrement(ptr);
@@ -79,7 +83,7 @@ sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) {
return *ptr;
#elif defined(ANDROID_TARGET_BUILD)
return android_atomic_dec((volatile int*)ptr);
-#elif defined(__GNUC__)
+#elif defined(GNU_ATOMICS)
return __sync_sub_and_fetch(ptr, 1);
#elif defined(_MSC_VER)
return InterlockedDecrement(ptr);
@@ -94,7 +98,7 @@ sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) {
return *ptr;
#elif defined(ANDROID_TARGET_BUILD)
return android_atomic_add((int32_t)val, (volatile int*)ptr);
-#elif defined(__GNUC__)
+#elif defined(GNU_ATOMICS)
return __sync_add_and_fetch(ptr, val);
#elif defined(_MSC_VER)
return InterlockedExchangeAdd(ptr, val) + val;
diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt
index 83baf60..f294a17 100644
--- a/lib/Support/CMakeLists.txt
+++ b/lib/Support/CMakeLists.txt
@@ -1,9 +1,3 @@
-## FIXME: This only requires RTTI because tblgen uses it. Fix that.
-set(LLVM_REQUIRES_RTTI 1)
-if( MINGW )
- set(LLVM_REQUIRES_EH 1)
-endif()
-
add_llvm_library(LLVMSupport
APFloat.cpp
APInt.cpp
@@ -56,6 +50,7 @@ add_llvm_library(LLVMSupport
Triple.cpp
Twine.cpp
YAMLParser.cpp
+ YAMLTraits.cpp
raw_os_ostream.cpp
raw_ostream.cpp
regcomp.c
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 593315d..53fcf06 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -17,20 +17,20 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Support/Path.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
#include <cerrno>
#include <cstdlib>
using namespace llvm;
@@ -464,7 +464,7 @@ static void ParseCStringVector(std::vector<char *> &OutputVector,
/// an environment variable (whose name is given in ENVVAR).
///
void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
- const char *Overview, bool ReadResponseFiles) {
+ const char *Overview) {
// Check args.
assert(progName && "Program name not specified");
assert(envVar && "Environment variable name missing");
@@ -483,7 +483,7 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
// and hand it off to ParseCommandLineOptions().
ParseCStringVector(newArgv, envValue);
int newArgc = static_cast<int>(newArgv.size());
- ParseCommandLineOptions(newArgc, &newArgv[0], Overview, ReadResponseFiles);
+ ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
// Free all the strdup()ed strings.
for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
@@ -529,7 +529,7 @@ static void ExpandResponseFiles(unsigned argc, const char*const* argv,
}
void cl::ParseCommandLineOptions(int argc, const char * const *argv,
- const char *Overview, bool ReadResponseFiles) {
+ const char *Overview) {
// Process all registered options.
SmallVector<Option*, 4> PositionalOpts;
SmallVector<Option*, 4> SinkOpts;
@@ -541,12 +541,10 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// Expand response files.
std::vector<char*> newArgv;
- if (ReadResponseFiles) {
- newArgv.push_back(strdup(argv[0]));
- ExpandResponseFiles(argc, argv, newArgv);
- argv = &newArgv[0];
- argc = static_cast<int>(newArgv.size());
- }
+ newArgv.push_back(strdup(argv[0]));
+ ExpandResponseFiles(argc, argv, newArgv);
+ argv = &newArgv[0];
+ argc = static_cast<int>(newArgv.size());
// Copy the program name into ProgName, making sure not to overflow it.
std::string ProgName = sys::path::filename(argv[0]);
@@ -839,12 +837,10 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
MoreHelp->clear();
// Free the memory allocated by ExpandResponseFiles.
- if (ReadResponseFiles) {
- // Free all the strdup()ed strings.
- for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
- i != e; ++i)
- free(*i);
- }
+ // Free all the strdup()ed strings.
+ for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
+ i != e; ++i)
+ free(*i);
// If we had an error processing our arguments, don't let the program execute
if (ErrorParsing) exit(1);
diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp
index 720ef36..5c58950 100644
--- a/lib/Support/ConstantRange.cpp
+++ b/lib/Support/ConstantRange.cpp
@@ -21,7 +21,7 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/InstrTypes.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp
index e175056..182c362 100644
--- a/lib/Support/CrashRecoveryContext.cpp
+++ b/lib/Support/CrashRecoveryContext.cpp
@@ -10,11 +10,11 @@
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/ThreadLocal.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <setjmp.h>
#include <cstdio>
+#include <setjmp.h>
using namespace llvm;
namespace {
diff --git a/lib/Support/DAGDeltaAlgorithm.cpp b/lib/Support/DAGDeltaAlgorithm.cpp
index 1e89c6a..34e82cf 100644
--- a/lib/Support/DAGDeltaAlgorithm.cpp
+++ b/lib/Support/DAGDeltaAlgorithm.cpp
@@ -122,7 +122,7 @@ private:
DDA.UpdatedSearchState(Changes, Sets, Required);
}
- /// ExecuteOneTest - Execute a single test predicate on the change set \arg S.
+ /// ExecuteOneTest - Execute a single test predicate on the change set \p S.
bool ExecuteOneTest(const changeset_ty &S) {
// Check dependencies invariant.
DEBUG({
@@ -143,8 +143,8 @@ public:
changeset_ty Run();
- /// GetTestResult - Get the test result for the active set \arg Changes with
- /// \arg Required changes from the cache, executing the test if necessary.
+ /// GetTestResult - Get the test result for the active set \p Changes with
+ /// \p Required changes from the cache, executing the test if necessary.
///
/// \param Changes - The set of active changes being minimized, which should
/// have their pred closure included in the test.
@@ -163,11 +163,11 @@ class DeltaActiveSetHelper : public DeltaAlgorithm {
protected:
/// UpdatedSearchState - Callback used when the search state changes.
virtual void UpdatedSearchState(const changeset_ty &Changes,
- const changesetlist_ty &Sets) {
+ const changesetlist_ty &Sets) LLVM_OVERRIDE {
DDAI.UpdatedSearchState(Changes, Sets, Required);
}
- virtual bool ExecuteOneTest(const changeset_ty &S) {
+ virtual bool ExecuteOneTest(const changeset_ty &S) LLVM_OVERRIDE {
return DDAI.GetTestResult(S, Required);
}
diff --git a/lib/Support/DataStream.cpp b/lib/Support/DataStream.cpp
index 94d14a5..0a02281 100644
--- a/lib/Support/DataStream.cpp
+++ b/lib/Support/DataStream.cpp
@@ -15,13 +15,13 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "Data-stream"
-#include "llvm/ADT/Statistic.h"
#include "llvm/Support/DataStream.h"
+#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/system_error.h"
-#include <string>
#include <cerrno>
#include <cstdio>
+#include <string>
#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <unistd.h>
#else
@@ -58,7 +58,7 @@ public:
virtual ~DataFileStreamer() {
close(Fd);
}
- virtual size_t GetBytes(unsigned char *buf, size_t len) {
+ virtual size_t GetBytes(unsigned char *buf, size_t len) LLVM_OVERRIDE {
NumStreamFetches++;
return read(Fd, buf, len);
}
diff --git a/lib/Support/Debug.cpp b/lib/Support/Debug.cpp
index c8e8900..0c0f15e 100644
--- a/lib/Support/Debug.cpp
+++ b/lib/Support/Debug.cpp
@@ -23,10 +23,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/circular_raw_ostream.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/circular_raw_ostream.h"
using namespace llvm;
diff --git a/lib/Support/DeltaAlgorithm.cpp b/lib/Support/DeltaAlgorithm.cpp
index 9e52874..a1e3311 100644
--- a/lib/Support/DeltaAlgorithm.cpp
+++ b/lib/Support/DeltaAlgorithm.cpp
@@ -27,13 +27,15 @@ bool DeltaAlgorithm::GetTestResult(const changeset_ty &Changes) {
void DeltaAlgorithm::Split(const changeset_ty &S, changesetlist_ty &Res) {
// FIXME: Allow clients to provide heuristics for improved splitting.
+ // Get the iterator to the middle.
+ unsigned N = S.size() / 2;
+ changeset_ty::iterator middle(S.begin());
+ std::advance(middle, N);
+
+ // Create each vector using the middle as the split.
+ changeset_ty LHS(S.begin(), middle);
+ changeset_ty RHS(middle, S.end());
- // FIXME: This is really slow.
- changeset_ty LHS, RHS;
- unsigned idx = 0, N = S.size() / 2;
- for (changeset_ty::const_iterator it = S.begin(),
- ie = S.end(); it != ie; ++it, ++idx)
- ((idx < N) ? LHS : RHS).insert(*it);
if (!LHS.empty())
Res.push_back(LHS);
if (!RHS.empty())
diff --git a/lib/Support/Disassembler.cpp b/lib/Support/Disassembler.cpp
index c6d73bc..b3244fa 100644
--- a/lib/Support/Disassembler.cpp
+++ b/lib/Support/Disassembler.cpp
@@ -12,13 +12,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Config/config.h"
#include "llvm/Support/Disassembler.h"
-
+#include "llvm/Config/config.h"
#include <cassert>
#include <iomanip>
-#include <string>
#include <sstream>
+#include <string>
#if USE_UDIS86
#include <udis86.h>
diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp
index 5c59a3e..615efb8 100644
--- a/lib/Support/Dwarf.cpp
+++ b/lib/Support/Dwarf.cpp
@@ -80,8 +80,6 @@ const char *llvm::dwarf::TagString(unsigned Tag) {
case DW_TAG_hi_user: return "DW_TAG_hi_user";
case DW_TAG_auto_variable: return "DW_TAG_auto_variable";
case DW_TAG_arg_variable: return "DW_TAG_arg_variable";
- case DW_TAG_return_variable: return "DW_TAG_return_variable";
- case DW_TAG_vector_type: return "DW_TAG_vector_type";
case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type";
case DW_TAG_template_alias: return "DW_TAG_template_alias";
case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
@@ -248,6 +246,14 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) {
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";
+
+ // 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";
}
return 0;
}
@@ -281,6 +287,10 @@ const char *llvm::dwarf::FormEncodingString(unsigned Encoding) {
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";
}
return 0;
}
@@ -445,6 +455,10 @@ const char *llvm::dwarf::OperationEncodingString(unsigned Encoding) {
case DW_OP_stack_value: return "DW_OP_stack_value";
case DW_OP_lo_user: return "DW_OP_lo_user";
case DW_OP_hi_user: return "DW_OP_hi_user";
+
+ // DWARF5 Fission Proposal Op Extensions
+ case DW_OP_GNU_addr_index: return "DW_OP_GNU_addr_index";
+ case DW_OP_GNU_const_index: return "DW_OP_GNU_const_index";
}
return 0;
}
diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp
index 45fec36..d40439a 100644
--- a/lib/Support/DynamicLibrary.cpp
+++ b/lib/Support/DynamicLibrary.cpp
@@ -13,11 +13,11 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/Mutex.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/Mutex.h"
#include <cstdio>
#include <cstring>
diff --git a/lib/Support/Errno.cpp b/lib/Support/Errno.cpp
index dd218f6..730220f 100644
--- a/lib/Support/Errno.cpp
+++ b/lib/Support/Errno.cpp
@@ -13,6 +13,7 @@
#include "llvm/Support/Errno.h"
#include "llvm/Config/config.h" // Get autoconf configuration settings
+#include "llvm/Support/raw_ostream.h"
#if HAVE_STRING_H
#include <string.h>
@@ -39,7 +40,7 @@ std::string StrError(int errnum) {
const int MaxErrStrLen = 2000;
char buffer[MaxErrStrLen];
buffer[0] = '\0';
- char* str = buffer;
+ std::string str;
#ifdef HAVE_STRERROR_R
// strerror_r is thread-safe.
if (errnum)
@@ -49,21 +50,25 @@ std::string StrError(int errnum) {
str = strerror_r(errnum,buffer,MaxErrStrLen-1);
# else
strerror_r(errnum,buffer,MaxErrStrLen-1);
+ str = buffer;
# endif
#elif HAVE_DECL_STRERROR_S // "Windows Secure API"
- if (errnum)
+ if (errnum) {
strerror_s(buffer, MaxErrStrLen - 1, errnum);
+ str = buffer;
+ }
#elif defined(HAVE_STRERROR)
// Copy the thread un-safe result of strerror into
// the buffer as fast as possible to minimize impact
// of collision of strerror in multiple threads.
if (errnum)
- strncpy(buffer,strerror(errnum),MaxErrStrLen-1);
- buffer[MaxErrStrLen-1] = '\0';
+ str = strerror(errnum);
#else
// Strange that this system doesn't even have strerror
// but, oh well, just use a generic message
- sprintf(buffer, "Error #%d", errnum);
+ raw_string_ostream stream(str);
+ stream << "Error #" << errnum;
+ stream.flush();
#endif
return str;
}
diff --git a/lib/Support/ErrorHandling.cpp b/lib/Support/ErrorHandling.cpp
index e6cc57d..d4382e5 100644
--- a/lib/Support/ErrorHandling.cpp
+++ b/lib/Support/ErrorHandling.cpp
@@ -12,14 +12,14 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Config/config.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/Threading.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Config/config.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdlib>
diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp
index 7dc9587..cd430f2 100644
--- a/lib/Support/FileOutputBuffer.cpp
+++ b/lib/Support/FileOutputBuffer.cpp
@@ -12,37 +12,28 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/FileOutputBuffer.h"
-
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
+using llvm::sys::fs::mapped_file_region;
namespace llvm {
-
-
-FileOutputBuffer::FileOutputBuffer(uint8_t *Start, uint8_t *End,
- StringRef Path, StringRef TmpPath)
- : BufferStart(Start), BufferEnd(End) {
- FinalPath.assign(Path);
- TempPath.assign(TmpPath);
+FileOutputBuffer::FileOutputBuffer(mapped_file_region * R,
+ StringRef Path, StringRef TmpPath)
+ : Region(R)
+ , FinalPath(Path)
+ , TempPath(TmpPath) {
}
-
FileOutputBuffer::~FileOutputBuffer() {
- // If not already commited, delete buffer and remove temp file.
- if ( BufferStart != NULL ) {
- sys::fs::unmap_file_pages((void*)BufferStart, getBufferSize());
- bool Existed;
- sys::fs::remove(Twine(TempPath), Existed);
- }
+ bool Existed;
+ sys::fs::remove(Twine(TempPath), Existed);
}
-
-error_code FileOutputBuffer::create(StringRef FilePath,
- size_t Size,
+error_code FileOutputBuffer::create(StringRef FilePath,
+ size_t Size,
OwningPtr<FileOutputBuffer> &Result,
unsigned Flags) {
// If file already exists, it must be a regular file (to be mappable).
@@ -70,34 +61,27 @@ error_code FileOutputBuffer::create(StringRef FilePath,
EC = sys::fs::remove(FilePath, Existed);
if (EC)
return EC;
-
+
// Create new file in same directory but with random name.
SmallString<128> TempFilePath;
int FD;
- EC = sys::fs::unique_file(Twine(FilePath) + ".tmp%%%%%%%",
- FD, TempFilePath, false, 0644);
+ EC = sys::fs::unique_file(Twine(FilePath) + ".tmp%%%%%%%",
+ FD, TempFilePath, false, 0644);
if (EC)
return EC;
-
- // The unique_file() interface leaks lower layers and returns a file
- // descriptor. There is no way to directly close it, so use this hack
- // to hand it off to raw_fd_ostream to close for us.
- {
- raw_fd_ostream Dummy(FD, /*shouldClose=*/true);
- }
-
- // Resize file to requested initial size
- EC = sys::fs::resize_file(Twine(TempFilePath), Size);
+
+ OwningPtr<mapped_file_region> MappedFile(
+ new mapped_file_region(FD, mapped_file_region::readwrite, Size, 0, EC));
if (EC)
return EC;
-
+
// If requested, make the output file executable.
if ( Flags & F_executable ) {
sys::fs::file_status Stat2;
EC = sys::fs::status(Twine(TempFilePath), Stat2);
if (EC)
return EC;
-
+
sys::fs::perms new_perms = Stat2.permissions();
if ( new_perms & sys::fs::owner_read )
new_perms |= sys::fs::owner_exe;
@@ -111,38 +95,25 @@ error_code FileOutputBuffer::create(StringRef FilePath,
return EC;
}
- // Memory map new file.
- void *Base;
- EC = sys::fs::map_file_pages(Twine(TempFilePath), 0, Size, true, Base);
- if (EC)
- return EC;
-
- // Create FileOutputBuffer object to own mapped range.
- uint8_t *Start = reinterpret_cast<uint8_t*>(Base);
- Result.reset(new FileOutputBuffer(Start, Start+Size, FilePath, TempFilePath));
-
- return error_code::success();
-}
+ Result.reset(new FileOutputBuffer(MappedFile.get(), FilePath, TempFilePath));
+ if (Result)
+ MappedFile.take();
+ return error_code::success();
+}
error_code FileOutputBuffer::commit(int64_t NewSmallerSize) {
// Unmap buffer, letting OS flush dirty pages to file on disk.
- void *Start = reinterpret_cast<void*>(BufferStart);
- error_code EC = sys::fs::unmap_file_pages(Start, getBufferSize());
- if (EC)
- return EC;
-
+ Region.reset(0);
+
// If requested, resize file as part of commit.
if ( NewSmallerSize != -1 ) {
- EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize);
+ error_code EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize);
if (EC)
return EC;
}
-
+
// Rename file to final name.
return sys::fs::rename(Twine(TempPath), Twine(FinalPath));
}
-
-
} // namespace
-
diff --git a/lib/Support/FileUtilities.cpp b/lib/Support/FileUtilities.cpp
index f9e9cf0..fc8a2f3 100644
--- a/lib/Support/FileUtilities.cpp
+++ b/lib/Support/FileUtilities.cpp
@@ -13,15 +13,15 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/FileUtilities.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallString.h"
+#include <cctype>
#include <cstdlib>
#include <cstring>
-#include <cctype>
using namespace llvm;
static bool isSignedChar(char C) {
diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp
index 4d489a8..36e33b5 100644
--- a/lib/Support/FoldingSet.cpp
+++ b/lib/Support/FoldingSet.cpp
@@ -8,9 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file implements a hash set that can be used to remove duplication of
-// nodes in a graph. This code was originally created by Chris Lattner for use
-// with SelectionDAGCSEMap, but was isolated to provide use across the llvm code
-// set.
+// nodes in a graph.
//
//===----------------------------------------------------------------------===//
@@ -18,8 +16,8 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <cstring>
using namespace llvm;
@@ -150,7 +148,7 @@ unsigned FoldingSetNodeID::ComputeHash() const {
/// operator== - Used to compare two nodes to each other.
///
-bool FoldingSetNodeID::operator==(const FoldingSetNodeID &RHS)const{
+bool FoldingSetNodeID::operator==(const FoldingSetNodeID &RHS) const {
return *this == FoldingSetNodeIDRef(RHS.Bits.data(), RHS.Bits.size());
}
@@ -162,7 +160,7 @@ bool FoldingSetNodeID::operator==(FoldingSetNodeIDRef RHS) const {
/// Used to compare the "ordering" of two nodes as defined by the
/// profiled bits and their ordering defined by memcmp().
-bool FoldingSetNodeID::operator<(const FoldingSetNodeID &RHS)const{
+bool FoldingSetNodeID::operator<(const FoldingSetNodeID &RHS) const {
return *this < FoldingSetNodeIDRef(RHS.Bits.data(), RHS.Bits.size());
}
diff --git a/lib/Support/GraphWriter.cpp b/lib/Support/GraphWriter.cpp
index f6aaf83..669c238 100644
--- a/lib/Support/GraphWriter.cpp
+++ b/lib/Support/GraphWriter.cpp
@@ -11,11 +11,11 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/GraphWriter.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
-#include "llvm/Config/config.h"
using namespace llvm;
static cl::opt<bool> ViewBackground("view-background", cl::Hidden,
diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp
index 9a2c39d..5ad5308 100644
--- a/lib/Support/Host.cpp
+++ b/lib/Support/Host.cpp
@@ -11,14 +11,14 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Support/Host.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Config/config.h"
#include "llvm/Support/DataStream.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Config/config.h"
#include <string.h>
// Include the platform-specific parts of this class.
@@ -234,6 +234,8 @@ std::string sys::getHostCPUName() {
case 37: // Intel Core i7, laptop version.
case 44: // Intel Core i7 processor and Intel Xeon processor. All
// processors are manufactured using the 32 nm process.
+ case 46: // Nehalem EX
+ case 47: // Westmere EX
return "corei7";
// SandyBridge:
@@ -303,6 +305,7 @@ std::string sys::getHostCPUName() {
case 8: return "k6-2";
case 9:
case 13: return "k6-3";
+ case 10: return "geode";
default: return "pentium";
}
case 6:
@@ -500,6 +503,7 @@ std::string sys::getHostCPUName() {
.Case("0xb76", "arm1176jz-s")
.Case("0xc08", "cortex-a8")
.Case("0xc09", "cortex-a9")
+ .Case("0xc0f", "cortex-a15")
.Case("0xc20", "cortex-m0")
.Case("0xc23", "cortex-m3")
.Case("0xc24", "cortex-m4")
@@ -513,6 +517,64 @@ std::string sys::getHostCPUName() {
}
#endif
+#if defined(__linux__) && defined(__arm__)
+bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
+ std::string Err;
+ DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
+ if (!DS) {
+ DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
+ return false;
+ }
+
+ // Read 1024 bytes from /proc/cpuinfo, which should contain the Features line
+ // in all cases.
+ char buffer[1024];
+ size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
+ delete DS;
+
+ StringRef Str(buffer, CPUInfoSize);
+
+ SmallVector<StringRef, 32> Lines;
+ Str.split(Lines, "\n");
+
+ // Look for the CPU implementer line.
+ StringRef Implementer;
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("CPU implementer"))
+ Implementer = Lines[I].substr(15).ltrim("\t :");
+
+ if (Implementer == "0x41") { // ARM Ltd.
+ SmallVector<StringRef, 32> CPUFeatures;
+
+ // Look for the CPU features.
+ for (unsigned I = 0, E = Lines.size(); I != E; ++I)
+ if (Lines[I].startswith("Features")) {
+ Lines[I].split(CPUFeatures, " ");
+ break;
+ }
+
+ for (unsigned I = 0, E = CPUFeatures.size(); I != E; ++I) {
+ StringRef LLVMFeatureStr = StringSwitch<StringRef>(CPUFeatures[I])
+ .Case("half", "fp16")
+ .Case("neon", "neon")
+ .Case("vfpv3", "vfp3")
+ .Case("vfpv3d16", "d16")
+ .Case("vfpv4", "vfp4")
+ .Case("idiva", "hwdiv-arm")
+ .Case("idivt", "hwdiv")
+ .Default("");
+
+ if (LLVMFeatureStr != "")
+ Features.GetOrCreateValue(LLVMFeatureStr).setValue(true);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+#else
bool sys::getHostCPUFeatures(StringMap<bool> &Features){
return false;
}
+#endif
diff --git a/lib/Support/LocaleWindows.inc b/lib/Support/LocaleWindows.inc
index 6827ac1..28e429c 100644
--- a/lib/Support/LocaleWindows.inc
+++ b/lib/Support/LocaleWindows.inc
@@ -12,4 +12,4 @@ bool isPrint(int c) {
}
}
-} \ No newline at end of file
+}
diff --git a/lib/Support/LocaleXlocale.inc b/lib/Support/LocaleXlocale.inc
index f595e7c..389fe3d 100644
--- a/lib/Support/LocaleXlocale.inc
+++ b/lib/Support/LocaleXlocale.inc
@@ -1,5 +1,5 @@
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ManagedStatic.h"
#include <cassert>
#include <xlocale.h>
diff --git a/lib/Support/LockFileManager.cpp b/lib/Support/LockFileManager.cpp
index 59bfcfc..075d8a5 100644
--- a/lib/Support/LockFileManager.cpp
+++ b/lib/Support/LockFileManager.cpp
@@ -10,8 +10,8 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <fstream>
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/types.h>
#if LLVM_ON_WIN32
#include <windows.h>
#endif
diff --git a/lib/Support/Makefile b/lib/Support/Makefile
index d68e500..4a2185d 100644
--- a/lib/Support/Makefile
+++ b/lib/Support/Makefile
@@ -11,9 +11,6 @@ LEVEL = ../..
LIBRARYNAME = LLVMSupport
BUILD_ARCHIVE = 1
-## FIXME: This only requires RTTI because tblgen uses it. Fix that.
-REQUIRES_RTTI = 1
-
EXTRA_DIST = Unix Win32 README.txt
include $(LEVEL)/Makefile.common
diff --git a/lib/Support/Memory.cpp b/lib/Support/Memory.cpp
index 8617365..f9a4903 100644
--- a/lib/Support/Memory.cpp
+++ b/lib/Support/Memory.cpp
@@ -13,16 +13,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Memory.h"
-#include "llvm/Support/Valgrind.h"
#include "llvm/Config/config.h"
-
-#if defined(__mips__)
-#include <sys/cachectl.h>
-#endif
-
-namespace llvm {
-using namespace sys;
-}
+#include "llvm/Support/Valgrind.h"
// Include the platform-specific parts of this class.
#ifdef LLVM_ON_UNIX
@@ -31,55 +23,3 @@ using namespace sys;
#ifdef LLVM_ON_WIN32
#include "Windows/Memory.inc"
#endif
-
-extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
-
-/// InvalidateInstructionCache - Before the JIT can run a block of code
-/// that has been emitted it must invalidate the instruction cache on some
-/// platforms.
-void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr,
- size_t Len) {
-
-// icache invalidation for PPC and ARM.
-#if defined(__APPLE__)
-
-# if (defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__)
- sys_icache_invalidate(const_cast<void *>(Addr), Len);
-# endif
-
-#else
-
-# if (defined(__POWERPC__) || defined (__ppc__) || \
- defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
- const size_t LineSize = 32;
-
- const intptr_t Mask = ~(LineSize - 1);
- const intptr_t StartLine = ((intptr_t) Addr) & Mask;
- const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
-
- for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
- asm volatile("dcbf 0, %0" : : "r"(Line));
- asm volatile("sync");
-
- for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
- asm volatile("icbi 0, %0" : : "r"(Line));
- asm volatile("isync");
-# elif defined(__arm__) && defined(__GNUC__)
- // FIXME: Can we safely always call this for __GNUC__ everywhere?
- const char *Start = static_cast<const char *>(Addr);
- const char *End = Start + Len;
- __clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
-# elif defined(__mips__) && defined(ANDROID)
- // NOTE: The declaration of "cacheflush" in bionic:
- // extern int cacheflush(long start, long end, long flags);
- cacheflush((long)Addr, (long)(Addr+Len), BCACHE);
-# elif defined(__mips__)
- const char *Start = static_cast<const char *>(Addr);
- cacheflush(const_cast<char *>(Start), Len, BCACHE);
-# endif
-
-#endif // end apple
-
- ValgrindDiscardTranslations(Addr, Len);
-}
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index 992f03c..65b4332 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -15,24 +15,27 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/system_error.h"
#include <cassert>
+#include <cerrno>
#include <cstdio>
#include <cstring>
-#include <cerrno>
#include <new>
-#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/types.h>
#if !defined(_MSC_VER) && !defined(__MINGW32__)
#include <unistd.h>
#else
#include <io.h>
+#ifndef S_ISFIFO
+#define S_ISFIFO(x) (0)
+#endif
#endif
#include <fcntl.h>
using namespace llvm;
@@ -81,12 +84,12 @@ public:
init(InputData.begin(), InputData.end(), RequiresNullTerminator);
}
- virtual const char *getBufferIdentifier() const {
+ virtual const char *getBufferIdentifier() const LLVM_OVERRIDE {
// The name is stored after the class itself.
return reinterpret_cast<const char*>(this + 1);
}
-
- virtual BufferKind getBufferKind() const {
+
+ virtual BufferKind getBufferKind() const LLVM_OVERRIDE {
return MemoryBuffer_Malloc;
}
};
@@ -184,7 +187,7 @@ public:
: MemoryBufferMem(Buffer, RequiresNullTerminator) { }
~MemoryBufferMMapFile() {
- static int PageSize = sys::Process::GetPageSize();
+ static int PageSize = sys::process::get_self()->page_size();
uintptr_t Start = reinterpret_cast<uintptr_t>(getBufferStart());
size_t Size = getBufferSize();
@@ -194,13 +197,34 @@ public:
sys::Path::UnMapFilePages(reinterpret_cast<const char*>(RealStart),
RealSize);
}
-
- virtual BufferKind getBufferKind() const {
+
+ virtual BufferKind getBufferKind() const LLVM_OVERRIDE {
return MemoryBuffer_MMap;
}
};
}
+static error_code getMemoryBufferForStream(int FD,
+ StringRef BufferName,
+ OwningPtr<MemoryBuffer> &result) {
+ const ssize_t ChunkSize = 4096*4;
+ SmallString<ChunkSize> Buffer;
+ ssize_t ReadBytes;
+ // Read into Buffer until we hit EOF.
+ do {
+ Buffer.reserve(Buffer.size() + ChunkSize);
+ ReadBytes = read(FD, Buffer.end(), ChunkSize);
+ if (ReadBytes == -1) {
+ if (errno == EINTR) continue;
+ return error_code(errno, posix_category());
+ }
+ Buffer.set_size(Buffer.size() + ReadBytes);
+ } while (ReadBytes != 0);
+
+ result.reset(MemoryBuffer::getMemBufferCopy(Buffer, BufferName));
+ return error_code::success();
+}
+
error_code MemoryBuffer::getFile(StringRef Filename,
OwningPtr<MemoryBuffer> &result,
int64_t FileSize,
@@ -285,7 +309,7 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
uint64_t FileSize, uint64_t MapSize,
int64_t Offset,
bool RequiresNullTerminator) {
- static int PageSize = sys::Process::GetPageSize();
+ static int PageSize = sys::process::get_self()->page_size();
// Default is to map the full file.
if (MapSize == uint64_t(-1)) {
@@ -297,6 +321,13 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
if (fstat(FD, &FileInfo) == -1) {
return error_code(errno, posix_category());
}
+
+ // If this is a named pipe, we can't trust the size. Create the memory
+ // buffer by copying off the stream.
+ if (S_ISFIFO(FileInfo.st_mode)) {
+ return getMemoryBufferForStream(FD, Filename, result);
+ }
+
FileSize = FileInfo.st_size;
}
MapSize = FileSize;
@@ -370,20 +401,5 @@ error_code MemoryBuffer::getSTDIN(OwningPtr<MemoryBuffer> &result) {
// fallback if it fails.
sys::Program::ChangeStdinToBinary();
- const ssize_t ChunkSize = 4096*4;
- SmallString<ChunkSize> Buffer;
- ssize_t ReadBytes;
- // Read into Buffer until we hit EOF.
- do {
- Buffer.reserve(Buffer.size() + ChunkSize);
- ReadBytes = read(0, Buffer.end(), ChunkSize);
- if (ReadBytes == -1) {
- if (errno == EINTR) continue;
- return error_code(errno, posix_category());
- }
- Buffer.set_size(Buffer.size() + ReadBytes);
- } while (ReadBytes != 0);
-
- result.reset(getMemBufferCopy(Buffer, "<stdin>"));
- return error_code::success();
+ return getMemoryBufferForStream(0, "<stdin>", result);
}
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index db4a56b..d070375 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -12,10 +12,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Path.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Config/config.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/FileSystem.h"
#include <cassert>
#include <cstring>
#include <ostream>
diff --git a/lib/Support/PathV2.cpp b/lib/Support/PathV2.cpp
index 46571c0..98d7382 100644
--- a/lib/Support/PathV2.cpp
+++ b/lib/Support/PathV2.cpp
@@ -12,9 +12,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/PathV2.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FileSystem.h"
#include <cctype>
#include <cstdio>
#include <cstring>
diff --git a/lib/Support/PluginLoader.cpp b/lib/Support/PluginLoader.cpp
index 2924cfa..358137f 100644
--- a/lib/Support/PluginLoader.cpp
+++ b/lib/Support/PluginLoader.cpp
@@ -12,11 +12,11 @@
//===----------------------------------------------------------------------===//
#define DONT_GET_PLUGIN_LOADER_OPTION
-#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
+#include "llvm/Support/raw_ostream.h"
#include <vector>
using namespace llvm;
diff --git a/lib/Support/PrettyStackTrace.cpp b/lib/Support/PrettyStackTrace.cpp
index ef33073..21d56ad 100644
--- a/lib/Support/PrettyStackTrace.cpp
+++ b/lib/Support/PrettyStackTrace.cpp
@@ -12,12 +12,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Config/config.h" // Get autoconf configuration settings
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Config/config.h" // Get autoconf configuration settings
#include "llvm/Support/Signals.h"
#include "llvm/Support/ThreadLocal.h"
-#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
#ifdef HAVE_CRASHREPORTERCLIENT_H
#include <CrashReporterClient.h>
diff --git a/lib/Support/Process.cpp b/lib/Support/Process.cpp
index 88ca7c3..2c0d37b 100644
--- a/lib/Support/Process.cpp
+++ b/lib/Support/Process.cpp
@@ -11,10 +11,11 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Process.h"
#include "llvm/Config/config.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Process.h"
-namespace llvm {
+using namespace llvm;
using namespace sys;
//===----------------------------------------------------------------------===//
@@ -22,8 +23,63 @@ using namespace sys;
//=== independent code.
//===----------------------------------------------------------------------===//
+// Empty virtual destructor to anchor the vtable for the process class.
+process::~process() {}
+
+self_process *process::get_self() {
+ // Use a function local static for thread safe initialization and allocate it
+ // as a raw pointer to ensure it is never destroyed.
+ static self_process *SP = new self_process();
+
+ return SP;
}
+#if defined(_MSC_VER)
+// Visual Studio complains that the self_process destructor never exits. This
+// doesn't make much sense, as that's the whole point of calling abort... Just
+// silence this warning.
+#pragma warning(push)
+#pragma warning(disable:4722)
+#endif
+
+// The destructor for the self_process subclass must never actually be
+// executed. There should be at most one instance of this class, and that
+// instance should live until the process terminates to avoid the potential for
+// racy accesses during shutdown.
+self_process::~self_process() {
+ llvm_unreachable("This destructor must never be executed!");
+}
+
+/// \brief A helper function to compute the elapsed wall-time since the program
+/// started.
+///
+/// Note that this routine actually computes the elapsed wall time since the
+/// first time it was called. However, we arrange to have it called during the
+/// startup of the process to get approximately correct results.
+static TimeValue getElapsedWallTime() {
+ static TimeValue &StartTime = *new TimeValue(TimeValue::now());
+ return TimeValue::now() - StartTime;
+}
+
+/// \brief A special global variable to ensure we call \c getElapsedWallTime
+/// during global initialization of the program.
+///
+/// Note that this variable is never referenced elsewhere. Doing so could
+/// create race conditions during program startup or shutdown.
+static volatile TimeValue DummyTimeValue = getElapsedWallTime();
+
+// Implement this routine by using the static helpers above. They're already
+// portable.
+TimeValue self_process::get_wall_time() const {
+ return getElapsedWallTime();
+}
+
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+
// Include the platform-specific parts of this class.
#ifdef LLVM_ON_UNIX
#include "Unix/Process.inc"
diff --git a/lib/Support/Regex.cpp b/lib/Support/Regex.cpp
index d293da0..efc8b90 100644
--- a/lib/Support/Regex.cpp
+++ b/lib/Support/Regex.cpp
@@ -12,10 +12,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Regex.h"
+#include "regex_impl.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/SmallVector.h"
-#include "regex_impl.h"
#include <string>
using namespace llvm;
@@ -27,7 +27,9 @@ Regex::Regex(StringRef regex, unsigned Flags) {
flags |= REG_ICASE;
if (Flags & Newline)
flags |= REG_NEWLINE;
- error = llvm_regcomp(preg, regex.data(), flags|REG_EXTENDED|REG_PEND);
+ if (!(Flags & BasicRegex))
+ flags |= REG_EXTENDED;
+ error = llvm_regcomp(preg, regex.data(), flags|REG_PEND);
}
Regex::~Regex() {
diff --git a/lib/Support/SourceMgr.cpp b/lib/Support/SourceMgr.cpp
index e4e01be..6540319 100644
--- a/lib/Support/SourceMgr.cpp
+++ b/lib/Support/SourceMgr.cpp
@@ -13,10 +13,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
using namespace llvm;
@@ -304,7 +304,7 @@ void SMDiagnostic::print(const char *ProgName, raw_ostream &S,
for (unsigned r = 0, e = Ranges.size(); r != e; ++r) {
std::pair<unsigned, unsigned> R = Ranges[r];
for (unsigned i = R.first,
- e = std::min(R.second, (unsigned)LineContents.size())+1; i != e; ++i)
+ e = std::min(R.second, (unsigned)LineContents.size()); i != e; ++i)
CaretLine[i] = '~';
}
diff --git a/lib/Support/Statistic.cpp b/lib/Support/Statistic.cpp
index d8a6ad3..3a65221 100644
--- a/lib/Support/Statistic.cpp
+++ b/lib/Support/Statistic.cpp
@@ -22,13 +22,13 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Mutex.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstring>
using namespace llvm;
diff --git a/lib/Support/StreamableMemoryObject.cpp b/lib/Support/StreamableMemoryObject.cpp
index fe3752a..59e27a2 100644
--- a/lib/Support/StreamableMemoryObject.cpp
+++ b/lib/Support/StreamableMemoryObject.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/StreamableMemoryObject.h"
+#include "llvm/Support/Compiler.h"
#include <cassert>
#include <cstring>
@@ -23,18 +24,23 @@ public:
assert(LastChar >= FirstChar && "Invalid start/end range");
}
- virtual uint64_t getBase() const { return 0; }
- virtual uint64_t getExtent() const { return LastChar - FirstChar; }
- virtual int readByte(uint64_t address, uint8_t* ptr) const;
+ virtual uint64_t getBase() const LLVM_OVERRIDE { return 0; }
+ virtual uint64_t getExtent() const LLVM_OVERRIDE {
+ return LastChar - FirstChar;
+ }
+ virtual int readByte(uint64_t address, uint8_t* ptr) const LLVM_OVERRIDE;
virtual int readBytes(uint64_t address,
uint64_t size,
uint8_t* buf,
- uint64_t* copied) const;
- virtual const uint8_t *getPointer(uint64_t address, uint64_t size) const;
- virtual bool isValidAddress(uint64_t address) const {
+ uint64_t* copied) const LLVM_OVERRIDE;
+ virtual const uint8_t *getPointer(uint64_t address,
+ uint64_t size) const LLVM_OVERRIDE;
+ virtual bool isValidAddress(uint64_t address) const LLVM_OVERRIDE {
return validAddress(address);
}
- virtual bool isObjectEnd(uint64_t address) const {return objectEnd(address);}
+ virtual bool isObjectEnd(uint64_t address) const LLVM_OVERRIDE {
+ return objectEnd(address);
+ }
private:
const uint8_t* const FirstChar;
@@ -49,8 +55,8 @@ private:
return static_cast<ptrdiff_t>(address) == LastChar - FirstChar;
}
- RawMemoryObject(const RawMemoryObject&); // DO NOT IMPLEMENT
- void operator=(const RawMemoryObject&); // DO NOT IMPLEMENT
+ RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION;
+ void operator=(const RawMemoryObject&) LLVM_DELETED_FUNCTION;
};
int RawMemoryObject::readByte(uint64_t address, uint8_t* ptr) const {
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
index 8aab4b2..d7a0bfa 100644
--- a/lib/Support/StringRef.cpp
+++ b/lib/Support/StringRef.cpp
@@ -9,10 +9,9 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/edit_distance.h"
-
#include <bitset>
using namespace llvm;
@@ -350,8 +349,8 @@ bool llvm::getAsUnsignedInteger(StringRef Str, unsigned Radix,
unsigned long long PrevResult = Result;
Result = Result*Radix+CharVal;
- // Check for overflow.
- if (Result < PrevResult)
+ // Check for overflow by shifting back and seeing if bits were lost.
+ if (Result/Radix < PrevResult)
return true;
Str = Str.substr(1);
diff --git a/lib/Support/Threading.cpp b/lib/Support/Threading.cpp
index 7483225..13fba2e 100644
--- a/lib/Support/Threading.cpp
+++ b/lib/Support/Threading.cpp
@@ -12,9 +12,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Threading.h"
+#include "llvm/Config/config.h"
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Mutex.h"
-#include "llvm/Config/config.h"
#include <cassert>
using namespace llvm;
diff --git a/lib/Support/Timer.cpp b/lib/Support/Timer.cpp
index 598e8ad..896d869 100644
--- a/lib/Support/Timer.cpp
+++ b/lib/Support/Timer.cpp
@@ -12,15 +12,15 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Timer.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Process.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
// CreateInfoOutputFile - Return a file stream to print our output on.
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index d1dc7c8..eefb96b 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -8,9 +8,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include <cstring>
using namespace llvm;
@@ -20,7 +20,6 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case UnknownArch: return "unknown";
case arm: return "arm";
- case cellspu: return "cellspu";
case hexagon: return "hexagon";
case mips: return "mips";
case mipsel: return "mipsel";
@@ -42,6 +41,8 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case nvptx64: return "nvptx64";
case le32: return "le32";
case amdil: return "amdil";
+ case spir: return "spir";
+ case spir64: return "spir64";
}
llvm_unreachable("Invalid ArchType!");
@@ -55,8 +56,6 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case arm:
case thumb: return "arm";
- case cellspu: return "spu";
-
case ppc64:
case ppc: return "ppc";
@@ -83,6 +82,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case nvptx64: return "nvptx";
case le32: return "le32";
case amdil: return "amdil";
+ case spir: return "spir";
+ case spir64: return "spir";
}
}
@@ -96,6 +97,7 @@ const char *Triple::getVendorTypeName(VendorType Kind) {
case BGP: return "bgp";
case BGQ: return "bgq";
case Freescale: return "fsl";
+ case IBM: return "ibm";
}
llvm_unreachable("Invalid VendorType!");
@@ -123,9 +125,10 @@ const char *Triple::getOSTypeName(OSType Kind) {
case Haiku: return "haiku";
case Minix: return "minix";
case RTEMS: return "rtems";
- case NativeClient: return "nacl";
+ case NaCl: return "nacl";
case CNK: return "cnk";
case Bitrig: return "bitrig";
+ case AIX: return "aix";
}
llvm_unreachable("Invalid OSType");
@@ -140,6 +143,7 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
case EABI: return "eabi";
case MachO: return "macho";
case Android: return "android";
+ case ELF: return "elf";
}
llvm_unreachable("Invalid EnvironmentType!");
@@ -148,7 +152,6 @@ const char *Triple::getEnvironmentTypeName(EnvironmentType Kind) {
Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
return StringSwitch<Triple::ArchType>(Name)
.Case("arm", arm)
- .Case("cellspu", cellspu)
.Case("mips", mips)
.Case("mipsel", mipsel)
.Case("mips64", mips64)
@@ -171,40 +174,11 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("nvptx64", nvptx64)
.Case("le32", le32)
.Case("amdil", amdil)
+ .Case("spir", spir)
+ .Case("spir64", spir64)
.Default(UnknownArch);
}
-Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
- // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
- // archs which Darwin doesn't use.
-
- // The matching this routine does is fairly pointless, since it is neither the
- // complete architecture list, nor a reasonable subset. The problem is that
- // historically the driver driver accepts this and also ties its -march=
- // handling to the architecture name, so we need to be careful before removing
- // support for it.
-
- // This code must be kept in sync with Clang's Darwin specific argument
- // translation.
-
- return StringSwitch<ArchType>(Str)
- .Cases("ppc", "ppc601", "ppc603", "ppc604", "ppc604e", Triple::ppc)
- .Cases("ppc750", "ppc7400", "ppc7450", "ppc970", Triple::ppc)
- .Case("ppc64", Triple::ppc64)
- .Cases("i386", "i486", "i486SX", "i586", "i686", Triple::x86)
- .Cases("pentium", "pentpro", "pentIIm3", "pentIIm5", "pentium4",
- Triple::x86)
- .Case("x86_64", Triple::x86_64)
- // This is derived from the driver driver.
- .Cases("arm", "armv4t", "armv5", "armv6", Triple::arm)
- .Cases("armv7", "armv7f", "armv7k", "armv7s", "xscale", Triple::arm)
- .Case("r600", Triple::r600)
- .Case("nvptx", Triple::nvptx)
- .Case("nvptx64", Triple::nvptx64)
- .Case("amdil", Triple::amdil)
- .Default(Triple::UnknownArch);
-}
-
// Returns architecture name that is understood by the target assembler.
const char *Triple::getArchNameForAssembler() {
if (!isOSDarwin() && getVendor() != Triple::Apple)
@@ -226,6 +200,8 @@ const char *Triple::getArchNameForAssembler() {
.Case("nvptx64", "nvptx64")
.Case("le32", "le32")
.Case("amdil", "amdil")
+ .Case("spir", "spir")
+ .Case("spir64", "spir64")
.Default(NULL);
}
@@ -244,7 +220,6 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.StartsWith("armv", Triple::arm)
.Case("thumb", Triple::thumb)
.StartsWith("thumbv", Triple::thumb)
- .Cases("spu", "cellspu", Triple::cellspu)
.Case("msp430", Triple::msp430)
.Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
.Cases("mipsel", "mipsallegrexel", Triple::mipsel)
@@ -260,6 +235,8 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("nvptx64", Triple::nvptx64)
.Case("le32", Triple::le32)
.Case("amdil", Triple::amdil)
+ .Case("spir", Triple::spir)
+ .Case("spir64", Triple::spir64)
.Default(Triple::UnknownArch);
}
@@ -271,6 +248,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) {
.Case("bgp", Triple::BGP)
.Case("bgq", Triple::BGQ)
.Case("fsl", Triple::Freescale)
+ .Case("ibm", Triple::IBM)
.Default(Triple::UnknownVendor);
}
@@ -294,9 +272,10 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("haiku", Triple::Haiku)
.StartsWith("minix", Triple::Minix)
.StartsWith("rtems", Triple::RTEMS)
- .StartsWith("nacl", Triple::NativeClient)
+ .StartsWith("nacl", Triple::NaCl)
.StartsWith("cnk", Triple::CNK)
.StartsWith("bitrig", Triple::Bitrig)
+ .StartsWith("aix", Triple::AIX)
.Default(Triple::UnknownOS);
}
@@ -308,6 +287,7 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
.StartsWith("gnu", Triple::GNU)
.StartsWith("macho", Triple::MachO)
.StartsWith("android", Triple::Android)
+ .StartsWith("elf", Triple::ELF)
.Default(Triple::UnknownEnvironment);
}
@@ -678,7 +658,6 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::amdil:
case llvm::Triple::arm:
- case llvm::Triple::cellspu:
case llvm::Triple::hexagon:
case llvm::Triple::le32:
case llvm::Triple::mblaze:
@@ -692,6 +671,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::thumb:
case llvm::Triple::x86:
case llvm::Triple::xcore:
+ case llvm::Triple::spir:
return 32;
case llvm::Triple::mips64:
@@ -700,6 +680,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::ppc64:
case llvm::Triple::sparcv9:
case llvm::Triple::x86_64:
+ case llvm::Triple::spir64:
return 64;
}
llvm_unreachable("Invalid architecture value");
@@ -726,8 +707,8 @@ Triple Triple::get32BitArchVariant() const {
break;
case Triple::amdil:
+ case Triple::spir:
case Triple::arm:
- case Triple::cellspu:
case Triple::hexagon:
case Triple::le32:
case Triple::mblaze:
@@ -750,6 +731,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::ppc64: T.setArch(Triple::ppc); break;
case Triple::sparcv9: T.setArch(Triple::sparc); break;
case Triple::x86_64: T.setArch(Triple::x86); break;
+ case Triple::spir64: T.setArch(Triple::spir); break;
}
return T;
}
@@ -760,7 +742,6 @@ Triple Triple::get64BitArchVariant() const {
case Triple::UnknownArch:
case Triple::amdil:
case Triple::arm:
- case Triple::cellspu:
case Triple::hexagon:
case Triple::le32:
case Triple::mblaze:
@@ -772,6 +753,7 @@ Triple Triple::get64BitArchVariant() const {
T.setArch(UnknownArch);
break;
+ case Triple::spir64:
case Triple::mips64:
case Triple::mips64el:
case Triple::nvptx64:
@@ -787,6 +769,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::ppc: T.setArch(Triple::ppc64); break;
case Triple::sparc: T.setArch(Triple::sparcv9); break;
case Triple::x86: T.setArch(Triple::x86_64); break;
+ case Triple::spir: T.setArch(Triple::spir64); break;
}
return T;
}
diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc
index 5a57a28..40d6b3f 100644
--- a/lib/Support/Unix/Memory.inc
+++ b/lib/Support/Unix/Memory.inc
@@ -13,6 +13,7 @@
#include "Unix.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Process.h"
#ifdef HAVE_SYS_MMAN_H
@@ -23,18 +24,150 @@
#include <mach/mach.h>
#endif
+#if defined(__mips__)
+# if defined(__OpenBSD__)
+# include <mips64/sysarch.h>
+# else
+# include <sys/cachectl.h>
+# endif
+#endif
+
+extern "C" void sys_icache_invalidate(const void *Addr, size_t len);
+
+namespace {
+
+int getPosixProtectionFlags(unsigned Flags) {
+ switch (Flags) {
+ case llvm::sys::Memory::MF_READ:
+ return PROT_READ;
+ case llvm::sys::Memory::MF_WRITE:
+ return PROT_WRITE;
+ case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_WRITE:
+ return PROT_READ | PROT_WRITE;
+ case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC:
+ return PROT_READ | PROT_EXEC;
+ case llvm::sys::Memory::MF_READ |
+ llvm::sys::Memory::MF_WRITE |
+ llvm::sys::Memory::MF_EXEC:
+ return PROT_READ | PROT_WRITE | PROT_EXEC;
+ case llvm::sys::Memory::MF_EXEC:
+ return PROT_EXEC;
+ default:
+ llvm_unreachable("Illegal memory protection flag specified!");
+ }
+ // Provide a default return value as required by some compilers.
+ return PROT_NONE;
+}
+
+} // namespace
+
+namespace llvm {
+namespace sys {
+
+MemoryBlock
+Memory::allocateMappedMemory(size_t NumBytes,
+ const MemoryBlock *const NearBlock,
+ unsigned PFlags,
+ error_code &EC) {
+ EC = error_code::success();
+ if (NumBytes == 0)
+ return MemoryBlock();
+
+ static const size_t PageSize = process::get_self()->page_size();
+ 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 = error_code(errno, system_category());
+ return MemoryBlock();
+ }
+ fd = zero_fd;
+#endif
+
+ int MMFlags = MAP_PRIVATE |
+#ifdef HAVE_MMAP_ANONYMOUS
+ MAP_ANONYMOUS
+#else
+ MAP_ANON
+#endif
+ ; // Ends statement above
+
+ int Protect = getPosixProtectionFlags(PFlags);
+
+ // Use any near hint and the page size to set a page-aligned starting address
+ uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) +
+ NearBlock->size() : 0;
+ if (Start && Start % PageSize)
+ Start += PageSize - Start % PageSize;
+
+ void *Addr = ::mmap(reinterpret_cast<void*>(Start), PageSize*NumPages,
+ Protect, MMFlags, fd, 0);
+ if (Addr == MAP_FAILED) {
+ if (NearBlock) //Try again without a near hint
+ return allocateMappedMemory(NumBytes, 0, PFlags, EC);
+
+ EC = error_code(errno, system_category());
+ return MemoryBlock();
+ }
+
+ MemoryBlock Result;
+ Result.Address = Addr;
+ Result.Size = NumPages*PageSize;
+
+ if (PFlags & MF_EXEC)
+ Memory::InvalidateInstructionCache(Result.Address, Result.Size);
+
+ return Result;
+}
+
+error_code
+Memory::releaseMappedMemory(MemoryBlock &M) {
+ if (M.Address == 0 || M.Size == 0)
+ return error_code::success();
+
+ if (0 != ::munmap(M.Address, M.Size))
+ return error_code(errno, system_category());
+
+ M.Address = 0;
+ M.Size = 0;
+
+ return error_code::success();
+}
+
+error_code
+Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) {
+ if (M.Address == 0 || M.Size == 0)
+ return error_code::success();
+
+ if (!Flags)
+ return error_code(EINVAL, generic_category());
+
+ int Protect = getPosixProtectionFlags(Flags);
+
+ int Result = ::mprotect(M.Address, M.Size, Protect);
+ if (Result != 0)
+ return error_code(errno, system_category());
+
+ if (Flags & MF_EXEC)
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
+
+ return error_code::success();
+}
+
/// AllocateRWX - Allocate a slab of memory with read/write/execute
/// permissions. This is typically used for JIT applications where we want
/// to emit code to the memory then jump to it. Getting this type of memory
/// is very OS specific.
///
-llvm::sys::MemoryBlock
-llvm::sys::Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
- std::string *ErrMsg) {
+MemoryBlock
+Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
+ std::string *ErrMsg) {
if (NumBytes == 0) return MemoryBlock();
- size_t pageSize = Process::GetPageSize();
- size_t NumPages = (NumBytes+pageSize-1)/pageSize;
+ size_t PageSize = process::get_self()->page_size();
+ size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
#ifdef NEED_DEV_ZERO_FOR_MMAP
@@ -58,10 +191,10 @@ llvm::sys::Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
NearBlock->size() : 0;
#if defined(__APPLE__) && defined(__arm__)
- void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_EXEC,
+ void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_EXEC,
flags, fd, 0);
#else
- void *pa = ::mmap(start, pageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
+ void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
flags, fd, 0);
#endif
if (pa == MAP_FAILED) {
@@ -74,40 +207,40 @@ llvm::sys::Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
#if defined(__APPLE__) && defined(__arm__)
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa,
- (vm_size_t)(pageSize*NumPages), 0,
+ (vm_size_t)(PageSize*NumPages), 0,
VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
if (KERN_SUCCESS != kr) {
MakeErrMsg(ErrMsg, "vm_protect max RX failed");
- return sys::MemoryBlock();
+ return MemoryBlock();
}
kr = vm_protect(mach_task_self(), (vm_address_t)pa,
- (vm_size_t)(pageSize*NumPages), 0,
+ (vm_size_t)(PageSize*NumPages), 0,
VM_PROT_READ | VM_PROT_WRITE);
if (KERN_SUCCESS != kr) {
MakeErrMsg(ErrMsg, "vm_protect RW failed");
- return sys::MemoryBlock();
+ return MemoryBlock();
}
#endif
MemoryBlock result;
result.Address = pa;
- result.Size = NumPages*pageSize;
+ result.Size = NumPages*PageSize;
return result;
}
-bool llvm::sys::Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
+bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
if (M.Address == 0 || M.Size == 0) return false;
if (0 != ::munmap(M.Address, M.Size))
return MakeErrMsg(ErrMsg, "Can't release RWX Memory");
return false;
}
-bool llvm::sys::Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
+bool Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
#if defined(__APPLE__) && defined(__arm__)
if (M.Address == 0 || M.Size == 0) return false;
- sys::Memory::InvalidateInstructionCache(M.Address, M.Size);
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
(vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_WRITE);
return KERN_SUCCESS == kr;
@@ -116,10 +249,10 @@ bool llvm::sys::Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) {
#endif
}
-bool llvm::sys::Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
+bool Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
#if defined(__APPLE__) && defined(__arm__)
if (M.Address == 0 || M.Size == 0) return false;
- sys::Memory::InvalidateInstructionCache(M.Address, M.Size);
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address,
(vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
return KERN_SUCCESS == kr;
@@ -128,7 +261,7 @@ bool llvm::sys::Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
#endif
}
-bool llvm::sys::Memory::setRangeWritable(const void *Addr, size_t Size) {
+bool Memory::setRangeWritable(const void *Addr, size_t Size) {
#if defined(__APPLE__) && defined(__arm__)
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
(vm_size_t)Size, 0,
@@ -139,7 +272,7 @@ bool llvm::sys::Memory::setRangeWritable(const void *Addr, size_t Size) {
#endif
}
-bool llvm::sys::Memory::setRangeExecutable(const void *Addr, size_t Size) {
+bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
#if defined(__APPLE__) && defined(__arm__)
kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr,
(vm_size_t)Size, 0,
@@ -149,3 +282,52 @@ bool llvm::sys::Memory::setRangeExecutable(const void *Addr, size_t Size) {
return true;
#endif
}
+
+/// InvalidateInstructionCache - Before the JIT can run a block of code
+/// that has been emitted it must invalidate the instruction cache on some
+/// platforms.
+void Memory::InvalidateInstructionCache(const void *Addr,
+ size_t Len) {
+
+// icache invalidation for PPC and ARM.
+#if defined(__APPLE__)
+
+# if (defined(__POWERPC__) || defined (__ppc__) || \
+ defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__)
+ sys_icache_invalidate(const_cast<void *>(Addr), Len);
+# endif
+
+#else
+
+# if (defined(__POWERPC__) || defined (__ppc__) || \
+ defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
+ const size_t LineSize = 32;
+
+ const intptr_t Mask = ~(LineSize - 1);
+ const intptr_t StartLine = ((intptr_t) Addr) & Mask;
+ const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
+
+ for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+ asm volatile("dcbf 0, %0" : : "r"(Line));
+ asm volatile("sync");
+
+ for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
+ asm volatile("icbi 0, %0" : : "r"(Line));
+ asm volatile("isync");
+# elif defined(__arm__) && defined(__GNUC__)
+ // FIXME: Can we safely always call this for __GNUC__ everywhere?
+ const char *Start = static_cast<const char *>(Addr);
+ const char *End = Start + Len;
+ __clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
+# elif defined(__mips__)
+ const char *Start = static_cast<const char *>(Addr);
+ cacheflush(const_cast<char *>(Start), Len, BCACHE);
+# endif
+
+#endif // end apple
+
+ ValgrindDiscardTranslations(Addr, Len);
+}
+
+} // namespace sys
+} // namespace llvm
diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc
index 6bddbdf..6a5ebb8 100644
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -261,7 +261,8 @@ Path::GetCurrentDirectory() {
}
#if defined(__FreeBSD__) || defined (__NetBSD__) || defined(__Bitrig__) || \
- defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__)
+ defined(__OpenBSD__) || defined(__minix) || defined(__FreeBSD_kernel__) || \
+ defined(__linux__) || defined(__CYGWIN__)
static int
test_dir(char buf[PATH_MAX], char ret[PATH_MAX],
const char *dir, const char *bin)
@@ -337,9 +338,17 @@ Path Path::GetMainExecutable(const char *argv0, void *MainAddr) {
return Path(exe_path);
#elif defined(__linux__) || defined(__CYGWIN__)
char exe_path[MAXPATHLEN];
- ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path));
- if (len >= 0)
- return Path(StringRef(exe_path, len));
+ StringRef aPath("/proc/self/exe");
+ if (sys::fs::exists(aPath)) {
+ // /proc is not always mounted under Linux (chroot for example).
+ ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path));
+ if (len >= 0)
+ return Path(StringRef(exe_path, len));
+ } else {
+ // Fall back to the classical detection.
+ if (getprogpath(exe_path, argv0) != NULL)
+ return Path(exe_path);
+ }
#elif defined(HAVE_DLFCN_H)
// Use dladdr to get executable path if available.
Dl_info DLInfo;
diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc
index f59551e..dc43b59 100644
--- a/lib/Support/Unix/PathV2.inc
+++ b/lib/Support/Unix/PathV2.inc
@@ -426,9 +426,10 @@ rety_open_create:
// If the file existed, try again, otherwise, error.
if (errno == errc::file_exists)
goto retry_random_path;
- // The path prefix doesn't exist.
- if (errno == errc::no_such_file_or_directory) {
- StringRef p(RandomPath.begin(), RandomPath.size());
+ // If path prefix doesn't exist, try to create it.
+ if (errno == errc::no_such_file_or_directory &&
+ !exists(path::parent_path(RandomPath))) {
+ StringRef p(RandomPath);
SmallString<64> dir_to_create;
for (path::const_iterator i = path::begin(p),
e = --path::end(p); i != e; ++i) {
@@ -547,7 +548,7 @@ mapped_file_region::~mapped_file_region() {
::munmap(Mapping, Size);
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
mapped_file_region::mapped_file_region(mapped_file_region &&other)
: Mode(other.Mode), Size(other.Size), Mapping(other.Mapping) {
other.Mapping = 0;
@@ -576,7 +577,7 @@ const char *mapped_file_region::const_data() const {
}
int mapped_file_region::alignment() {
- return Process::GetPageSize();
+ return process::get_self()->page_size();
}
error_code detail::directory_iterator_construct(detail::DirIterState &it,
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index 5204147..1335b78 100644
--- a/lib/Support/Unix/Process.inc
+++ b/lib/Support/Unix/Process.inc
@@ -44,9 +44,49 @@
using namespace llvm;
using namespace sys;
-unsigned
-Process::GetPageSize()
-{
+
+process::id_type self_process::get_id() {
+ return getpid();
+}
+
+static std::pair<TimeValue, TimeValue> 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)));
+#else
+#warning Cannot get usage times on this platform
+ return std::make_pair(TimeValue(), TimeValue());
+#endif
+}
+
+TimeValue self_process::get_user_time() const {
+#if _POSIX_TIMERS > 0 && _POSIX_CPUTIME > 0
+ // Try to get a high resolution CPU timer.
+ struct timespec TS;
+ if (::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &TS) == 0)
+ return TimeValue(static_cast<TimeValue::SecondsType>(TS.tv_sec),
+ static_cast<TimeValue::NanoSecondsType>(TS.tv_nsec));
+#endif
+
+ // Otherwise fall back to rusage based timing.
+ return getRUsageTimes().first;
+}
+
+TimeValue self_process::get_system_time() const {
+ // We can only collect system time by inspecting the results of getrusage.
+ return getRUsageTimes().second;
+}
+
+static unsigned getPageSize() {
#if defined(__CYGWIN__)
// On Cygwin, getpagesize() returns 64k but the page size for the purposes of
// memory protection and mmap() is 4k.
@@ -62,6 +102,12 @@ Process::GetPageSize()
return static_cast<unsigned>(page_size);
}
+// This constructor guaranteed to be run exactly once on a single thread, and
+// sets up various process invariants that can be queried cheaply from then on.
+self_process::self_process() : PageSize(getPageSize()) {
+}
+
+
size_t Process::GetMallocUsage() {
#if defined(HAVE_MALLINFO)
struct mallinfo mi;
@@ -86,49 +132,10 @@ size_t Process::GetMallocUsage() {
#endif
}
-size_t
-Process::GetTotalMemoryUsage()
-{
-#if defined(HAVE_MALLINFO)
- struct mallinfo mi = ::mallinfo();
- return mi.uordblks + mi.hblkhd;
-#elif defined(HAVE_MALLOC_ZONE_STATISTICS) && defined(HAVE_MALLOC_MALLOC_H)
- malloc_statistics_t Stats;
- malloc_zone_statistics(malloc_default_zone(), &Stats);
- return Stats.size_allocated; // darwin
-#elif defined(HAVE_GETRUSAGE) && !defined(__HAIKU__)
- struct rusage usage;
- ::getrusage(RUSAGE_SELF, &usage);
- return usage.ru_maxrss;
-#else
-#warning Cannot get total memory size on this platform
- return 0;
-#endif
-}
-
-void
-Process::GetTimeUsage(TimeValue& elapsed, TimeValue& user_time,
- TimeValue& sys_time)
-{
+void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
+ TimeValue &sys_time) {
elapsed = TimeValue::now();
-#if defined(HAVE_GETRUSAGE)
- struct rusage usage;
- ::getrusage(RUSAGE_SELF, &usage);
- user_time = TimeValue(
- static_cast<TimeValue::SecondsType>( usage.ru_utime.tv_sec ),
- static_cast<TimeValue::NanoSecondsType>( usage.ru_utime.tv_usec *
- TimeValue::NANOSECONDS_PER_MICROSECOND ) );
- sys_time = TimeValue(
- static_cast<TimeValue::SecondsType>( usage.ru_stime.tv_sec ),
- static_cast<TimeValue::NanoSecondsType>( usage.ru_stime.tv_usec *
- TimeValue::NANOSECONDS_PER_MICROSECOND ) );
-#else
-#warning Cannot get usage times on this platform
- user_time.seconds(0);
- user_time.microseconds(0);
- sys_time.seconds(0);
- sys_time.microseconds(0);
-#endif
+ llvm::tie(user_time, sys_time) = getRUsageTimes();
}
int Process::GetCurrentUserId() {
@@ -318,7 +325,7 @@ static unsigned GetRandomNumberSeed() {
// Otherwise, swizzle the current time and the process ID to form a reasonable
// seed.
- TimeValue Now = llvm::TimeValue::now();
+ TimeValue Now = TimeValue::now();
return hash_combine(Now.seconds(), Now.nanoseconds(), ::getpid());
}
#endif
diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc
index e5990d0..c384316 100644
--- a/lib/Support/Unix/Program.inc
+++ b/lib/Support/Unix/Program.inc
@@ -16,9 +16,9 @@
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
-#include <llvm/Config/config.h>
-#include "llvm/Support/FileSystem.h"
#include "Unix.h"
+#include "llvm/Support/FileSystem.h"
+#include <llvm/Config/config.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
@@ -47,11 +47,6 @@ Program::Program() : Data_(0) {}
Program::~Program() {}
-unsigned Program::GetPid() const {
- uint64_t pid = reinterpret_cast<uint64_t>(Data_);
- return static_cast<unsigned>(pid);
-}
-
// This function just uses the PATH environment variable to find the program.
Path
Program::FindProgramByName(const std::string& progName) {
@@ -394,24 +389,6 @@ Program::Wait(const sys::Path &path,
#endif
}
-bool
-Program::Kill(std::string* ErrMsg) {
- if (Data_ == 0) {
- MakeErrMsg(ErrMsg, "Process not started!");
- return true;
- }
-
- uint64_t pid64 = reinterpret_cast<uint64_t>(Data_);
- pid_t pid = static_cast<pid_t>(pid64);
-
- if (kill(pid, SIGKILL) != 0) {
- MakeErrMsg(ErrMsg, "The process couldn't be killed!");
- return true;
- }
-
- return false;
-}
-
error_code Program::ChangeStdinToBinary(){
// Do nothing, as Unix doesn't differentiate between text and binary.
return make_error_code(errc::success);
diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc
index 2f1e382..4a2496f 100644
--- a/lib/Support/Unix/Signals.inc
+++ b/lib/Support/Unix/Signals.inc
@@ -15,9 +15,9 @@
#include "Unix.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Mutex.h"
+#include <algorithm>
#include <string>
#include <vector>
-#include <algorithm>
#if HAVE_EXECINFO_H
# include <execinfo.h> // For backtrace().
#endif
@@ -121,17 +121,29 @@ static void UnregisterHandlers() {
/// NB: This must be an async signal safe function. It cannot allocate or free
/// memory, even in debug builds.
static void RemoveFilesToRemove() {
- // Note: avoid iterators in case of debug iterators that allocate or release
+ // We avoid iterators in case of debug iterators that allocate or release
// memory.
for (unsigned i = 0, e = FilesToRemove.size(); i != e; ++i) {
- // Note that we don't want to use any external code here, and we don't care
- // about errors. We're going to try as hard as we can as often as we need
- // to to make these files go away. If these aren't files, too bad.
- //
- // We do however rely on a std::string implementation for which repeated
- // calls to 'c_str()' don't allocate memory. We pre-call 'c_str()' on all
- // of these strings to try to ensure this is safe.
- unlink(FilesToRemove[i].c_str());
+ // We rely on a std::string implementation for which repeated calls to
+ // 'c_str()' don't allocate memory. We pre-call 'c_str()' on all of these
+ // strings to try to ensure this is safe.
+ const char *path = FilesToRemove[i].c_str();
+
+ // Get the status so we can determine if it's a file or directory. If we
+ // can't stat the file, ignore it.
+ struct stat buf;
+ if (stat(path, &buf) != 0)
+ continue;
+
+ // If this is not a regular file, ignore it. We want to prevent removal of
+ // special files like /dev/null, even if the compiler is being run with the
+ // super-user permissions.
+ if (!S_ISREG(buf.st_mode))
+ continue;
+
+ // Otherwise, remove the file. We ignore any errors here as there is nothing
+ // else we can do.
+ unlink(path);
}
}
@@ -243,7 +255,7 @@ void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
// On glibc systems we have the 'backtrace' function, which works nicely, but
// doesn't demangle symbols.
static void PrintStackTrace(void *) {
-#ifdef HAVE_BACKTRACE
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
static void* StackTrace[256];
// Use backtrace() to output a backtrace on Linux systems with glibc.
int depth = backtrace(StackTrace,
diff --git a/lib/Support/Unix/Unix.h b/lib/Support/Unix/Unix.h
index 361f297..051f56f 100644
--- a/lib/Support/Unix/Unix.h
+++ b/lib/Support/Unix/Unix.h
@@ -21,12 +21,12 @@
#include "llvm/Config/config.h" // Get autoconf configuration settings
#include "llvm/Support/Errno.h"
-#include <cstdlib>
+#include <algorithm>
+#include <cerrno>
#include <cstdio>
+#include <cstdlib>
#include <cstring>
-#include <cerrno>
#include <string>
-#include <algorithm>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
diff --git a/lib/Support/Windows/Memory.inc b/lib/Support/Windows/Memory.inc
index fcc7283..4c5aebd 100644
--- a/lib/Support/Windows/Memory.inc
+++ b/lib/Support/Windows/Memory.inc
@@ -12,51 +12,165 @@
//
//===----------------------------------------------------------------------===//
-#include "Windows.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Process.h"
+// The Windows.h header must be the last one included.
+#include "Windows.h"
+
+namespace {
+
+DWORD getWindowsProtectionFlags(unsigned Flags) {
+ switch (Flags) {
+ // Contrary to what you might expect, the Windows page protection flags
+ // are not a bitwise combination of RWX values
+ case llvm::sys::Memory::MF_READ:
+ return PAGE_READONLY;
+ case llvm::sys::Memory::MF_WRITE:
+ // Note: PAGE_WRITE is not supported by VirtualProtect
+ return PAGE_READWRITE;
+ case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_WRITE:
+ return PAGE_READWRITE;
+ case llvm::sys::Memory::MF_READ|llvm::sys::Memory::MF_EXEC:
+ return PAGE_EXECUTE_READ;
+ case llvm::sys::Memory::MF_READ |
+ llvm::sys::Memory::MF_WRITE |
+ llvm::sys::Memory::MF_EXEC:
+ return PAGE_EXECUTE_READWRITE;
+ case llvm::sys::Memory::MF_EXEC:
+ return PAGE_EXECUTE;
+ default:
+ llvm_unreachable("Illegal memory protection flag specified!");
+ }
+ // Provide a default return value as required by some compilers.
+ return PAGE_NOACCESS;
+}
+
+size_t getAllocationGranularity() {
+ SYSTEM_INFO Info;
+ ::GetSystemInfo(&Info);
+ if (Info.dwPageSize > Info.dwAllocationGranularity)
+ return Info.dwPageSize;
+ else
+ return Info.dwAllocationGranularity;
+}
+
+} // namespace
+
namespace llvm {
-using namespace sys;
+namespace sys {
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only Win32 specific code
//=== and must not be UNIX code
//===----------------------------------------------------------------------===//
-MemoryBlock Memory::AllocateRWX(size_t NumBytes,
- const MemoryBlock *NearBlock,
- std::string *ErrMsg) {
- if (NumBytes == 0) return MemoryBlock();
+MemoryBlock Memory::allocateMappedMemory(size_t NumBytes,
+ const MemoryBlock *const NearBlock,
+ unsigned Flags,
+ error_code &EC) {
+ EC = error_code::success();
+ if (NumBytes == 0)
+ return MemoryBlock();
+
+ // While we'd be happy to allocate single pages, the Windows allocation
+ // granularity may be larger than a single page (in practice, it is 64K)
+ // so mapping less than that will create an unreachable fragment of memory.
+ static const size_t Granularity = getAllocationGranularity();
+ const size_t NumBlocks = (NumBytes+Granularity-1)/Granularity;
- static const size_t pageSize = Process::GetPageSize();
- size_t NumPages = (NumBytes+pageSize-1)/pageSize;
+ uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) +
+ NearBlock->size()
+ : NULL;
- PVOID start = NearBlock ? static_cast<unsigned char *>(NearBlock->base()) +
- NearBlock->size() : NULL;
+ // If the requested address is not aligned to the allocation granularity,
+ // round up to get beyond NearBlock. VirtualAlloc would have rounded down.
+ if (Start && Start % Granularity != 0)
+ Start += Granularity - Start % Granularity;
- void *pa = VirtualAlloc(start, NumPages*pageSize, MEM_RESERVE | MEM_COMMIT,
- PAGE_EXECUTE_READWRITE);
- if (pa == NULL) {
+ DWORD Protect = getWindowsProtectionFlags(Flags);
+
+ void *PA = ::VirtualAlloc(reinterpret_cast<void*>(Start),
+ NumBlocks*Granularity,
+ MEM_RESERVE | MEM_COMMIT, Protect);
+ if (PA == NULL) {
if (NearBlock) {
// Try again without the NearBlock hint
- return AllocateRWX(NumBytes, NULL, ErrMsg);
+ return allocateMappedMemory(NumBytes, NULL, Flags, EC);
}
- MakeErrMsg(ErrMsg, "Can't allocate RWX Memory: ");
+ EC = error_code(::GetLastError(), system_category());
return MemoryBlock();
}
- MemoryBlock result;
- result.Address = pa;
- result.Size = NumPages*pageSize;
- return result;
+ MemoryBlock Result;
+ Result.Address = PA;
+ Result.Size = NumBlocks*Granularity;
+ ;
+ if (Flags & MF_EXEC)
+ Memory::InvalidateInstructionCache(Result.Address, Result.Size);
+
+ return Result;
}
-bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
- if (M.Address == 0 || M.Size == 0) return false;
+error_code Memory::releaseMappedMemory(MemoryBlock &M) {
+ if (M.Address == 0 || M.Size == 0)
+ return error_code::success();
+
if (!VirtualFree(M.Address, 0, MEM_RELEASE))
- return MakeErrMsg(ErrMsg, "Can't release RWX Memory: ");
- return false;
+ return error_code(::GetLastError(), system_category());
+
+ M.Address = 0;
+ M.Size = 0;
+
+ return error_code::success();
+}
+
+error_code Memory::protectMappedMemory(const MemoryBlock &M,
+ unsigned Flags) {
+ if (M.Address == 0 || M.Size == 0)
+ return error_code::success();
+
+ DWORD Protect = getWindowsProtectionFlags(Flags);
+
+ DWORD OldFlags;
+ if (!VirtualProtect(M.Address, M.Size, Protect, &OldFlags))
+ return error_code(::GetLastError(), system_category());
+
+ if (Flags & MF_EXEC)
+ Memory::InvalidateInstructionCache(M.Address, M.Size);
+
+ return error_code::success();
+}
+
+/// InvalidateInstructionCache - Before the JIT can run a block of code
+/// that has been emitted it must invalidate the instruction cache on some
+/// platforms.
+void Memory::InvalidateInstructionCache(
+ const void *Addr, size_t Len) {
+ FlushInstructionCache(GetCurrentProcess(), Addr, Len);
+}
+
+
+MemoryBlock Memory::AllocateRWX(size_t NumBytes,
+ const MemoryBlock *NearBlock,
+ std::string *ErrMsg) {
+ MemoryBlock MB;
+ error_code EC;
+ MB = allocateMappedMemory(NumBytes, NearBlock,
+ MF_READ|MF_WRITE|MF_EXEC, EC);
+ if (EC != error_code::success() && ErrMsg) {
+ MakeErrMsg(ErrMsg, EC.message());
+ }
+ return MB;
+}
+
+bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
+ error_code EC = releaseMappedMemory(M);
+ if (EC == error_code::success())
+ return false;
+ MakeErrMsg(ErrMsg, EC.message());
+ return true;
}
static DWORD getProtection(const void *addr) {
@@ -93,7 +207,7 @@ bool Memory::setRangeWritable(const void *Addr, size_t Size) {
}
DWORD oldProt;
- sys::Memory::InvalidateInstructionCache(Addr, Size);
+ Memory::InvalidateInstructionCache(Addr, Size);
return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt)
== TRUE;
}
@@ -112,9 +226,10 @@ bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
}
DWORD oldProt;
- sys::Memory::InvalidateInstructionCache(Addr, Size);
+ Memory::InvalidateInstructionCache(Addr, Size);
return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt)
== TRUE;
}
-}
+} // namespace sys
+} // namespace llvm
diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc
index 2280b34..98d8a18 100644
--- a/lib/Support/Windows/Path.inc
+++ b/lib/Support/Windows/Path.inc
@@ -17,8 +17,8 @@
//===----------------------------------------------------------------------===//
#include "Windows.h"
-#include <malloc.h>
#include <cstdio>
+#include <malloc.h>
// We need to undo a macro defined in Windows.h, otherwise we won't compile:
#undef CopyFile
diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc
index 696768b..2e6cc96 100644
--- a/lib/Support/Windows/PathV2.inc
+++ b/lib/Support/Windows/PathV2.inc
@@ -328,7 +328,7 @@ error_code resize_file(const Twine &path, uint64_t size) {
path_utf16))
return ec;
- int fd = ::_wopen(path_utf16.begin(), O_BINARY, S_IREAD | S_IWRITE);
+ int fd = ::_wopen(path_utf16.begin(), O_BINARY | _O_RDWR, S_IWRITE);
if (fd == -1)
return error_code(errno, generic_category());
#ifdef HAVE__CHSIZE_S
@@ -794,7 +794,7 @@ mapped_file_region::mapped_file_region(const Twine &path,
SmallVector<wchar_t, 128> path_utf16;
// Convert path to UTF-16.
- if (ec = UTF8ToUTF16(path.toStringRef(path_storage), path_utf16))
+ if ((ec = UTF8ToUTF16(path.toStringRef(path_storage), path_utf16)))
return;
// Get file handle for creating a file mapping.
@@ -861,7 +861,7 @@ mapped_file_region::~mapped_file_region() {
::CloseHandle(FileHandle);
}
-#if LLVM_USE_RVALUE_REFERENCES
+#if LLVM_HAS_RVALUE_REFERENCES
mapped_file_region::mapped_file_region(mapped_file_region &&other)
: Mode(other.Mode)
, Size(other.Size)
diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc
index e29eb6d..ad94128 100644
--- a/lib/Support/Windows/Process.inc
+++ b/lib/Support/Windows/Process.inc
@@ -12,10 +12,10 @@
//===----------------------------------------------------------------------===//
#include "Windows.h"
-#include <psapi.h>
-#include <malloc.h>
-#include <io.h>
#include <direct.h>
+#include <io.h>
+#include <malloc.h>
+#include <psapi.h>
#ifdef __MINGW32__
#if (HAVE_LIBPSAPI != 1)
@@ -35,13 +35,47 @@
# define _HEAPOK (-2)
#endif
-namespace llvm {
+using namespace llvm;
using namespace sys;
+
+process::id_type self_process::get_id() {
+ return GetCurrentProcess();
+}
+
+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));
+}
+
+TimeValue self_process::get_user_time() const {
+ FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
+ if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
+ &UserTime) == 0)
+ return TimeValue();
+
+ return getTimeValueFromFILETIME(UserTime);
+}
+
+TimeValue self_process::get_system_time() const {
+ FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
+ if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
+ &UserTime) == 0)
+ return TimeValue();
+
+ return getTimeValueFromFILETIME(KernelTime);
+}
+
// This function retrieves the page size using GetSystemInfo and is present
-// solely so it can be called once in Process::GetPageSize to initialize the
-// static variable PageSize.
-inline unsigned GetPageSizeOnce() {
+// solely so it can be called once to initialize the self_process member below.
+static unsigned getPageSize() {
// NOTE: A 32-bit application running under WOW64 is supposed to use
// GetNativeSystemInfo. However, this interface is not present prior
// to Windows XP so to use it requires dynamic linking. It is not clear
@@ -52,12 +86,12 @@ inline unsigned GetPageSizeOnce() {
return static_cast<unsigned>(info.dwPageSize);
}
-unsigned
-Process::GetPageSize() {
- static const unsigned PageSize = GetPageSizeOnce();
- return PageSize;
+// This constructor guaranteed to be run exactly once on a single thread, and
+// sets up various process invariants that can be queried cheaply from then on.
+self_process::self_process() : PageSize(getPageSize()) {
}
+
size_t
Process::GetMallocUsage()
{
@@ -72,30 +106,17 @@ Process::GetMallocUsage()
return size;
}
-size_t
-Process::GetTotalMemoryUsage()
-{
- PROCESS_MEMORY_COUNTERS pmc;
- GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
- return pmc.PagefileUsage;
-}
-
-void
-Process::GetTimeUsage(
- TimeValue& elapsed, TimeValue& user_time, TimeValue& sys_time)
-{
+void Process::GetTimeUsage(TimeValue &elapsed, TimeValue &user_time,
+ TimeValue &sys_time) {
elapsed = TimeValue::now();
- uint64_t ProcCreate, ProcExit, KernelTime, UserTime;
- GetProcessTimes(GetCurrentProcess(), (FILETIME*)&ProcCreate,
- (FILETIME*)&ProcExit, (FILETIME*)&KernelTime,
- (FILETIME*)&UserTime);
+ FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
+ if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
+ &UserTime) == 0)
+ return;
- // FILETIME's are # of 100 nanosecond ticks (1/10th of a microsecond)
- user_time.seconds( UserTime / 10000000 );
- user_time.nanoseconds( unsigned(UserTime % 10000000) * 100 );
- sys_time.seconds( KernelTime / 10000000 );
- sys_time.nanoseconds( unsigned(KernelTime % 10000000) * 100 );
+ user_time = getTimeValueFromFILETIME(UserTime);
+ sys_time = getTimeValueFromFILETIME(KernelTime);
}
int Process::GetCurrentUserId()
@@ -255,5 +276,3 @@ const char *Process::ResetColor() {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), defaultColors());
return 0;
}
-
-}
diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc
index 80ccaa6..691d6d4 100644
--- a/lib/Support/Windows/Program.inc
+++ b/lib/Support/Windows/Program.inc
@@ -13,9 +13,9 @@
#include "Windows.h"
#include <cstdio>
-#include <malloc.h>
-#include <io.h>
#include <fcntl.h>
+#include <io.h>
+#include <malloc.h>
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only Win32 specific code
@@ -43,11 +43,6 @@ Program::~Program() {
}
}
-unsigned Program::GetPid() const {
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
- return wpi->dwProcessId;
-}
-
// This function just uses the PATH environment variable to find the program.
Path
Program::FindProgramByName(const std::string& progName) {
@@ -380,23 +375,6 @@ Program::Wait(const Path &path,
return 1;
}
-bool
-Program::Kill(std::string* ErrMsg) {
- if (Data_ == 0) {
- MakeErrMsg(ErrMsg, "Process not started!");
- return true;
- }
-
- Win32ProcessInfo* wpi = reinterpret_cast<Win32ProcessInfo*>(Data_);
- HANDLE hProcess = wpi->hProcess;
- if (TerminateProcess(hProcess, 1) == 0) {
- MakeErrMsg(ErrMsg, "The process couldn't be killed!");
- return true;
- }
-
- return false;
-}
-
error_code Program::ChangeStdinToBinary(){
int result = _setmode( _fileno(stdin), _O_BINARY );
if (result == -1)
diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc
index 38308f6..a969753 100644
--- a/lib/Support/Windows/Signals.inc
+++ b/lib/Support/Windows/Signals.inc
@@ -12,9 +12,9 @@
//===----------------------------------------------------------------------===//
#include "Windows.h"
+#include <algorithm>
#include <stdio.h>
#include <vector>
-#include <algorithm>
#ifdef __MINGW32__
#include <imagehlp.h>
diff --git a/lib/Support/YAMLParser.cpp b/lib/Support/YAMLParser.cpp
index 7c353c8..2cead20 100644
--- a/lib/Support/YAMLParser.cpp
+++ b/lib/Support/YAMLParser.cpp
@@ -12,16 +12,15 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/YAMLParser.h"
-
-#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.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/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace yaml;
@@ -252,6 +251,7 @@ namespace yaml {
class Scanner {
public:
Scanner(const StringRef Input, SourceMgr &SM);
+ Scanner(MemoryBuffer *Buffer, SourceMgr &SM_);
/// @brief Parse the next token and return it without popping it.
Token &peekNext();
@@ -708,6 +708,21 @@ Scanner::Scanner(StringRef Input, SourceMgr &sm)
End = InputBuffer->getBufferEnd();
}
+Scanner::Scanner(MemoryBuffer *Buffer, SourceMgr &SM_)
+ : SM(SM_)
+ , InputBuffer(Buffer)
+ , Current(InputBuffer->getBufferStart())
+ , End(InputBuffer->getBufferEnd())
+ , Indent(-1)
+ , Column(0)
+ , Line(0)
+ , FlowLevel(0)
+ , IsStartOfStream(true)
+ , IsSimpleKeyAllowed(true)
+ , Failed(false) {
+ SM.AddNewSourceBuffer(InputBuffer, SMLoc());
+}
+
Token &Scanner::peekNext() {
// If the current token is a possible simple key, keep parsing until we
// can confirm.
@@ -903,6 +918,7 @@ bool Scanner::consume(uint32_t Expected) {
void Scanner::skip(uint32_t Distance) {
Current += Distance;
Column += Distance;
+ assert(Current <= End && "Skipped past the end");
}
bool Scanner::isBlankOrBreak(StringRef::iterator Position) {
@@ -1239,6 +1255,12 @@ bool Scanner::scanFlowScalar(bool IsDoubleQuoted) {
}
}
}
+
+ if (Current == End) {
+ setError("Expected quote at end of scalar", Current);
+ return false;
+ }
+
skip(1); // Skip ending quote.
Token T;
T.Kind = Token::TK_Scalar;
@@ -1525,6 +1547,10 @@ Stream::Stream(StringRef Input, SourceMgr &SM)
: scanner(new Scanner(Input, SM))
, CurrentDoc(0) {}
+Stream::Stream(MemoryBuffer *InputBuffer, SourceMgr &SM)
+ : scanner(new Scanner(InputBuffer, SM))
+ , CurrentDoc(0) {}
+
Stream::~Stream() {}
bool Stream::failed() { return scanner->failed(); }
diff --git a/lib/Support/YAMLTraits.cpp b/lib/Support/YAMLTraits.cpp
new file mode 100644
index 0000000..9da2aa7
--- /dev/null
+++ b/lib/Support/YAMLTraits.cpp
@@ -0,0 +1,827 @@
+//===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstring>
+using namespace llvm;
+using namespace yaml;
+
+//===----------------------------------------------------------------------===//
+// IO
+//===----------------------------------------------------------------------===//
+
+IO::IO(void *Context) : Ctxt(Context) {
+}
+
+IO::~IO() {
+}
+
+void *IO::getContext() {
+ return Ctxt;
+}
+
+void IO::setContext(void *Context) {
+ Ctxt = Context;
+}
+
+//===----------------------------------------------------------------------===//
+// Input
+//===----------------------------------------------------------------------===//
+
+Input::Input(StringRef InputContent, void *Ctxt)
+ : IO(Ctxt),
+ Strm(new Stream(InputContent, SrcMgr)),
+ CurrentNode(NULL) {
+ DocIterator = Strm->begin();
+}
+
+Input::~Input() {
+
+}
+
+error_code Input::error() {
+ return EC;
+}
+
+void Input::setDiagHandler(SourceMgr::DiagHandlerTy Handler, void *Ctxt) {
+ SrcMgr.setDiagHandler(Handler, Ctxt);
+}
+
+bool Input::outputting() {
+ return false;
+}
+
+bool Input::setCurrentDocument() {
+ if (DocIterator != Strm->end()) {
+ Node *N = DocIterator->getRoot();
+ if (isa<NullNode>(N)) {
+ // Empty files are allowed and ignored
+ ++DocIterator;
+ return setCurrentDocument();
+ }
+ TopNode.reset(this->createHNodes(N));
+ CurrentNode = TopNode.get();
+ return true;
+ }
+ return false;
+}
+
+void Input::nextDocument() {
+ ++DocIterator;
+}
+
+void Input::beginMapping() {
+ if (EC)
+ return;
+ MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
+ if (MN) {
+ MN->ValidKeys.clear();
+ }
+}
+
+bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
+ void *&SaveInfo) {
+ UseDefault = false;
+ if (EC)
+ return false;
+ MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
+ if (!MN) {
+ setError(CurrentNode, "not a mapping");
+ return false;
+ }
+ MN->ValidKeys.push_back(Key);
+ HNode *Value = MN->Mapping[Key];
+ if (!Value) {
+ if (Required)
+ setError(CurrentNode, Twine("missing required key '") + Key + "'");
+ else
+ UseDefault = true;
+ return false;
+ }
+ SaveInfo = CurrentNode;
+ CurrentNode = Value;
+ return true;
+}
+
+void Input::postflightKey(void *saveInfo) {
+ CurrentNode = reinterpret_cast<HNode *>(saveInfo);
+}
+
+void Input::endMapping() {
+ if (EC)
+ return;
+ MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
+ if (!MN)
+ return;
+ for (MapHNode::NameToNode::iterator i = MN->Mapping.begin(),
+ End = MN->Mapping.end(); i != End; ++i) {
+ if (!MN->isValidKey(i->first)) {
+ setError(i->second, Twine("unknown key '") + i->first + "'");
+ break;
+ }
+ }
+}
+
+unsigned Input::beginSequence() {
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ return SQ->Entries.size();
+ }
+ return 0;
+}
+
+void Input::endSequence() {
+}
+
+bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
+ if (EC)
+ return false;
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ SaveInfo = CurrentNode;
+ CurrentNode = SQ->Entries[Index];
+ return true;
+ }
+ return false;
+}
+
+void Input::postflightElement(void *SaveInfo) {
+ CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
+}
+
+unsigned Input::beginFlowSequence() {
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ return SQ->Entries.size();
+ }
+ return 0;
+}
+
+bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
+ if (EC)
+ return false;
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ SaveInfo = CurrentNode;
+ CurrentNode = SQ->Entries[index];
+ return true;
+ }
+ return false;
+}
+
+void Input::postflightFlowElement(void *SaveInfo) {
+ CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
+}
+
+void Input::endFlowSequence() {
+}
+
+void Input::beginEnumScalar() {
+ ScalarMatchFound = false;
+}
+
+bool Input::matchEnumScalar(const char *Str, bool) {
+ if (ScalarMatchFound)
+ return false;
+ if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
+ if (SN->value().equals(Str)) {
+ ScalarMatchFound = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+void Input::endEnumScalar() {
+ if (!ScalarMatchFound) {
+ setError(CurrentNode, "unknown enumerated scalar");
+ }
+}
+
+bool Input::beginBitSetScalar(bool &DoClear) {
+ BitValuesUsed.clear();
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
+ } else {
+ setError(CurrentNode, "expected sequence of bit values");
+ }
+ DoClear = true;
+ return true;
+}
+
+bool Input::bitSetMatch(const char *Str, bool) {
+ if (EC)
+ return false;
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ unsigned Index = 0;
+ for (std::vector<HNode *>::iterator i = SQ->Entries.begin(),
+ End = SQ->Entries.end(); i != End; ++i) {
+ if (ScalarHNode *SN = dyn_cast<ScalarHNode>(*i)) {
+ if (SN->value().equals(Str)) {
+ BitValuesUsed[Index] = true;
+ return true;
+ }
+ } else {
+ setError(CurrentNode, "unexpected scalar in sequence of bit values");
+ }
+ ++Index;
+ }
+ } else {
+ setError(CurrentNode, "expected sequence of bit values");
+ }
+ return false;
+}
+
+void Input::endBitSetScalar() {
+ if (EC)
+ return;
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ assert(BitValuesUsed.size() == SQ->Entries.size());
+ for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
+ if (!BitValuesUsed[i]) {
+ setError(SQ->Entries[i], "unknown bit value");
+ return;
+ }
+ }
+ }
+}
+
+void Input::scalarString(StringRef &S) {
+ if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
+ S = SN->value();
+ } else {
+ setError(CurrentNode, "unexpected scalar");
+ }
+}
+
+void Input::setError(HNode *hnode, const Twine &message) {
+ this->setError(hnode->_node, message);
+}
+
+void Input::setError(Node *node, const Twine &message) {
+ Strm->printError(node, message);
+ EC = make_error_code(errc::invalid_argument);
+}
+
+Input::HNode *Input::createHNodes(Node *N) {
+ SmallString<128> StringStorage;
+ if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
+ StringRef KeyStr = SN->getValue(StringStorage);
+ if (!StringStorage.empty()) {
+ // Copy string to permanent storage
+ unsigned Len = StringStorage.size();
+ char *Buf = StringAllocator.Allocate<char>(Len);
+ memcpy(Buf, &StringStorage[0], Len);
+ KeyStr = StringRef(Buf, Len);
+ }
+ return new ScalarHNode(N, KeyStr);
+ } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
+ SequenceHNode *SQHNode = new SequenceHNode(N);
+ for (SequenceNode::iterator i = SQ->begin(), End = SQ->end(); i != End;
+ ++i) {
+ HNode *Entry = this->createHNodes(i);
+ if (EC)
+ break;
+ SQHNode->Entries.push_back(Entry);
+ }
+ return SQHNode;
+ } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
+ MapHNode *mapHNode = new MapHNode(N);
+ for (MappingNode::iterator i = Map->begin(), End = Map->end(); i != End;
+ ++i) {
+ ScalarNode *KeyScalar = dyn_cast<ScalarNode>(i->getKey());
+ StringStorage.clear();
+ StringRef KeyStr = KeyScalar->getValue(StringStorage);
+ if (!StringStorage.empty()) {
+ // Copy string to permanent storage
+ unsigned Len = StringStorage.size();
+ char *Buf = StringAllocator.Allocate<char>(Len);
+ memcpy(Buf, &StringStorage[0], Len);
+ KeyStr = StringRef(Buf, Len);
+ }
+ HNode *ValueHNode = this->createHNodes(i->getValue());
+ if (EC)
+ break;
+ mapHNode->Mapping[KeyStr] = ValueHNode;
+ }
+ return mapHNode;
+ } else if (isa<NullNode>(N)) {
+ return new EmptyHNode(N);
+ } else {
+ setError(N, "unknown node kind");
+ return NULL;
+ }
+}
+
+bool Input::MapHNode::isValidKey(StringRef Key) {
+ for (SmallVector<const char *, 6>::iterator i = ValidKeys.begin(),
+ End = ValidKeys.end(); i != End; ++i) {
+ if (Key.equals(*i))
+ return true;
+ }
+ return false;
+}
+
+void Input::setError(const Twine &Message) {
+ this->setError(CurrentNode, Message);
+}
+
+Input::MapHNode::~MapHNode() {
+ for (MapHNode::NameToNode::iterator i = Mapping.begin(), End = Mapping.end();
+ i != End; ++i) {
+ delete i->second;
+ }
+}
+
+Input::SequenceHNode::~SequenceHNode() {
+ for (std::vector<HNode*>::iterator i = Entries.begin(), End = Entries.end();
+ i != End; ++i) {
+ delete *i;
+ }
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Output
+//===----------------------------------------------------------------------===//
+
+Output::Output(raw_ostream &yout, void *context)
+ : IO(context),
+ Out(yout),
+ Column(0),
+ ColumnAtFlowStart(0),
+ NeedBitValueComma(false),
+ NeedFlowSequenceComma(false),
+ EnumerationMatchFound(false),
+ NeedsNewLine(false) {
+}
+
+Output::~Output() {
+}
+
+bool Output::outputting() {
+ return true;
+}
+
+void Output::beginMapping() {
+ StateStack.push_back(inMapFirstKey);
+ NeedsNewLine = true;
+}
+
+void Output::endMapping() {
+ StateStack.pop_back();
+}
+
+bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
+ bool &UseDefault, void *&) {
+ UseDefault = false;
+ if (Required || !SameAsDefault) {
+ this->newLineCheck();
+ this->paddedKey(Key);
+ return true;
+ }
+ return false;
+}
+
+void Output::postflightKey(void *) {
+ if (StateStack.back() == inMapFirstKey) {
+ StateStack.pop_back();
+ StateStack.push_back(inMapOtherKey);
+ }
+}
+
+void Output::beginDocuments() {
+ this->outputUpToEndOfLine("---");
+}
+
+bool Output::preflightDocument(unsigned index) {
+ if (index > 0)
+ this->outputUpToEndOfLine("\n---");
+ return true;
+}
+
+void Output::postflightDocument() {
+}
+
+void Output::endDocuments() {
+ output("\n...\n");
+}
+
+unsigned Output::beginSequence() {
+ StateStack.push_back(inSeq);
+ NeedsNewLine = true;
+ return 0;
+}
+
+void Output::endSequence() {
+ StateStack.pop_back();
+}
+
+bool Output::preflightElement(unsigned, void *&) {
+ return true;
+}
+
+void Output::postflightElement(void *) {
+}
+
+unsigned Output::beginFlowSequence() {
+ StateStack.push_back(inFlowSeq);
+ this->newLineCheck();
+ ColumnAtFlowStart = Column;
+ output("[ ");
+ NeedFlowSequenceComma = false;
+ return 0;
+}
+
+void Output::endFlowSequence() {
+ StateStack.pop_back();
+ this->outputUpToEndOfLine(" ]");
+}
+
+bool Output::preflightFlowElement(unsigned, void *&) {
+ if (NeedFlowSequenceComma)
+ output(", ");
+ if (Column > 70) {
+ output("\n");
+ for (int i = 0; i < ColumnAtFlowStart; ++i)
+ output(" ");
+ Column = ColumnAtFlowStart;
+ output(" ");
+ }
+ return true;
+}
+
+void Output::postflightFlowElement(void *) {
+ NeedFlowSequenceComma = true;
+}
+
+void Output::beginEnumScalar() {
+ EnumerationMatchFound = false;
+}
+
+bool Output::matchEnumScalar(const char *Str, bool Match) {
+ if (Match && !EnumerationMatchFound) {
+ this->newLineCheck();
+ this->outputUpToEndOfLine(Str);
+ EnumerationMatchFound = true;
+ }
+ return false;
+}
+
+void Output::endEnumScalar() {
+ if (!EnumerationMatchFound)
+ llvm_unreachable("bad runtime enum value");
+}
+
+bool Output::beginBitSetScalar(bool &DoClear) {
+ this->newLineCheck();
+ output("[ ");
+ NeedBitValueComma = false;
+ DoClear = false;
+ return true;
+}
+
+bool Output::bitSetMatch(const char *Str, bool Matches) {
+ if (Matches) {
+ if (NeedBitValueComma)
+ output(", ");
+ this->output(Str);
+ NeedBitValueComma = true;
+ }
+ return false;
+}
+
+void Output::endBitSetScalar() {
+ this->outputUpToEndOfLine(" ]");
+}
+
+void Output::scalarString(StringRef &S) {
+ this->newLineCheck();
+ if (S.find('\n') == StringRef::npos) {
+ // No embedded new-line chars, just print string.
+ this->outputUpToEndOfLine(S);
+ return;
+ }
+ unsigned i = 0;
+ unsigned j = 0;
+ unsigned End = S.size();
+ output("'"); // Starting single quote.
+ const char *Base = S.data();
+ while (j < End) {
+ // Escape a single quote by doubling it.
+ if (S[j] == '\'') {
+ output(StringRef(&Base[i], j - i + 1));
+ output("'");
+ i = j + 1;
+ }
+ ++j;
+ }
+ output(StringRef(&Base[i], j - i));
+ this->outputUpToEndOfLine("'"); // Ending single quote.
+}
+
+void Output::setError(const Twine &message) {
+}
+
+void Output::output(StringRef s) {
+ Column += s.size();
+ Out << s;
+}
+
+void Output::outputUpToEndOfLine(StringRef s) {
+ this->output(s);
+ if (StateStack.empty() || StateStack.back() != inFlowSeq)
+ NeedsNewLine = true;
+}
+
+void Output::outputNewLine() {
+ Out << "\n";
+ Column = 0;
+}
+
+// if seq at top, indent as if map, then add "- "
+// if seq in middle, use "- " if firstKey, else use " "
+//
+
+void Output::newLineCheck() {
+ if (!NeedsNewLine)
+ return;
+ NeedsNewLine = false;
+
+ this->outputNewLine();
+
+ assert(StateStack.size() > 0);
+ unsigned Indent = StateStack.size() - 1;
+ bool OutputDash = false;
+
+ if (StateStack.back() == inSeq) {
+ OutputDash = true;
+ } else if ((StateStack.size() > 1) && (StateStack.back() == inMapFirstKey) &&
+ (StateStack[StateStack.size() - 2] == inSeq)) {
+ --Indent;
+ OutputDash = true;
+ }
+
+ for (unsigned i = 0; i < Indent; ++i) {
+ output(" ");
+ }
+ if (OutputDash) {
+ output("- ");
+ }
+
+}
+
+void Output::paddedKey(StringRef key) {
+ output(key);
+ output(":");
+ const char *spaces = " ";
+ if (key.size() < strlen(spaces))
+ output(&spaces[key.size()]);
+ else
+ output(" ");
+}
+
+//===----------------------------------------------------------------------===//
+// traits for built-in types
+//===----------------------------------------------------------------------===//
+
+void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
+ Out << (Val ? "true" : "false");
+}
+
+StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
+ if (Scalar.equals("true")) {
+ Val = true;
+ return StringRef();
+ } else if (Scalar.equals("false")) {
+ Val = false;
+ return StringRef();
+ }
+ return "invalid boolean";
+}
+
+void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
+ StringRef &Val) {
+ Val = Scalar;
+ return StringRef();
+}
+
+void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
+ raw_ostream &Out) {
+ // use temp uin32_t because ostream thinks uint8_t is a character
+ uint32_t Num = Val;
+ Out << Num;
+}
+
+StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid number";
+ if (n > 0xFF)
+ return "out of range number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
+ uint16_t &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid number";
+ if (n > 0xFFFF)
+ return "out of range number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
+ uint32_t &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid number";
+ if (n > 0xFFFFFFFFUL)
+ return "out of range number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
+ uint64_t &Val) {
+ unsigned long long N;
+ if (getAsUnsignedInteger(Scalar, 0, N))
+ return "invalid number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
+ // use temp in32_t because ostream thinks int8_t is a character
+ int32_t Num = Val;
+ Out << Num;
+}
+
+StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
+ long long N;
+ if (getAsSignedInteger(Scalar, 0, N))
+ return "invalid number";
+ if ((N > 127) || (N < -128))
+ return "out of range number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
+ long long N;
+ if (getAsSignedInteger(Scalar, 0, N))
+ return "invalid number";
+ if ((N > INT16_MAX) || (N < INT16_MIN))
+ return "out of range number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
+ long long N;
+ if (getAsSignedInteger(Scalar, 0, N))
+ return "invalid number";
+ if ((N > INT32_MAX) || (N < INT32_MIN))
+ return "out of range number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
+ raw_ostream &Out) {
+ Out << Val;
+}
+
+StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
+ long long N;
+ if (getAsSignedInteger(Scalar, 0, N))
+ return "invalid number";
+ Val = N;
+ return StringRef();
+}
+
+void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
+ Out << format("%g", Val);
+}
+
+StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
+ SmallString<32> buff(Scalar.begin(), Scalar.end());
+ char *end;
+ Val = strtod(buff.c_str(), &end);
+ if (*end != '\0')
+ return "invalid floating point number";
+ return StringRef();
+}
+
+void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
+ Out << format("%g", Val);
+}
+
+StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
+ SmallString<32> buff(Scalar.begin(), Scalar.end());
+ char *end;
+ Val = strtod(buff.c_str(), &end);
+ if (*end != '\0')
+ return "invalid floating point number";
+ return StringRef();
+}
+
+void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
+ uint8_t Num = Val;
+ Out << format("0x%02X", Num);
+}
+
+StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid hex8 number";
+ if (n > 0xFF)
+ return "out of range hex8 number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
+ uint16_t Num = Val;
+ Out << format("0x%04X", Num);
+}
+
+StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid hex16 number";
+ if (n > 0xFFFF)
+ return "out of range hex16 number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
+ uint32_t Num = Val;
+ Out << format("0x%08X", Num);
+}
+
+StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 0, n))
+ return "invalid hex32 number";
+ if (n > 0xFFFFFFFFUL)
+ return "out of range hex32 number";
+ Val = n;
+ return StringRef();
+}
+
+void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
+ uint64_t Num = Val;
+ Out << format("0x%016llX", Num);
+}
+
+StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
+ unsigned long long Num;
+ if (getAsUnsignedInteger(Scalar, 0, Num))
+ return "invalid hex64 number";
+ Val = Num;
+ return StringRef();
+}
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 7cd5364..106864d 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -12,16 +12,16 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/Program.h"
-#include "llvm/Support/Process.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/system_error.h"
-#include "llvm/ADT/STLExtras.h"
#include <cctype>
#include <cerrno>
#include <sys/stat.h>
diff --git a/lib/Support/regcomp.c b/lib/Support/regcomp.c
index 46c91a9..74d9186 100644
--- a/lib/Support/regcomp.c
+++ b/lib/Support/regcomp.c
@@ -303,6 +303,7 @@ p_ere_exp(struct parse *p)
sopno pos;
int count;
int count2;
+ int backrefnum;
sopno subno;
int wascaret = 0;
@@ -370,7 +371,34 @@ p_ere_exp(struct parse *p)
case '\\':
REQUIRE(MORE(), REG_EESCAPE);
c = GETNEXT();
- ordinary(p, c);
+ if (c >= '1' && c <= '9') {
+ /* \[0-9] is taken to be a back-reference to a previously specified
+ * matching group. backrefnum will hold the number. The matching
+ * group must exist (i.e. if \4 is found there must have been at
+ * least 4 matching groups specified in the pattern previously).
+ */
+ backrefnum = c - '0';
+ if (p->pend[backrefnum] == 0) {
+ SETERROR(REG_ESUBREG);
+ break;
+ }
+
+ /* Make sure everything checks out and emit the sequence
+ * that marks a back-reference to the parse structure.
+ */
+ assert(backrefnum <= p->g->nsub);
+ EMIT(OBACK_, backrefnum);
+ assert(p->pbegin[backrefnum] != 0);
+ assert(OP(p->strip[p->pbegin[backrefnum]]) != OLPAREN);
+ assert(OP(p->strip[p->pend[backrefnum]]) != ORPAREN);
+ (void) dupl(p, p->pbegin[backrefnum]+1, p->pend[backrefnum]);
+ EMIT(O_BACK, backrefnum);
+ p->g->backrefs = 1;
+ } else {
+ /* Other chars are simply themselves when escaped with a backslash.
+ */
+ ordinary(p, c);
+ }
break;
case '{': /* okay as ordinary except if digit follows */
REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT);
diff --git a/lib/Support/system_error.cpp b/lib/Support/system_error.cpp
index 56898de..b22745a 100644
--- a/lib/Support/system_error.cpp
+++ b/lib/Support/system_error.cpp
@@ -13,8 +13,8 @@
#include "llvm/Support/system_error.h"
#include "llvm/Support/Errno.h"
-#include <string>
#include <cstring>
+#include <string>
namespace llvm {
@@ -48,8 +48,8 @@ _do_message::message(int ev) const {
class _generic_error_category : public _do_message {
public:
- virtual const char* name() const;
- virtual std::string message(int ev) const;
+ virtual const char* name() const LLVM_OVERRIDE;
+ virtual std::string message(int ev) const LLVM_OVERRIDE;
};
const char*
@@ -74,9 +74,9 @@ generic_category() {
class _system_error_category : public _do_message {
public:
- virtual const char* name() const;
- virtual std::string message(int ev) const;
- virtual error_condition default_error_condition(int ev) const;
+ virtual const char* name() const LLVM_OVERRIDE;
+ virtual std::string message(int ev) const LLVM_OVERRIDE;
+ virtual error_condition default_error_condition(int ev) const LLVM_OVERRIDE;
};
const char*