aboutsummaryrefslogtreecommitdiff
path: root/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp31
-rw-r--r--lib/Support/APInt.cpp56
-rw-r--r--lib/Support/Atomic.cpp10
-rw-r--r--lib/Support/BlockFrequency.cpp126
-rw-r--r--lib/Support/BranchProbability.cpp3
-rw-r--r--lib/Support/CMakeLists.txt4
-rw-r--r--lib/Support/CommandLine.cpp66
-rw-r--r--lib/Support/ConstantRange.cpp25
-rw-r--r--lib/Support/CrashRecoveryContext.cpp68
-rw-r--r--lib/Support/DataExtractor.cpp175
-rw-r--r--lib/Support/Disassembler.cpp2
-rw-r--r--lib/Support/Dwarf.cpp49
-rw-r--r--lib/Support/DynamicLibrary.cpp99
-rw-r--r--lib/Support/FoldingSet.cpp6
-rw-r--r--lib/Support/Host.cpp4
-rw-r--r--lib/Support/IncludeFile.cpp2
-rw-r--r--lib/Support/Memory.cpp6
-rw-r--r--lib/Support/MemoryBuffer.cpp8
-rw-r--r--lib/Support/MemoryObject.cpp7
-rw-r--r--lib/Support/Mutex.cpp2
-rw-r--r--lib/Support/Path.cpp2
-rw-r--r--lib/Support/PathV2.cpp36
-rw-r--r--lib/Support/PrettyStackTrace.cpp2
-rw-r--r--lib/Support/RWMutex.cpp2
-rw-r--r--lib/Support/SearchForAddressOfSpecialSymbol.cpp15
-rw-r--r--lib/Support/StringExtras.cpp9
-rw-r--r--lib/Support/StringRef.cpp19
-rw-r--r--lib/Support/TargetRegistry.cpp32
-rw-r--r--lib/Support/ThreadLocal.cpp2
-rw-r--r--lib/Support/Threading.cpp41
-rw-r--r--lib/Support/Triple.cpp44
-rw-r--r--lib/Support/Twine.cpp60
-rw-r--r--lib/Support/Unix/Host.inc1
-rw-r--r--lib/Support/Unix/Path.inc4
-rw-r--r--lib/Support/Unix/PathV2.inc22
-rw-r--r--lib/Support/Unix/Process.inc4
-rw-r--r--lib/Support/Windows/DynamicLibrary.inc76
-rw-r--r--lib/Support/Windows/Memory.inc57
-rw-r--r--lib/Support/Windows/PathV2.inc51
-rw-r--r--lib/Support/Windows/Process.inc5
-rw-r--r--lib/Support/Windows/RWMutex.inc98
-rw-r--r--lib/Support/Windows/Signals.inc224
-rw-r--r--lib/Support/Windows/Windows.h6
-rw-r--r--lib/Support/raw_ostream.cpp7
44 files changed, 1254 insertions, 314 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index c64da6e137ea..f2388944929b 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -832,6 +832,7 @@ APFloat::incrementSignificand()
/* Our callers should never cause us to overflow. */
assert(carry == 0);
+ (void)carry;
}
/* Add the significand of the RHS. Returns the carry flag. */
@@ -926,6 +927,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
APFloat extendedAddend(*addend);
status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
assert(status == opOK);
+ (void)status;
lost_fraction = addOrSubtractSignificand(extendedAddend, false);
/* Restore our state. */
@@ -1190,7 +1192,7 @@ APFloat::normalize(roundingMode rounding_mode,
if (omsb) {
/* OMSB is numbered from 1. We want to place it in the integer
- bit numbered PRECISON if possible, with a compensating change in
+ bit numbered PRECISION if possible, with a compensating change in
the exponent. */
exponentChange = omsb - semantics->precision;
@@ -1389,6 +1391,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
/* The code above is intended to ensure that no borrow is
necessary. */
assert(!carry);
+ (void)carry;
} else {
if (bits > 0) {
APFloat temp_rhs(rhs);
@@ -1402,6 +1405,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
/* We have a guard bit; generating a carry cannot happen. */
assert(!carry);
+ (void)carry;
}
return lost_fraction;
@@ -2098,7 +2102,7 @@ APFloat::convertToInteger(APSInt &result,
opStatus status = convertToInteger(
parts.data(), bitWidth, result.isSigned(), rounding_mode, isExact);
// Keeps the original signed-ness.
- result = APInt(bitWidth, (unsigned)parts.size(), parts.data());
+ result = APInt(bitWidth, parts);
return status;
}
@@ -2121,7 +2125,7 @@ APFloat::convertFromUnsignedParts(const integerPart *src,
dstCount = partCount();
precision = semantics->precision;
- /* We want the most significant PRECISON bits of SRC. There may not
+ /* We want the most significant PRECISION bits of SRC. There may not
be that many; extract what we can. */
if (precision <= omsb) {
exponent = omsb - 1;
@@ -2192,7 +2196,7 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
roundingMode rounding_mode)
{
unsigned int partCount = partCountForBits(width);
- APInt api = APInt(width, partCount, parts);
+ APInt api = APInt(width, makeArrayRef(parts, partCount));
sign = false;
if (isSigned && APInt::tcExtractBit(parts, width - 1)) {
@@ -2746,7 +2750,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const
words[0] = mysignificand;
words[1] = ((uint64_t)(sign & 1) << 15) |
(myexponent & 0x7fffLL);
- return APInt(80, 2, words);
+ return APInt(80, words);
}
APInt
@@ -2791,7 +2795,7 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
words[1] = ((uint64_t)(sign2 & 1) << 63) |
((myexponent2 & 0x7ff) << 52) |
(mysignificand2 & 0xfffffffffffffLL);
- return APInt(128, 2, words);
+ return APInt(128, words);
}
APInt
@@ -2827,7 +2831,7 @@ APFloat::convertQuadrupleAPFloatToAPInt() const
((myexponent & 0x7fff) << 48) |
(mysignificand2 & 0xffffffffffffLL);
- return APInt(128, 2, words);
+ return APInt(128, words);
}
APInt
@@ -3239,8 +3243,9 @@ APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) {
significand[i] = ~((integerPart) 0);
// ...and then clear the top bits for internal consistency.
- significand[N-1] &=
- (((integerPart) 1) << ((Sem.precision % integerPartWidth) - 1)) - 1;
+ if (Sem.precision % integerPartWidth != 0)
+ significand[N-1] &=
+ (((integerPart) 1) << (Sem.precision % integerPartWidth)) - 1;
return Val;
}
@@ -3270,7 +3275,7 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
Val.exponent = Sem.minExponent;
Val.zeroSignificand();
Val.significandParts()[partCountForBits(Sem.precision)-1] |=
- (((integerPart) 1) << ((Sem.precision % integerPartWidth) - 1));
+ (((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth));
return Val;
}
@@ -3413,8 +3418,8 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
// Decompose the number into an APInt and an exponent.
int exp = exponent - ((int) semantics->precision - 1);
APInt significand(semantics->precision,
- partCountForBits(semantics->precision),
- significandParts());
+ makeArrayRef(significandParts(),
+ partCountForBits(semantics->precision)));
// Set FormatPrecision if zero. We want to do this before we
// truncate trailing zeros, as those are part of the precision.
@@ -3451,7 +3456,7 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
// <= semantics->precision + e * 137 / 59
// (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59)
- unsigned precision = semantics->precision + 137 * texp / 59;
+ unsigned precision = semantics->precision + (137 * texp + 136) / 59;
// Multiply significand by 5^e.
// N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 76265d445f45..3774c5223c46 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -48,18 +48,20 @@ inline static uint64_t* getMemory(unsigned numWords) {
inline static unsigned getDigit(char cdigit, uint8_t radix) {
unsigned r;
- if (radix == 16) {
+ if (radix == 16 || radix == 36) {
r = cdigit - '0';
if (r <= 9)
return r;
r = cdigit - 'A';
- if (r <= 5)
+ if (r <= radix - 11U)
return r + 10;
r = cdigit - 'a';
- if (r <= 5)
+ if (r <= radix - 11U)
return r + 10;
+
+ radix = 10;
}
r = cdigit - '0';
@@ -83,25 +85,33 @@ void APInt::initSlowCase(const APInt& that) {
memcpy(pVal, that.pVal, getNumWords() * APINT_WORD_SIZE);
}
-
-APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[])
- : BitWidth(numBits), VAL(0) {
+void APInt::initFromArray(ArrayRef<uint64_t> bigVal) {
assert(BitWidth && "Bitwidth too small");
- assert(bigVal && "Null pointer detected!");
+ assert(bigVal.data() && "Null pointer detected!");
if (isSingleWord())
VAL = bigVal[0];
else {
// Get memory, cleared to 0
pVal = getClearedMemory(getNumWords());
// Calculate the number of words to copy
- unsigned words = std::min<unsigned>(numWords, getNumWords());
+ unsigned words = std::min<unsigned>(bigVal.size(), getNumWords());
// Copy the words from bigVal to pVal
- memcpy(pVal, bigVal, words * APINT_WORD_SIZE);
+ memcpy(pVal, bigVal.data(), words * APINT_WORD_SIZE);
}
// Make sure unused high bits are cleared
clearUnusedBits();
}
+APInt::APInt(unsigned numBits, ArrayRef<uint64_t> bigVal)
+ : BitWidth(numBits), VAL(0) {
+ initFromArray(bigVal);
+}
+
+APInt::APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[])
+ : BitWidth(numBits), VAL(0) {
+ initFromArray(makeArrayRef(bigVal, numWords));
+}
+
APInt::APInt(unsigned numbits, StringRef Str, uint8_t radix)
: BitWidth(numbits), VAL(0) {
assert(BitWidth && "Bitwidth too small");
@@ -376,6 +386,7 @@ APInt& APInt::operator*=(const APInt& RHS) {
clearAllBits();
unsigned wordsToCopy = destWords >= getNumWords() ? getNumWords() : destWords;
memcpy(pVal, dest, wordsToCopy * APINT_WORD_SIZE);
+ clearUnusedBits();
// delete dest array and return
delete[] dest;
@@ -461,7 +472,7 @@ APInt APInt::operator*(const APInt& RHS) const {
return APInt(BitWidth, VAL * RHS.VAL);
APInt Result(*this);
Result *= RHS;
- return Result.clearUnusedBits();
+ return Result;
}
APInt APInt::operator+(const APInt& RHS) const {
@@ -613,8 +624,9 @@ void APInt::flipBit(unsigned bitPosition) {
unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) {
assert(!str.empty() && "Invalid string length");
- assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
- "Radix should be 2, 8, 10, or 16!");
+ assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 ||
+ radix == 36) &&
+ "Radix should be 2, 8, 10, 16, or 36!");
size_t slen = str.size();
@@ -636,6 +648,8 @@ unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) {
if (radix == 16)
return slen * 4 + isNegative;
+ // FIXME: base 36
+
// This is grossly inefficient but accurate. We could probably do something
// with a computation of roughly slen*64/20 and then adjust by the value of
// the first few digits. But, I'm not sure how accurate that could be.
@@ -644,7 +658,9 @@ unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) {
// be too large. This avoids the assertion in the constructor. This
// calculation doesn't work appropriately for the numbers 0-9, so just use 4
// bits in that case.
- unsigned sufficient = slen == 1 ? 4 : slen * 64/18;
+ unsigned sufficient
+ = radix == 10? (slen == 1 ? 4 : slen * 64/18)
+ : (slen == 1 ? 7 : slen * 16/3);
// Convert to the actual binary value.
APInt tmp(sufficient, StringRef(p, slen), radix);
@@ -2107,8 +2123,9 @@ APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) const {
void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
// Check our assumptions here
assert(!str.empty() && "Invalid string length");
- assert((radix == 10 || radix == 8 || radix == 16 || radix == 2) &&
- "Radix should be 2, 8, 10, or 16!");
+ assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 ||
+ radix == 36) &&
+ "Radix should be 2, 8, 10, 16, or 36!");
StringRef::iterator p = str.begin();
size_t slen = str.size();
@@ -2165,7 +2182,8 @@ void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) {
void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
bool Signed, bool formatAsCLiteral) const {
- assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2) &&
+ assert((Radix == 10 || Radix == 8 || Radix == 16 || Radix == 2 ||
+ Radix == 36) &&
"Radix should be 2, 8, 10, or 16!");
const char *Prefix = "";
@@ -2195,7 +2213,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
return;
}
- static const char Digits[] = "0123456789ABCDEF";
+ static const char Digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (isSingleWord()) {
char Buffer[65];
@@ -2249,7 +2267,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
// For the 2, 8 and 16 bit cases, we can just shift instead of divide
// because the number of bits per digit (1, 3 and 4 respectively) divides
// equaly. We just shift until the value is zero.
- if (Radix != 10) {
+ if (Radix == 2 || Radix == 8 || Radix == 16) {
// Just shift tmp right for each digit width until it becomes zero
unsigned ShiftAmt = (Radix == 16 ? 4 : (Radix == 8 ? 3 : 1));
unsigned MaskAmt = Radix - 1;
@@ -2260,7 +2278,7 @@ void APInt::toString(SmallVectorImpl<char> &Str, unsigned Radix,
Tmp = Tmp.lshr(ShiftAmt);
}
} else {
- APInt divisor(4, 10);
+ APInt divisor(Radix == 10? 4 : 8, Radix);
while (Tmp != 0) {
APInt APdigit(1, 0);
APInt tmp2(Tmp.getBitWidth(), 0);
diff --git a/lib/Support/Atomic.cpp b/lib/Support/Atomic.cpp
index c7b4bff27948..94760cc069fc 100644
--- a/lib/Support/Atomic.cpp
+++ b/lib/Support/Atomic.cpp
@@ -22,7 +22,7 @@ using namespace llvm;
#endif
void sys::MemoryFence() {
-#if LLVM_MULTITHREADED==0
+#if LLVM_HAS_ATOMICS == 0
return;
#else
# if defined(__GNUC__)
@@ -38,7 +38,7 @@ void sys::MemoryFence() {
sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
sys::cas_flag new_value,
sys::cas_flag old_value) {
-#if LLVM_MULTITHREADED==0
+#if LLVM_HAS_ATOMICS == 0
sys::cas_flag result = *ptr;
if (result == old_value)
*ptr = new_value;
@@ -53,7 +53,7 @@ sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
}
sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) {
-#if LLVM_MULTITHREADED==0
+#if LLVM_HAS_ATOMICS == 0
++(*ptr);
return *ptr;
#elif defined(__GNUC__)
@@ -66,7 +66,7 @@ sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) {
}
sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) {
-#if LLVM_MULTITHREADED==0
+#if LLVM_HAS_ATOMICS == 0
--(*ptr);
return *ptr;
#elif defined(__GNUC__)
@@ -79,7 +79,7 @@ sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) {
}
sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) {
-#if LLVM_MULTITHREADED==0
+#if LLVM_HAS_ATOMICS == 0
*ptr += val;
return *ptr;
#elif defined(__GNUC__)
diff --git a/lib/Support/BlockFrequency.cpp b/lib/Support/BlockFrequency.cpp
new file mode 100644
index 000000000000..a63bf83f2039
--- /dev/null
+++ b/lib/Support/BlockFrequency.cpp
@@ -0,0 +1,126 @@
+//====--------------- lib/Support/BlockFrequency.cpp -----------*- C++ -*-====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements Block Frequency class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/BlockFrequency.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+using namespace llvm;
+
+namespace {
+
+/// mult96bit - Multiply FREQ by N and store result in W array.
+void mult96bit(uint64_t freq, uint32_t N, uint64_t W[2]) {
+ uint64_t u0 = freq & UINT32_MAX;
+ uint64_t u1 = freq >> 32;
+
+ // Represent 96-bit value as w[2]:w[1]:w[0];
+ uint32_t w[3] = { 0, 0, 0 };
+
+ uint64_t t = u0 * N;
+ uint64_t k = t >> 32;
+ w[0] = t;
+ t = u1 * N + k;
+ w[1] = t;
+ w[2] = t >> 32;
+
+ // W[1] - higher bits.
+ // W[0] - lower bits.
+ W[0] = w[0] + ((uint64_t) w[1] << 32);
+ W[1] = w[2];
+}
+
+
+/// div96bit - Divide 96-bit value stored in W array by D. Return 64-bit frequency.
+uint64_t div96bit(uint64_t W[2], uint32_t D) {
+ uint64_t y = W[0];
+ uint64_t x = W[1];
+ int i;
+
+ for (i = 1; i <= 64 && x; ++i) {
+ uint32_t t = (int)x >> 31;
+ x = (x << 1) | (y >> 63);
+ y = y << 1;
+ if ((x | t) >= D) {
+ x -= D;
+ ++y;
+ }
+ }
+
+ return y << (64 - i + 1);
+}
+
+}
+
+
+BlockFrequency &BlockFrequency::operator*=(const BranchProbability &Prob) {
+ uint32_t n = Prob.getNumerator();
+ uint32_t d = Prob.getDenominator();
+
+ assert(n <= d && "Probability must be less or equal to 1.");
+
+ // If we can overflow use 96-bit operations.
+ if (n > 0 && Frequency > UINT64_MAX / n) {
+ // 96-bit value represented as W[1]:W[0].
+ uint64_t W[2];
+
+ // Probability is less or equal to 1 which means that results must fit
+ // 64-bit.
+ mult96bit(Frequency, n, W);
+ Frequency = div96bit(W, d);
+ return *this;
+ }
+
+ Frequency *= n;
+ Frequency /= d;
+ return *this;
+}
+
+const BlockFrequency
+BlockFrequency::operator*(const BranchProbability &Prob) const {
+ BlockFrequency Freq(Frequency);
+ Freq *= Prob;
+ return Freq;
+}
+
+BlockFrequency &BlockFrequency::operator+=(const BlockFrequency &Freq) {
+ uint64_t Before = Freq.Frequency;
+ Frequency += Freq.Frequency;
+
+ // If overflow, set frequency to the maximum value.
+ if (Frequency < Before)
+ Frequency = UINT64_MAX;
+
+ return *this;
+}
+
+const BlockFrequency
+BlockFrequency::operator+(const BlockFrequency &Prob) const {
+ BlockFrequency Freq(Frequency);
+ Freq += Prob;
+ return Freq;
+}
+
+void BlockFrequency::print(raw_ostream &OS) const {
+ OS << Frequency;
+}
+
+namespace llvm {
+
+raw_ostream &operator<<(raw_ostream &OS, const BlockFrequency &Freq) {
+ Freq.print(OS);
+ return OS;
+}
+
+}
diff --git a/lib/Support/BranchProbability.cpp b/lib/Support/BranchProbability.cpp
index 97342da3f078..49d04ed83653 100644
--- a/lib/Support/BranchProbability.cpp
+++ b/lib/Support/BranchProbability.cpp
@@ -24,9 +24,8 @@ BranchProbability::BranchProbability(uint32_t n, uint32_t d) {
D = d;
}
-raw_ostream &BranchProbability::print(raw_ostream &OS) const {
+void BranchProbability::print(raw_ostream &OS) const {
OS << N << " / " << D << " = " << ((double)N / D);
- return OS;
}
void BranchProbability::dump() const {
diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt
index 867d930a0f9b..63a833c38046 100644
--- a/lib/Support/CMakeLists.txt
+++ b/lib/Support/CMakeLists.txt
@@ -9,11 +9,13 @@ add_llvm_library(LLVMSupport
APInt.cpp
APSInt.cpp
Allocator.cpp
+ BlockFrequency.cpp
BranchProbability.cpp
circular_raw_ostream.cpp
CommandLine.cpp
ConstantRange.cpp
CrashRecoveryContext.cpp
+ DataExtractor.cpp
Debug.cpp
DeltaAlgorithm.cpp
DAGDeltaAlgorithm.cpp
@@ -42,7 +44,6 @@ add_llvm_library(LLVMSupport
StringPool.cpp
StringRef.cpp
SystemUtils.cpp
- TargetRegistry.cpp
Timer.cpp
ToolOutputFile.cpp
Triple.cpp
@@ -72,6 +73,7 @@ add_llvm_library(LLVMSupport
SearchForAddressOfSpecialSymbol.cpp
Signals.cpp
system_error.cpp
+ TargetRegistry.cpp
ThreadLocal.cpp
Threading.cpp
TimeValue.cpp
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 29143377628d..238adcce0a12 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -23,7 +23,6 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Target/TargetRegistry.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/ADT/OwningPtr.h"
@@ -45,6 +44,7 @@ TEMPLATE_INSTANTIATION(class basic_parser<bool>);
TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
TEMPLATE_INSTANTIATION(class basic_parser<int>);
TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
TEMPLATE_INSTANTIATION(class basic_parser<double>);
TEMPLATE_INSTANTIATION(class basic_parser<float>);
TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
@@ -63,6 +63,7 @@ void parser<bool>::anchor() {}
void parser<boolOrDefault>::anchor() {}
void parser<int>::anchor() {}
void parser<unsigned>::anchor() {}
+void parser<unsigned long long>::anchor() {}
void parser<double>::anchor() {}
void parser<float>::anchor() {}
void parser<std::string>::anchor() {}
@@ -1006,6 +1007,16 @@ bool parser<unsigned>::parse(Option &O, StringRef ArgName,
return false;
}
+// parser<unsigned long long> implementation
+//
+bool parser<unsigned long long>::parse(Option &O, StringRef ArgName,
+ StringRef Arg, unsigned long long &Value){
+
+ if (Arg.getAsInteger(0, Value))
+ return O.error("'" + Arg + "' value invalid for uint argument!");
+ return false;
+}
+
// parser<double>/parser<float> implementation
//
static bool parseDouble(Option &O, StringRef Arg, double &Value) {
@@ -1151,6 +1162,7 @@ PRINT_OPT_DIFF(bool)
PRINT_OPT_DIFF(boolOrDefault)
PRINT_OPT_DIFF(int)
PRINT_OPT_DIFF(unsigned)
+PRINT_OPT_DIFF(unsigned long long)
PRINT_OPT_DIFF(double)
PRINT_OPT_DIFF(float)
PRINT_OPT_DIFF(char)
@@ -1330,10 +1342,7 @@ void cl::PrintOptionValues() {
static void (*OverrideVersionPrinter)() = 0;
-static int TargetArraySortFn(const void *LHS, const void *RHS) {
- typedef std::pair<const char *, const Target*> pair_ty;
- return strcmp(((const pair_ty*)LHS)->first, ((const pair_ty*)RHS)->first);
-}
+static std::vector<void (*)()>* ExtraVersionPrinters = 0;
namespace {
class VersionPrinter {
@@ -1361,37 +1370,27 @@ public:
<< " Built " << __DATE__ << " (" << __TIME__ << ").\n"
#endif
<< " Host: " << sys::getHostTriple() << '\n'
- << " Host CPU: " << CPU << '\n'
- << '\n'
- << " Registered Targets:\n";
-
- std::vector<std::pair<const char *, const Target*> > Targets;
- size_t Width = 0;
- for (TargetRegistry::iterator it = TargetRegistry::begin(),
- ie = TargetRegistry::end(); it != ie; ++it) {
- Targets.push_back(std::make_pair(it->getName(), &*it));
- Width = std::max(Width, strlen(Targets.back().first));
- }
- if (!Targets.empty())
- qsort(&Targets[0], Targets.size(), sizeof(Targets[0]),
- TargetArraySortFn);
-
- for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
- OS << " " << Targets[i].first;
- OS.indent(Width - strlen(Targets[i].first)) << " - "
- << Targets[i].second->getShortDescription() << '\n';
- }
- if (Targets.empty())
- OS << " (none)\n";
+ << " Host CPU: " << CPU << '\n';
}
void operator=(bool OptionWasSpecified) {
if (!OptionWasSpecified) return;
- if (OverrideVersionPrinter == 0) {
- print();
+ if (OverrideVersionPrinter != 0) {
+ (*OverrideVersionPrinter)();
exit(1);
}
- (*OverrideVersionPrinter)();
+ print();
+
+ // Iterate over any registered extra printers and call them to add further
+ // information.
+ if (ExtraVersionPrinters != 0) {
+ outs() << '\n';
+ for (std::vector<void (*)()>::iterator I = ExtraVersionPrinters->begin(),
+ E = ExtraVersionPrinters->end();
+ I != E; ++I)
+ (*I)();
+ }
+
exit(1);
}
};
@@ -1424,3 +1423,10 @@ void cl::PrintVersionMessage() {
void cl::SetVersionPrinter(void (*func)()) {
OverrideVersionPrinter = func;
}
+
+void cl::AddExtraVersionPrinter(void (*func)()) {
+ if (ExtraVersionPrinters == 0)
+ ExtraVersionPrinters = new std::vector<void (*)()>;
+
+ ExtraVersionPrinters->push_back(func);
+}
diff --git a/lib/Support/ConstantRange.cpp b/lib/Support/ConstantRange.cpp
index 81382d08dc23..c29cb53fb9c5 100644
--- a/lib/Support/ConstantRange.cpp
+++ b/lib/Support/ConstantRange.cpp
@@ -21,11 +21,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Constants.h"
+#include "llvm/InstrTypes.h"
#include "llvm/Support/ConstantRange.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Instructions.h"
using namespace llvm;
/// Initialize a full (the default) or empty set for the specified type.
@@ -56,56 +55,56 @@ ConstantRange ConstantRange::makeICmpRegion(unsigned Pred,
uint32_t W = CR.getBitWidth();
switch (Pred) {
- default: assert(!"Invalid ICmp predicate to makeICmpRegion()");
- case ICmpInst::ICMP_EQ:
+ default: assert(0 && "Invalid ICmp predicate to makeICmpRegion()");
+ case CmpInst::ICMP_EQ:
return CR;
- case ICmpInst::ICMP_NE:
+ case CmpInst::ICMP_NE:
if (CR.isSingleElement())
return ConstantRange(CR.getUpper(), CR.getLower());
return ConstantRange(W);
- case ICmpInst::ICMP_ULT: {
+ case CmpInst::ICMP_ULT: {
APInt UMax(CR.getUnsignedMax());
if (UMax.isMinValue())
return ConstantRange(W, /* empty */ false);
return ConstantRange(APInt::getMinValue(W), UMax);
}
- case ICmpInst::ICMP_SLT: {
+ case CmpInst::ICMP_SLT: {
APInt SMax(CR.getSignedMax());
if (SMax.isMinSignedValue())
return ConstantRange(W, /* empty */ false);
return ConstantRange(APInt::getSignedMinValue(W), SMax);
}
- case ICmpInst::ICMP_ULE: {
+ case CmpInst::ICMP_ULE: {
APInt UMax(CR.getUnsignedMax());
if (UMax.isMaxValue())
return ConstantRange(W);
return ConstantRange(APInt::getMinValue(W), UMax + 1);
}
- case ICmpInst::ICMP_SLE: {
+ case CmpInst::ICMP_SLE: {
APInt SMax(CR.getSignedMax());
if (SMax.isMaxSignedValue())
return ConstantRange(W);
return ConstantRange(APInt::getSignedMinValue(W), SMax + 1);
}
- case ICmpInst::ICMP_UGT: {
+ case CmpInst::ICMP_UGT: {
APInt UMin(CR.getUnsignedMin());
if (UMin.isMaxValue())
return ConstantRange(W, /* empty */ false);
return ConstantRange(UMin + 1, APInt::getNullValue(W));
}
- case ICmpInst::ICMP_SGT: {
+ case CmpInst::ICMP_SGT: {
APInt SMin(CR.getSignedMin());
if (SMin.isMaxSignedValue())
return ConstantRange(W, /* empty */ false);
return ConstantRange(SMin + 1, APInt::getSignedMinValue(W));
}
- case ICmpInst::ICMP_UGE: {
+ case CmpInst::ICMP_UGE: {
APInt UMin(CR.getUnsignedMin());
if (UMin.isMinValue())
return ConstantRange(W);
return ConstantRange(UMin, APInt::getNullValue(W));
}
- case ICmpInst::ICMP_SGE: {
+ case CmpInst::ICMP_SGE: {
APInt SMin(CR.getSignedMin());
if (SMin.isMinSignedValue())
return ConstantRange(W);
diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp
index 899c3890d78a..263114c06f98 100644
--- a/lib/Support/CrashRecoveryContext.cpp
+++ b/lib/Support/CrashRecoveryContext.cpp
@@ -12,6 +12,7 @@
#include "llvm/Config/config.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/ThreadLocal.h"
+#include "llvm/Support/ErrorHandling.h"
#include <setjmp.h>
#include <cstdio>
using namespace llvm;
@@ -123,7 +124,56 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) {
#ifdef LLVM_ON_WIN32
-// FIXME: No real Win32 implementation currently.
+#include "Windows/Windows.h"
+
+// On Windows, we can make use of vectored exception handling to
+// catch most crashing situations. Note that this does mean
+// we will be alerted of exceptions *before* structured exception
+// handling has the opportunity to catch it. But that isn't likely
+// to cause problems because nowhere in the project is SEH being
+// used.
+//
+// Vectored exception handling is built on top of SEH, and so it
+// works on a per-thread basis.
+//
+// The vectored exception handler functionality was added in Windows
+// XP, so if support for older versions of Windows is required,
+// it will have to be added.
+//
+// If we want to support as far back as Win2k, we could use the
+// SetUnhandledExceptionFilter API, but there's a risk of that
+// being entirely overwritten (it's not a chain).
+
+static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
+{
+ // Lookup the current thread local recovery object.
+ const CrashRecoveryContextImpl *CRCI = CurrentContext.get();
+
+ if (!CRCI) {
+ // Something has gone horribly wrong, so let's just tell everyone
+ // to keep searching
+ CrashRecoveryContext::Disable();
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ // TODO: We can capture the stack backtrace here and store it on the
+ // implementation if we so choose.
+
+ // Handle the crash
+ const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash();
+
+ // Note that we don't actually get here because HandleCrash calls
+ // longjmp, which means the HandleCrash function never returns.
+ llvm_unreachable("Handled the crash, should have longjmp'ed out of here");
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+// Because the Enable and Disable calls are static, it means that
+// there may not actually be an Impl available, or even a current
+// CrashRecoveryContext at all. So we make use of a thread-local
+// exception table. The handles contained in here will either be
+// non-NULL, valid VEH handles, or NULL.
+static sys::ThreadLocal<const void> sCurrentExceptionHandle;
void CrashRecoveryContext::Enable() {
sys::ScopedLock L(gCrashRecoveryContexMutex);
@@ -132,6 +182,13 @@ void CrashRecoveryContext::Enable() {
return;
gCrashRecoveryEnabled = true;
+
+ // We can set up vectored exception handling now. We will install our
+ // handler as the front of the list, though there's no assurances that
+ // it will remain at the front (another call could install itself before
+ // our handler). This 1) isn't likely, and 2) shouldn't cause problems.
+ PVOID handle = ::AddVectoredExceptionHandler(1, ExceptionHandler);
+ sCurrentExceptionHandle.set(handle);
}
void CrashRecoveryContext::Disable() {
@@ -141,6 +198,15 @@ void CrashRecoveryContext::Disable() {
return;
gCrashRecoveryEnabled = false;
+
+ PVOID currentHandle = const_cast<PVOID>(sCurrentExceptionHandle.get());
+ if (currentHandle) {
+ // Now we can remove the vectored exception handler from the chain
+ ::RemoveVectoredExceptionHandler(currentHandle);
+
+ // Reset the handle in our thread-local set.
+ sCurrentExceptionHandle.set(NULL);
+ }
}
#else
diff --git a/lib/Support/DataExtractor.cpp b/lib/Support/DataExtractor.cpp
new file mode 100644
index 000000000000..b946c1df8363
--- /dev/null
+++ b/lib/Support/DataExtractor.cpp
@@ -0,0 +1,175 @@
+//===-- DataExtractor.cpp -------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
+using namespace llvm;
+
+template <typename T>
+static T getU(uint32_t *offset_ptr, const DataExtractor *de,
+ bool isLittleEndian, const char *Data) {
+ T val = 0;
+ uint32_t offset = *offset_ptr;
+ if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
+ std::memcpy(&val, &Data[offset], sizeof(val));
+ if (sys::isLittleEndianHost() != isLittleEndian)
+ val = sys::SwapByteOrder(val);
+
+ // Advance the offset
+ *offset_ptr += sizeof(val);
+ }
+ return val;
+}
+
+template <typename T>
+static T *getUs(uint32_t *offset_ptr, T *dst, uint32_t count,
+ const DataExtractor *de, bool isLittleEndian, const char *Data){
+ uint32_t offset = *offset_ptr;
+
+ if (count > 0 && de->isValidOffsetForDataOfSize(offset, sizeof(*dst)*count)) {
+ for (T *value_ptr = dst, *end = dst + count; value_ptr != end;
+ ++value_ptr, offset += sizeof(*dst))
+ *value_ptr = getU<T>(offset_ptr, de, isLittleEndian, Data);
+ // Advance the offset
+ *offset_ptr = offset;
+ // Return a non-NULL pointer to the converted data as an indicator of
+ // success
+ return dst;
+ }
+ return NULL;
+}
+
+uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const {
+ return getU<uint8_t>(offset_ptr, this, IsLittleEndian, Data.data());
+}
+
+uint8_t *
+DataExtractor::getU8(uint32_t *offset_ptr, uint8_t *dst, uint32_t count) const {
+ return getUs<uint8_t>(offset_ptr, dst, count, this, IsLittleEndian,
+ Data.data());
+}
+
+
+uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const {
+ return getU<uint16_t>(offset_ptr, this, IsLittleEndian, Data.data());
+}
+
+uint16_t *DataExtractor::getU16(uint32_t *offset_ptr, uint16_t *dst,
+ uint32_t count) const {
+ return getUs<uint16_t>(offset_ptr, dst, count, this, IsLittleEndian,
+ Data.data());
+}
+
+uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const {
+ return getU<uint32_t>(offset_ptr, this, IsLittleEndian, Data.data());
+}
+
+uint32_t *DataExtractor::getU32(uint32_t *offset_ptr, uint32_t *dst,
+ uint32_t count) const {
+ return getUs<uint32_t>(offset_ptr, dst, count, this, IsLittleEndian,
+ Data.data());;
+}
+
+uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const {
+ return getU<uint64_t>(offset_ptr, this, IsLittleEndian, Data.data());
+}
+
+uint64_t *DataExtractor::getU64(uint32_t *offset_ptr, uint64_t *dst,
+ uint32_t count) const {
+ return getUs<uint64_t>(offset_ptr, dst, count, this, IsLittleEndian,
+ Data.data());
+}
+
+uint64_t
+DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const {
+ switch (byte_size) {
+ case 1:
+ return getU8(offset_ptr);
+ case 2:
+ return getU16(offset_ptr);
+ case 4:
+ return getU32(offset_ptr);
+ case 8:
+ return getU64(offset_ptr);
+ }
+ llvm_unreachable("getUnsigned unhandled case!");
+}
+
+int64_t
+DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const {
+ switch (byte_size) {
+ case 1:
+ return (int8_t)getU8(offset_ptr);
+ case 2:
+ return (int16_t)getU16(offset_ptr);
+ case 4:
+ return (int32_t)getU32(offset_ptr);
+ case 8:
+ return (int64_t)getU64(offset_ptr);
+ }
+ llvm_unreachable("getSigned unhandled case!");
+}
+
+const char *DataExtractor::getCStr(uint32_t *offset_ptr) const {
+ uint32_t offset = *offset_ptr;
+ StringRef::size_type pos = Data.find('\0', offset);
+ if (pos != StringRef::npos) {
+ *offset_ptr = pos + 1;
+ return Data.data() + offset;
+ }
+ return NULL;
+}
+
+uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const {
+ uint64_t result = 0;
+ if (Data.empty())
+ return 0;
+
+ unsigned shift = 0;
+ uint32_t offset = *offset_ptr;
+ uint8_t byte = 0;
+
+ while (isValidOffset(offset)) {
+ byte = Data[offset++];
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
+ }
+
+ *offset_ptr = offset;
+ return result;
+}
+
+int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const {
+ int64_t result = 0;
+ if (Data.empty())
+ return 0;
+
+ unsigned shift = 0;
+ uint32_t offset = *offset_ptr;
+ uint8_t byte = 0;
+
+ while (isValidOffset(offset)) {
+ byte = Data[offset++];
+ result |= (byte & 0x7f) << shift;
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
+ }
+
+ // Sign bit of byte is 2nd high order bit (0x40)
+ if (shift < 64 && (byte & 0x40))
+ result |= -(1 << shift);
+
+ *offset_ptr = offset;
+ return result;
+}
diff --git a/lib/Support/Disassembler.cpp b/lib/Support/Disassembler.cpp
index 6362aff43a9d..c6d73bcad3e4 100644
--- a/lib/Support/Disassembler.cpp
+++ b/lib/Support/Disassembler.cpp
@@ -1,4 +1,4 @@
-//===- lib/System/Disassembler.cpp ------------------------------*- C++ -*-===//
+//===- lib/Support/Disassembler.cpp -----------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp
index 0813321b6f79..95a9550f9663 100644
--- a/lib/Support/Dwarf.cpp
+++ b/lib/Support/Dwarf.cpp
@@ -82,6 +82,19 @@ const char *llvm::dwarf::TagString(unsigned Tag) {
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";
+ case DW_TAG_type_unit: return "DW_TAG_type_unit";
+ case DW_TAG_format_label: return "DW_TAG_format_label";
+ case DW_TAG_function_template: return "DW_TAG_function_template";
+ case DW_TAG_class_template: return "DW_TAG_class_template";
+ case DW_TAG_GNU_template_template_param:
+ return "DW_TAG_GNU_template_template_param";
+ case DW_TAG_GNU_template_parameter_pack:
+ return "DW_TAG_GNU_template_parameter_pack";
+ case DW_TAG_GNU_formal_parameter_pack:
+ return "DW_TAG_GNU_formal_parameter_pack";
}
return 0;
}
@@ -186,7 +199,30 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) {
case DW_AT_elemental: return "DW_AT_elemental";
case DW_AT_pure: return "DW_AT_pure";
case DW_AT_recursive: return "DW_AT_recursive";
+ case DW_AT_signature: return "DW_AT_signature";
+ case DW_AT_main_subprogram: return "DW_AT_main_subprogram";
+ case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset";
+ case DW_AT_const_expr: return "DW_AT_const_expr";
+ case DW_AT_enum_class: return "DW_AT_enum_class";
+ case DW_AT_linkage_name: return "DW_AT_linkage_name";
+ case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
+ case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
+ case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
+ case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
+ case DW_AT_MIPS_software_pipeline_depth:
+ return "DW_AT_MIPS_software_pipeline_depth";
case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
+ case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
+ case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
+ case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
+ case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
+ case DW_AT_MIPS_stride_byte: return "DW_AT_MIPS_stride_byte";
+ case DW_AT_MIPS_stride_elem: return "DW_AT_MIPS_stride_elem";
+ case DW_AT_MIPS_ptr_dopetype: return "DW_AT_MIPS_ptr_dopetype";
+ case DW_AT_MIPS_allocatable_dopetype:
+ return "DW_AT_MIPS_allocatable_dopetype";
+ case DW_AT_MIPS_assumed_shape_dopetype:
+ return "DW_AT_MIPS_assumed_shape_dopetype";
case DW_AT_sf_names: return "DW_AT_sf_names";
case DW_AT_src_info: return "DW_AT_src_info";
case DW_AT_mac_info: return "DW_AT_mac_info";
@@ -194,6 +230,8 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) {
case DW_AT_body_begin: return "DW_AT_body_begin";
case DW_AT_body_end: return "DW_AT_body_end";
case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
+ case DW_AT_GNU_template_name: return "DW_AT_GNU_template_name";
+ case DW_AT_MIPS_assumed_size: return "DW_AT_MIPS_assumed_size";
case DW_AT_lo_user: return "DW_AT_lo_user";
case DW_AT_hi_user: return "DW_AT_hi_user";
case DW_AT_APPLE_optimized: return "DW_AT_APPLE_optimized";
@@ -237,6 +275,10 @@ const char *llvm::dwarf::FormEncodingString(unsigned Encoding) {
case DW_FORM_ref8: return "DW_FORM_ref8";
case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
case DW_FORM_indirect: return "DW_FORM_indirect";
+ case DW_FORM_sec_offset: return "DW_FORM_sec_offset";
+ case DW_FORM_exprloc: return "DW_FORM_exprloc";
+ case DW_FORM_flag_present: return "DW_FORM_flag_present";
+ case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8";
}
return 0;
}
@@ -397,6 +439,8 @@ const char *llvm::dwarf::OperationEncodingString(unsigned Encoding) {
case DW_OP_form_tls_address: return "DW_OP_form_tls_address";
case DW_OP_call_frame_cfa: return "DW_OP_call_frame_cfa";
case DW_OP_bit_piece: return "DW_OP_bit_piece";
+ case DW_OP_implicit_value: return "DW_OP_implicit_value";
+ 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";
}
@@ -416,6 +460,7 @@ const char *llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
case DW_ATE_unsigned: return "DW_ATE_unsigned";
case DW_ATE_unsigned_char: return "DW_ATE_unsigned_char";
case DW_ATE_imaginary_float: return "DW_ATE_imaginary_float";
+ case DW_ATE_UTF: return "DW_ATE_UTF";
case DW_ATE_packed_decimal: return "DW_ATE_packed_decimal";
case DW_ATE_numeric_string: return "DW_ATE_numeric_string";
case DW_ATE_edited: return "DW_ATE_edited";
@@ -602,6 +647,7 @@ const char *llvm::dwarf::LNExtendedString(unsigned Encoding) {
case DW_LNE_end_sequence: return "DW_LNE_end_sequence";
case DW_LNE_set_address: return "DW_LNE_set_address";
case DW_LNE_define_file: return "DW_LNE_define_file";
+ case DW_LNE_set_discriminator: return "DW_LNE_set_discriminator";
case DW_LNE_lo_user: return "DW_LNE_lo_user";
case DW_LNE_hi_user: return "DW_LNE_hi_user";
}
@@ -651,6 +697,9 @@ const char *llvm::dwarf::CallFrameString(unsigned Encoding) {
case DW_CFA_val_offset: return "DW_CFA_val_offset";
case DW_CFA_val_offset_sf: return "DW_CFA_val_offset_sf";
case DW_CFA_val_expression: return "DW_CFA_val_expression";
+ case DW_CFA_MIPS_advance_loc8: return "DW_CFA_MIPS_advance_loc8";
+ case DW_CFA_GNU_window_save: return "DW_CFA_GNU_window_save";
+ case DW_CFA_GNU_args_size: return "DW_CFA_GNU_args_size";
case DW_CFA_lo_user: return "DW_CFA_lo_user";
case DW_CFA_hi_user: return "DW_CFA_hi_user";
}
diff --git a/lib/Support/DynamicLibrary.cpp b/lib/Support/DynamicLibrary.cpp
index 455c3801cc68..fb02c07e4af8 100644
--- a/lib/Support/DynamicLibrary.cpp
+++ b/lib/Support/DynamicLibrary.cpp
@@ -9,28 +9,26 @@
//
// This header file implements the operating system DynamicLibrary concept.
//
-// FIXME: This file leaks the ExplicitSymbols and OpenedHandles vector, and is
-// not thread safe!
+// FIXME: This file leaks ExplicitSymbols and OpenedHandles!
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Config/config.h"
#include <cstdio>
#include <cstring>
-#include <map>
-#include <vector>
// Collection of symbol name/value pairs to be searched prior to any libraries.
-static std::map<std::string, void*> *ExplicitSymbols = 0;
+static llvm::StringMap<void *> *ExplicitSymbols = 0;
namespace {
struct ExplicitSymbolsDeleter {
~ExplicitSymbolsDeleter() {
- if (ExplicitSymbols)
- delete ExplicitSymbols;
+ delete ExplicitSymbols;
}
};
@@ -38,13 +36,22 @@ struct ExplicitSymbolsDeleter {
static ExplicitSymbolsDeleter Dummy;
-void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName,
+
+static llvm::sys::SmartMutex<true>& getMutex() {
+ static llvm::sys::SmartMutex<true> HandlesMutex;
+ return HandlesMutex;
+}
+
+void llvm::sys::DynamicLibrary::AddSymbol(StringRef symbolName,
void *symbolValue) {
+ SmartScopedLock<true> lock(getMutex());
if (ExplicitSymbols == 0)
- ExplicitSymbols = new std::map<std::string, void*>();
+ ExplicitSymbols = new llvm::StringMap<void*>();
(*ExplicitSymbols)[symbolName] = symbolValue;
}
+char llvm::sys::DynamicLibrary::Invalid = 0;
+
#ifdef LLVM_ON_WIN32
#include "Windows/DynamicLibrary.inc"
@@ -61,66 +68,78 @@ using namespace llvm::sys;
//=== independent code.
//===----------------------------------------------------------------------===//
-static std::vector<void *> *OpenedHandles = 0;
-
-
-static SmartMutex<true>& getMutex() {
- static SmartMutex<true> HandlesMutex;
- return HandlesMutex;
-}
+static DenseSet<void *> *OpenedHandles = 0;
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
+ std::string *errMsg) {
+ SmartScopedLock<true> lock(getMutex());
-bool DynamicLibrary::LoadLibraryPermanently(const char *Filename,
- std::string *ErrMsg) {
- void *H = dlopen(Filename, RTLD_LAZY|RTLD_GLOBAL);
- if (H == 0) {
- if (ErrMsg) *ErrMsg = dlerror();
- return true;
+ void *handle = dlopen(filename, RTLD_LAZY|RTLD_GLOBAL);
+ if (handle == 0) {
+ if (errMsg) *errMsg = dlerror();
+ return DynamicLibrary();
}
+
#ifdef __CYGWIN__
// Cygwin searches symbols only in the main
// with the handle of dlopen(NULL, RTLD_GLOBAL).
- if (Filename == NULL)
- H = RTLD_DEFAULT;
+ if (filename == NULL)
+ handle = RTLD_DEFAULT;
#endif
- SmartScopedLock<true> Lock(getMutex());
+
if (OpenedHandles == 0)
- OpenedHandles = new std::vector<void *>();
- OpenedHandles->push_back(H);
- return false;
+ OpenedHandles = new DenseSet<void *>();
+
+ // If we've already loaded this library, dlclose() the handle in order to
+ // keep the internal refcount at +1.
+ if (!OpenedHandles->insert(handle).second)
+ dlclose(handle);
+
+ return DynamicLibrary(handle);
+}
+
+void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+ if (!isValid())
+ return NULL;
+ return dlsym(Data, symbolName);
}
+
#else
using namespace llvm;
using namespace llvm::sys;
-bool DynamicLibrary::LoadLibraryPermanently(const char *Filename,
- std::string *ErrMsg) {
- if (ErrMsg) *ErrMsg = "dlopen() not supported on this platform";
- return true;
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
+ std::string *errMsg) {
+ if (errMsg) *errMsg = "dlopen() not supported on this platform";
+ return DynamicLibrary();
}
+
+void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+ return NULL;
+}
+
#endif
namespace llvm {
void *SearchForAddressOfSpecialSymbol(const char* symbolName);
}
-void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
+void* DynamicLibrary::SearchForAddressOfSymbol(const char *symbolName) {
+ SmartScopedLock<true> Lock(getMutex());
+
// First check symbols added via AddSymbol().
if (ExplicitSymbols) {
- std::map<std::string, void *>::iterator I =
- ExplicitSymbols->find(symbolName);
- std::map<std::string, void *>::iterator E = ExplicitSymbols->end();
+ StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
- if (I != E)
- return I->second;
+ if (i != ExplicitSymbols->end())
+ return i->second;
}
#if HAVE_DLFCN_H
// Now search the libraries.
- SmartScopedLock<true> Lock(getMutex());
if (OpenedHandles) {
- for (std::vector<void *>::iterator I = OpenedHandles->begin(),
+ for (DenseSet<void *>::iterator I = OpenedHandles->begin(),
E = OpenedHandles->end(); I != E; ++I) {
//lt_ptr ptr = lt_dlsym(*I, symbolName);
void *ptr = dlsym(*I, symbolName);
diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp
index 1568342e9c9d..17b827132f57 100644
--- a/lib/Support/FoldingSet.cpp
+++ b/lib/Support/FoldingSet.cpp
@@ -64,10 +64,8 @@ void FoldingSetNodeID::AddPointer(const void *Ptr) {
// depend on the host. It doesn't matter however, because hashing on
// pointer values in inherently unstable. Nothing should depend on the
// ordering of nodes in the folding set.
- intptr_t PtrI = (intptr_t)Ptr;
- Bits.push_back(unsigned(PtrI));
- if (sizeof(intptr_t) > sizeof(unsigned))
- Bits.push_back(unsigned(uint64_t(PtrI) >> 32));
+ Bits.append(reinterpret_cast<unsigned *>(&Ptr),
+ reinterpret_cast<unsigned *>(&Ptr+1));
}
void FoldingSetNodeID::AddInteger(signed I) {
Bits.push_back(I);
diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp
index c525a1228129..a19e4b41189b 100644
--- a/lib/Support/Host.cpp
+++ b/lib/Support/Host.cpp
@@ -213,13 +213,13 @@ std::string sys::getHostCPUName() {
case 30: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz.
// As found in a Summer 2010 model iMac.
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.
return "corei7";
// SandyBridge:
case 42: // Intel Core i7 processor. All processors are manufactured
// using the 32 nm process.
- case 44: // Intel Core i7 processor and Intel Xeon processor. All
- // processors are manufactured using the 32 nm process.
case 45:
return "corei7-avx";
diff --git a/lib/Support/IncludeFile.cpp b/lib/Support/IncludeFile.cpp
index 5da88261ce53..e67acb3d1d67 100644
--- a/lib/Support/IncludeFile.cpp
+++ b/lib/Support/IncludeFile.cpp
@@ -1,4 +1,4 @@
-//===- lib/System/IncludeFile.cpp - Ensure Linking Of Implementation -----===//
+//===- lib/Support/IncludeFile.cpp - Ensure Linking Of Implementation -----===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/lib/Support/Memory.cpp b/lib/Support/Memory.cpp
index a9689b2c39f2..2a1642ac2e85 100644
--- a/lib/Support/Memory.cpp
+++ b/lib/Support/Memory.cpp
@@ -16,6 +16,10 @@
#include "llvm/Support/Valgrind.h"
#include "llvm/Config/config.h"
+#if defined(__mips__)
+#include <sys/cachectl.h>
+#endif
+
namespace llvm {
using namespace sys;
}
@@ -66,6 +70,8 @@ void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr,
char *Start = (char*) Addr;
char *End = Start + Len;
__clear_cache(Start, End);
+# elif defined(__mips__)
+ cacheflush((char*)Addr, Len, BCACHE);
# endif
#endif // end apple
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index d264be9aced1..0771af5fee07 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -275,16 +275,16 @@ static bool shouldUseMmap(int FD,
error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
OwningPtr<MemoryBuffer> &result,
- size_t FileSize, size_t MapSize,
- off_t Offset,
+ uint64_t FileSize, uint64_t MapSize,
+ int64_t Offset,
bool RequiresNullTerminator) {
static int PageSize = sys::Process::GetPageSize();
// Default is to map the full file.
- if (MapSize == size_t(-1)) {
+ if (MapSize == uint64_t(-1)) {
// If we don't know the file size, use fstat to find out. fstat on an open
// file descriptor is cheaper than stat on a random path.
- if (FileSize == size_t(-1)) {
+ if (FileSize == uint64_t(-1)) {
struct stat FileInfo;
// TODO: This should use fstat64 when available.
if (fstat(FD, &FileInfo) == -1) {
diff --git a/lib/Support/MemoryObject.cpp b/lib/Support/MemoryObject.cpp
index 91e3ecd23a2e..b20ab8923813 100644
--- a/lib/Support/MemoryObject.cpp
+++ b/lib/Support/MemoryObject.cpp
@@ -19,8 +19,11 @@ int MemoryObject::readBytes(uint64_t address,
uint64_t* copied) const {
uint64_t current = address;
uint64_t limit = getBase() + getExtent();
-
- while (current - address < size && current < limit) {
+
+ if (current + size > limit)
+ return -1;
+
+ while (current - address < size) {
if (readByte(current, &buf[(current - address)]))
return -1;
diff --git a/lib/Support/Mutex.cpp b/lib/Support/Mutex.cpp
index b408973bbad1..8874e943f4c2 100644
--- a/lib/Support/Mutex.cpp
+++ b/lib/Support/Mutex.cpp
@@ -152,6 +152,6 @@ MutexImpl::tryacquire()
#elif defined( LLVM_ON_WIN32)
#include "Windows/Mutex.inc"
#else
-#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
#endif
#endif
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index 8fbaf2d42bf9..e5b7cd3bfbc2 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -121,7 +121,7 @@ sys::IdentifyFileType(const char *magic, unsigned length) {
case 7: return Mach_O_DynamicLinker_FileType;
case 8: return Mach_O_Bundle_FileType;
case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType;
- case 10: break; // FIXME: MH_DSYM companion file with only debug.
+ case 10: return Mach_O_DSYMCompanion_FileType;
}
break;
}
diff --git a/lib/Support/PathV2.cpp b/lib/Support/PathV2.cpp
index 896c94c071bc..bebe442e2478 100644
--- a/lib/Support/PathV2.cpp
+++ b/lib/Support/PathV2.cpp
@@ -490,6 +490,36 @@ bool is_separator(char value) {
}
}
+void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result) {
+ result.clear();
+
+ // Check whether the temporary directory is specified by an environment
+ // variable.
+ const char *EnvironmentVariable;
+#ifdef LLVM_ON_WIN32
+ EnvironmentVariable = "TEMP";
+#else
+ EnvironmentVariable = "TMPDIR";
+#endif
+ if (char *RequestedDir = getenv(EnvironmentVariable)) {
+ result.append(RequestedDir, RequestedDir + strlen(RequestedDir));
+ return;
+ }
+
+ // Fall back to a system default.
+ const char *DefaultResult;
+#ifdef LLVM_ON_WIN32
+ (void)erasedOnReboot;
+ DefaultResult = "C:\\TEMP";
+#else
+ if (erasedOnReboot)
+ DefaultResult = "/tmp";
+ else
+ DefaultResult = "/var/tmp";
+#endif
+ result.append(DefaultResult, DefaultResult + strlen(DefaultResult));
+}
+
bool has_root_name(const Twine &path) {
SmallString<128> path_storage;
StringRef p = path.toStringRef(path_storage);
@@ -626,7 +656,7 @@ error_code create_directories(const Twine &path, bool &existed) {
if (error_code ec = fs::exists(parent, parent_exists)) return ec;
if (!parent_exists)
- return create_directories(parent, existed);
+ if (error_code ec = create_directories(parent, existed)) return ec;
return create_directory(p, existed);
}
@@ -682,14 +712,12 @@ bool is_other(file_status status) {
!is_symlink(status);
}
-void directory_entry::replace_filename(const Twine &filename, file_status st,
- file_status symlink_st) {
+void directory_entry::replace_filename(const Twine &filename, file_status st) {
SmallString<128> path(Path.begin(), Path.end());
path::remove_filename(path);
path::append(path, filename);
Path = path.str();
Status = st;
- SymlinkStatus = symlink_st;
}
error_code has_magic(const Twine &path, const Twine &magic, bool &result) {
diff --git a/lib/Support/PrettyStackTrace.cpp b/lib/Support/PrettyStackTrace.cpp
index 082b7012eb23..ef3307317c4a 100644
--- a/lib/Support/PrettyStackTrace.cpp
+++ b/lib/Support/PrettyStackTrace.cpp
@@ -62,7 +62,7 @@ extern "C" {
CRASH_REPORTER_CLIENT_HIDDEN
struct crashreporter_annotations_t gCRAnnotations
__attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
- = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0 };
+ = { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0, 0, 0 };
}
#elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO
static const char *__crashreporter_info__ = 0;
diff --git a/lib/Support/RWMutex.cpp b/lib/Support/RWMutex.cpp
index fc02f9cf7c11..d0b1e10b56fb 100644
--- a/lib/Support/RWMutex.cpp
+++ b/lib/Support/RWMutex.cpp
@@ -152,6 +152,6 @@ RWMutexImpl::writer_release()
#elif defined( LLVM_ON_WIN32)
#include "Windows/RWMutex.inc"
#else
-#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
#endif
#endif
diff --git a/lib/Support/SearchForAddressOfSpecialSymbol.cpp b/lib/Support/SearchForAddressOfSpecialSymbol.cpp
index d63830185c32..2d23902bb85c 100644
--- a/lib/Support/SearchForAddressOfSpecialSymbol.cpp
+++ b/lib/Support/SearchForAddressOfSpecialSymbol.cpp
@@ -28,21 +28,6 @@ static void *DoSearch(const char* symbolName) {
#ifdef __APPLE__
{
- EXPLICIT_SYMBOL(__ashldi3);
- EXPLICIT_SYMBOL(__ashrdi3);
- EXPLICIT_SYMBOL(__cmpdi2);
- EXPLICIT_SYMBOL(__divdi3);
- EXPLICIT_SYMBOL(__fixdfdi);
- EXPLICIT_SYMBOL(__fixsfdi);
- EXPLICIT_SYMBOL(__fixunsdfdi);
- EXPLICIT_SYMBOL(__fixunssfdi);
- EXPLICIT_SYMBOL(__floatdidf);
- EXPLICIT_SYMBOL(__floatdisf);
- EXPLICIT_SYMBOL(__lshrdi3);
- EXPLICIT_SYMBOL(__moddi3);
- EXPLICIT_SYMBOL(__udivdi3);
- EXPLICIT_SYMBOL(__umoddi3);
-
// __eprintf is sometimes used for assert() handling on x86.
//
// FIXME: Currently disabled when using Clang, as we don't always have our
diff --git a/lib/Support/StringExtras.cpp b/lib/Support/StringExtras.cpp
index eb2fa084218a..49c5ac4252c8 100644
--- a/lib/Support/StringExtras.cpp
+++ b/lib/Support/StringExtras.cpp
@@ -51,11 +51,10 @@ std::pair<StringRef, StringRef> llvm::getToken(StringRef Source,
void llvm::SplitString(StringRef Source,
SmallVectorImpl<StringRef> &OutFragments,
StringRef Delimiters) {
- StringRef S2, S;
- tie(S2, S) = getToken(Source, Delimiters);
- while (!S2.empty()) {
- OutFragments.push_back(S2);
- tie(S2, S) = getToken(S, Delimiters);
+ std::pair<StringRef, StringRef> S = getToken(Source, Delimiters);
+ while (!S.first.empty()) {
+ OutFragments.push_back(S.first);
+ S = getToken(S.second, Delimiters);
}
}
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
index 8c3fc094cd11..b5b4f9476026 100644
--- a/lib/Support/StringRef.cpp
+++ b/lib/Support/StringRef.cpp
@@ -46,12 +46,12 @@ int StringRef::compare_lower(StringRef RHS) const {
/// compare_numeric - Compare strings, handle embedded numbers.
int StringRef::compare_numeric(StringRef RHS) const {
for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) {
- if (Data[I] == RHS.Data[I])
- continue;
+ // Check for sequences of digits.
if (ascii_isdigit(Data[I]) && ascii_isdigit(RHS.Data[I])) {
- // The longer sequence of numbers is larger. This doesn't really handle
- // prefixed zeros well.
- for (size_t J = I+1; J != E+1; ++J) {
+ // The longer sequence of numbers is considered larger.
+ // This doesn't really handle prefixed zeros well.
+ size_t J;
+ for (J = I + 1; J != E + 1; ++J) {
bool ld = J < Length && ascii_isdigit(Data[J]);
bool rd = J < RHS.Length && ascii_isdigit(RHS.Data[J]);
if (ld != rd)
@@ -59,8 +59,15 @@ int StringRef::compare_numeric(StringRef RHS) const {
if (!rd)
break;
}
+ // The two number sequences have the same length (J-I), just memcmp them.
+ if (int Res = compareMemory(Data + I, RHS.Data + I, J - I))
+ return Res < 0 ? -1 : 1;
+ // Identical number sequences, continue search after the numbers.
+ I = J - 1;
+ continue;
}
- return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1;
+ if (Data[I] != RHS.Data[I])
+ return (unsigned char)Data[I] < (unsigned char)RHS.Data[I] ? -1 : 1;
}
if (Length == RHS.Length)
return 0;
diff --git a/lib/Support/TargetRegistry.cpp b/lib/Support/TargetRegistry.cpp
index 293a5d7a0168..7497bfe035c6 100644
--- a/lib/Support/TargetRegistry.cpp
+++ b/lib/Support/TargetRegistry.cpp
@@ -7,9 +7,13 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Target/TargetRegistry.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Host.h"
+#include "llvm/Support/raw_ostream.h"
#include <cassert>
+#include <vector>
using namespace llvm;
// Clients are responsible for avoid race conditions in registration.
@@ -90,3 +94,29 @@ const Target *TargetRegistry::getClosestTargetForJIT(std::string &Error) {
return TheTarget;
}
+static int TargetArraySortFn(const void *LHS, const void *RHS) {
+ typedef std::pair<StringRef, const Target*> pair_ty;
+ return ((const pair_ty*)LHS)->first.compare(((const pair_ty*)RHS)->first);
+}
+
+void TargetRegistry::printRegisteredTargetsForVersion() {
+ std::vector<std::pair<StringRef, const Target*> > Targets;
+ size_t Width = 0;
+ for (TargetRegistry::iterator I = TargetRegistry::begin(),
+ E = TargetRegistry::end();
+ I != E; ++I) {
+ Targets.push_back(std::make_pair(I->getName(), &*I));
+ Width = std::max(Width, Targets.back().first.size());
+ }
+ array_pod_sort(Targets.begin(), Targets.end(), TargetArraySortFn);
+
+ raw_ostream &OS = outs();
+ OS << " Registered Targets:\n";
+ for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
+ OS << " " << Targets[i].first;
+ OS.indent(Width - Targets[i].first.size()) << " - "
+ << Targets[i].second->getShortDescription() << '\n';
+ }
+ if (Targets.empty())
+ OS << " (none)\n";
+}
diff --git a/lib/Support/ThreadLocal.cpp b/lib/Support/ThreadLocal.cpp
index 6b43048da155..fdb251c0a36b 100644
--- a/lib/Support/ThreadLocal.cpp
+++ b/lib/Support/ThreadLocal.cpp
@@ -79,6 +79,6 @@ void ThreadLocalImpl::removeInstance() {
#elif defined( LLVM_ON_WIN32)
#include "Windows/ThreadLocal.inc"
#else
-#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/ThreadLocal.cpp
+#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp
#endif
#endif
diff --git a/lib/Support/Threading.cpp b/lib/Support/Threading.cpp
index 29579567ac6c..8f0bb93eb4d1 100644
--- a/lib/Support/Threading.cpp
+++ b/lib/Support/Threading.cpp
@@ -24,7 +24,7 @@ static bool multithreaded_mode = false;
static sys::Mutex* global_lock = 0;
bool llvm::llvm_start_multithreaded() {
-#ifdef LLVM_MULTITHREADED
+#if ENABLE_THREADS != 0
assert(!multithreaded_mode && "Already multithreaded!");
multithreaded_mode = true;
global_lock = new sys::Mutex(true);
@@ -39,7 +39,7 @@ bool llvm::llvm_start_multithreaded() {
}
void llvm::llvm_stop_multithreaded() {
-#ifdef LLVM_MULTITHREADED
+#if ENABLE_THREADS != 0
assert(multithreaded_mode && "Not currently multithreaded!");
// We fence here to insure that all threaded operations are complete BEFORE we
@@ -63,7 +63,7 @@ void llvm::llvm_release_global_lock() {
if (multithreaded_mode) global_lock->release();
}
-#if defined(LLVM_MULTITHREADED) && defined(HAVE_PTHREAD_H)
+#if ENABLE_THREADS != 0 && defined(HAVE_PTHREAD_H)
#include <pthread.h>
struct ThreadInfo {
@@ -102,13 +102,44 @@ void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
error:
::pthread_attr_destroy(&Attr);
}
+#elif ENABLE_THREADS!=0 && defined(LLVM_ON_WIN32)
+#include "Windows/Windows.h"
+#include <process.h>
-#else
+struct ThreadInfo {
+ void (*func)(void*);
+ void *param;
+};
-// No non-pthread implementation, currently.
+static unsigned __stdcall ThreadCallback(void *param) {
+ struct ThreadInfo *info = reinterpret_cast<struct ThreadInfo *>(param);
+ info->func(info->param);
+
+ return 0;
+}
void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
unsigned RequestedStackSize) {
+ struct ThreadInfo param = { Fn, UserData };
+
+ HANDLE hThread = (HANDLE)::_beginthreadex(NULL,
+ RequestedStackSize, ThreadCallback,
+ &param, 0, NULL);
+
+ if (hThread) {
+ // We actually don't care whether the wait succeeds or fails, in
+ // the same way we don't care whether the pthread_join call succeeds
+ // or fails. There's not much we could do if this were to fail. But
+ // on success, this call will wait until the thread finishes executing
+ // before returning.
+ (void)::WaitForSingleObject(hThread, INFINITE);
+ ::CloseHandle(hThread);
+ }
+}
+#else
+// Support for non-Win32, non-pthread implementation.
+void llvm::llvm_execute_on_thread(void (*Fn)(void*), void *UserData,
+ unsigned RequestedStackSize) {
(void) RequestedStackSize;
Fn(UserData);
}
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index 7e094ee78f36..c61af372d79c 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -8,16 +8,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Triple.h"
-
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Twine.h"
-#include <cassert>
#include <cstring>
using namespace llvm;
-//
-
const char *Triple::getArchTypeName(ArchType Kind) {
switch (Kind) {
case InvalidArch: return "<invalid>";
@@ -29,6 +24,8 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case cellspu: return "cellspu";
case mips: return "mips";
case mipsel: return "mipsel";
+ case mips64: return "mips64";
+ case mips64el:return "mips64el";
case msp430: return "msp430";
case ppc64: return "powerpc64";
case ppc: return "powerpc";
@@ -43,6 +40,8 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case mblaze: return "mblaze";
case ptx32: return "ptx32";
case ptx64: return "ptx64";
+ case le32: return "le32";
+ case amdil: return "amdil";
}
return "<invalid>";
@@ -77,6 +76,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case ptx32: return "ptx";
case ptx64: return "ptx";
+ case le32: return "le32";
+ case amdil: return "amdil";
}
}
@@ -102,6 +103,7 @@ const char *Triple::getOSTypeName(OSType Kind) {
case DragonFly: return "dragonfly";
case FreeBSD: return "freebsd";
case IOS: return "ios";
+ case KFreeBSD: return "kfreebsd";
case Linux: return "linux";
case Lv2: return "lv2";
case MacOSX: return "macosx";
@@ -114,6 +116,7 @@ const char *Triple::getOSTypeName(OSType Kind) {
case Haiku: return "haiku";
case Minix: return "minix";
case RTEMS: return "rtems";
+ case NativeClient: return "nacl";
}
return "<invalid>";
@@ -144,10 +147,16 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
return mips;
if (Name == "mipsel")
return mipsel;
+ if (Name == "mips64")
+ return mips64;
+ if (Name == "mips64el")
+ return mips64el;
if (Name == "msp430")
return msp430;
if (Name == "ppc64")
return ppc64;
+ if (Name == "ppc32")
+ return ppc;
if (Name == "ppc")
return ppc;
if (Name == "mblaze")
@@ -172,6 +181,10 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
return ptx32;
if (Name == "ptx64")
return ptx64;
+ if (Name == "le32")
+ return le32;
+ if (Name == "amdil")
+ return amdil;
return UnknownArch;
}
@@ -207,13 +220,16 @@ Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
// This is derived from the driver driver.
if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
- Str == "armv6" || Str == "armv7")
+ Str == "armv6" || Str == "armv7" || Str == "armv7f" || Str == "armv7k" ||
+ Str == "armv7s")
return Triple::arm;
if (Str == "ptx32")
return Triple::ptx32;
if (Str == "ptx64")
return Triple::ptx64;
+ if (Str == "amdil")
+ return Triple::amdil;
return Triple::UnknownArch;
}
@@ -249,6 +265,10 @@ const char *Triple::getArchNameForAssembler() {
return "ptx32";
if (Str == "ptx64")
return "ptx64";
+ if (Str == "le32")
+ return "le32";
+ if (Str == "amdil")
+ return "amdil";
return NULL;
}
@@ -288,6 +308,10 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) {
else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
ArchName == "psp")
return mipsel;
+ else if (ArchName == "mips64" || ArchName == "mips64eb")
+ return mips64;
+ else if (ArchName == "mips64el")
+ return mips64el;
else if (ArchName == "sparc")
return sparc;
else if (ArchName == "sparcv9")
@@ -302,6 +326,10 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) {
return ptx32;
else if (ArchName == "ptx64")
return ptx64;
+ else if (ArchName == "le32")
+ return le32;
+ else if (ArchName == "amdil")
+ return amdil;
else
return UnknownArch;
}
@@ -330,6 +358,8 @@ Triple::OSType Triple::ParseOS(StringRef OSName) {
return FreeBSD;
else if (OSName.startswith("ios"))
return IOS;
+ else if (OSName.startswith("kfreebsd"))
+ return KFreeBSD;
else if (OSName.startswith("linux"))
return Linux;
else if (OSName.startswith("lv2"))
@@ -354,6 +384,8 @@ Triple::OSType Triple::ParseOS(StringRef OSName) {
return Minix;
else if (OSName.startswith("rtems"))
return RTEMS;
+ else if (OSName.startswith("nacl"))
+ return NativeClient;
else
return UnknownOS;
}
diff --git a/lib/Support/Twine.cpp b/lib/Support/Twine.cpp
index d62123cc985e..3d04bc34f0eb 100644
--- a/lib/Support/Twine.cpp
+++ b/lib/Support/Twine.cpp
@@ -16,7 +16,7 @@ using namespace llvm;
std::string Twine::str() const {
// If we're storing only a std::string, just return it.
if (LHSKind == StdStringKind && RHSKind == EmptyKind)
- return *static_cast<const std::string*>(LHS);
+ return *LHS.stdString;
// Otherwise, flatten and copy the contents first.
SmallString<256> Vec;
@@ -40,9 +40,9 @@ StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const {
switch (getLHSKind()) {
case CStringKind:
// Already null terminated, yay!
- return StringRef(static_cast<const char*>(LHS));
+ return StringRef(LHS.cString);
case StdStringKind: {
- const std::string *str = static_cast<const std::string*>(LHS);
+ const std::string *str = LHS.stdString;
return StringRef(str->c_str(), str->size());
}
default:
@@ -55,48 +55,51 @@ StringRef Twine::toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const {
return StringRef(Out.data(), Out.size());
}
-void Twine::printOneChild(raw_ostream &OS, const void *Ptr,
+void Twine::printOneChild(raw_ostream &OS, Child Ptr,
NodeKind Kind) const {
switch (Kind) {
case Twine::NullKind: break;
case Twine::EmptyKind: break;
case Twine::TwineKind:
- static_cast<const Twine*>(Ptr)->print(OS);
+ Ptr.twine->print(OS);
break;
case Twine::CStringKind:
- OS << static_cast<const char*>(Ptr);
+ OS << Ptr.cString;
break;
case Twine::StdStringKind:
- OS << *static_cast<const std::string*>(Ptr);
+ OS << *Ptr.stdString;
break;
case Twine::StringRefKind:
- OS << *static_cast<const StringRef*>(Ptr);
+ OS << *Ptr.stringRef;
+ break;
+ case Twine::CharKind:
+ OS << Ptr.character;
break;
case Twine::DecUIKind:
- OS << (unsigned)(uintptr_t)Ptr;
+ OS << Ptr.decUI;
break;
case Twine::DecIKind:
- OS << (int)(intptr_t)Ptr;
+ OS << Ptr.decI;
break;
case Twine::DecULKind:
- OS << *static_cast<const unsigned long*>(Ptr);
+ OS << *Ptr.decUL;
break;
case Twine::DecLKind:
- OS << *static_cast<const long*>(Ptr);
+ OS << *Ptr.decL;
break;
case Twine::DecULLKind:
- OS << *static_cast<const unsigned long long*>(Ptr);
+ OS << *Ptr.decULL;
break;
case Twine::DecLLKind:
- OS << *static_cast<const long long*>(Ptr);
+ OS << *Ptr.decLL;
break;
case Twine::UHexKind:
- OS.write_hex(*static_cast<const uint64_t*>(Ptr));
+ OS.write_hex(*Ptr.uHex);
break;
}
}
-void Twine::printOneChildRepr(raw_ostream &OS, const void *Ptr,
+void Twine::printOneChildRepr(raw_ostream &OS, Child Ptr,
NodeKind Kind) const {
switch (Kind) {
case Twine::NullKind:
@@ -105,40 +108,43 @@ void Twine::printOneChildRepr(raw_ostream &OS, const void *Ptr,
OS << "empty"; break;
case Twine::TwineKind:
OS << "rope:";
- static_cast<const Twine*>(Ptr)->printRepr(OS);
+ Ptr.twine->printRepr(OS);
break;
case Twine::CStringKind:
OS << "cstring:\""
- << static_cast<const char*>(Ptr) << "\"";
+ << Ptr.cString << "\"";
break;
case Twine::StdStringKind:
OS << "std::string:\""
- << static_cast<const std::string*>(Ptr) << "\"";
+ << Ptr.stdString << "\"";
break;
case Twine::StringRefKind:
OS << "stringref:\""
- << static_cast<const StringRef*>(Ptr) << "\"";
+ << Ptr.stringRef << "\"";
+ break;
+ case Twine::CharKind:
+ OS << "char:\"" << Ptr.character << "\"";
break;
case Twine::DecUIKind:
- OS << "decUI:\"" << (unsigned)(uintptr_t)Ptr << "\"";
+ OS << "decUI:\"" << Ptr.decUI << "\"";
break;
case Twine::DecIKind:
- OS << "decI:\"" << (int)(intptr_t)Ptr << "\"";
+ OS << "decI:\"" << Ptr.decI << "\"";
break;
case Twine::DecULKind:
- OS << "decUL:\"" << *static_cast<const unsigned long*>(Ptr) << "\"";
+ OS << "decUL:\"" << *Ptr.decUL << "\"";
break;
case Twine::DecLKind:
- OS << "decL:\"" << *static_cast<const long*>(Ptr) << "\"";
+ OS << "decL:\"" << *Ptr.decL << "\"";
break;
case Twine::DecULLKind:
- OS << "decULL:\"" << *static_cast<const unsigned long long*>(Ptr) << "\"";
+ OS << "decULL:\"" << *Ptr.decULL << "\"";
break;
case Twine::DecLLKind:
- OS << "decLL:\"" << *static_cast<const long long*>(Ptr) << "\"";
+ OS << "decLL:\"" << *Ptr.decLL << "\"";
break;
case Twine::UHexKind:
- OS << "uhex:\"" << static_cast<const uint64_t*>(Ptr) << "\"";
+ OS << "uhex:\"" << Ptr.uHex << "\"";
break;
}
}
diff --git a/lib/Support/Unix/Host.inc b/lib/Support/Unix/Host.inc
index 5fd0e5e0790b..dda3ce2c6f97 100644
--- a/lib/Support/Unix/Host.inc
+++ b/lib/Support/Unix/Host.inc
@@ -22,6 +22,7 @@
#include <sys/utsname.h>
#include <cctype>
#include <string>
+#include <cstdlib> // ::getenv
using namespace llvm;
diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc
index f295b92e4a5b..85c7c4022f48 100644
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -252,8 +252,8 @@ Path::GetUserHomeDirectory() {
Path
Path::GetCurrentDirectory() {
char pathname[MAXPATHLEN];
- if (!getcwd(pathname,MAXPATHLEN)) {
- assert (false && "Could not query current working directory.");
+ if (!getcwd(pathname, MAXPATHLEN)) {
+ assert(false && "Could not query current working directory.");
return Path();
}
diff --git a/lib/Support/Unix/PathV2.inc b/lib/Support/Unix/PathV2.inc
index 03ff28367e44..bbbc344661be 100644
--- a/lib/Support/Unix/PathV2.inc
+++ b/lib/Support/Unix/PathV2.inc
@@ -42,6 +42,9 @@
#if HAVE_STDIO_H
#include <stdio.h>
#endif
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
using namespace llvm;
@@ -342,19 +345,22 @@ error_code status(const Twine &path, file_status &result) {
}
error_code unique_file(const Twine &model, int &result_fd,
- SmallVectorImpl<char> &result_path) {
+ SmallVectorImpl<char> &result_path,
+ bool makeAbsolute) {
SmallString<128> Model;
model.toVector(Model);
// Null terminate.
Model.c_str();
- // Make model absolute by prepending a temp directory if it's not already.
- bool absolute = path::is_absolute(Twine(Model));
- if (!absolute) {
- SmallString<128> TDir;
- if (error_code ec = TempDir(TDir)) return ec;
- path::append(TDir, Twine(Model));
- Model.swap(TDir);
+ if (makeAbsolute) {
+ // Make model absolute by prepending a temp directory if it's not already.
+ bool absolute = path::is_absolute(Twine(Model));
+ if (!absolute) {
+ SmallString<128> TDir;
+ if (error_code ec = TempDir(TDir)) return ec;
+ path::append(TDir, Twine(Model));
+ Model.swap(TDir);
+ }
}
// Replace '%' with random chars. From here on, DO NOT modify model. It may be
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index 5cdb11ccebc4..da440fd48f3d 100644
--- a/lib/Support/Unix/Process.inc
+++ b/lib/Support/Unix/Process.inc
@@ -293,3 +293,7 @@ const char *Process::OutputBold(bool bg) {
const char *Process::ResetColor() {
return "\033[0m";
}
+
+void Process::SetWorkingDirectory(std::string Path) {
+ ::chdir(Path.c_str());
+}
diff --git a/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc
index fc5f5809cb40..83da82a949ca 100644
--- a/lib/Support/Windows/DynamicLibrary.inc
+++ b/lib/Support/Windows/DynamicLibrary.inc
@@ -39,7 +39,7 @@ using namespace sys;
//=== and must not be UNIX code.
//===----------------------------------------------------------------------===//
-static std::vector<HMODULE> OpenedHandles;
+static DenseSet<HMODULE> *OpenedHandles;
extern "C" {
@@ -63,30 +63,43 @@ extern "C" {
#endif
stricmp(ModuleName, "msvcrt20") != 0 &&
stricmp(ModuleName, "msvcrt40") != 0) {
- OpenedHandles.push_back((HMODULE)ModuleBase);
+ OpenedHandles->insert((HMODULE)ModuleBase);
}
return TRUE;
}
}
-bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
- std::string *ErrMsg) {
- if (filename) {
- HMODULE a_handle = LoadLibrary(filename);
+DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *filename,
+ std::string *errMsg) {
+ SmartScopedLock<true> lock(getMutex());
- if (a_handle == 0)
- return MakeErrMsg(ErrMsg, std::string(filename) + ": Can't open : ");
+ if (!filename) {
+ // When no file is specified, enumerate all DLLs and EXEs in the process.
+ if (OpenedHandles == 0)
+ OpenedHandles = new DenseSet<HMODULE>();
- OpenedHandles.push_back(a_handle);
- } else {
- // When no file is specified, enumerate all DLLs and EXEs in the
- // process.
EnumerateLoadedModules(GetCurrentProcess(), ELM_Callback, 0);
+ // Dummy library that represents "search all handles".
+ // This is mostly to ensure that the return value still shows up as "valid".
+ return DynamicLibrary(&OpenedHandles);
}
+
+ HMODULE a_handle = LoadLibrary(filename);
- // Because we don't remember the handle, we will never free it; hence,
- // it is loaded permanently.
- return false;
+ if (a_handle == 0) {
+ MakeErrMsg(errMsg, std::string(filename) + ": Can't open : ");
+ return DynamicLibrary();
+ }
+
+ if (OpenedHandles == 0)
+ OpenedHandles = new DenseSet<HMODULE>();
+
+ // If we've already loaded this library, FreeLibrary() the handle in order to
+ // keep the internal refcount at +1.
+ if (!OpenedHandles->insert(a_handle).second)
+ FreeLibrary(a_handle);
+
+ return DynamicLibrary(a_handle);
}
// Stack probing routines are in the support library (e.g. libgcc), but we don't
@@ -101,21 +114,24 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
#undef EXPLICIT_SYMBOL2
void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
+ SmartScopedLock<true> Lock(getMutex());
+
// First check symbols added via AddSymbol().
if (ExplicitSymbols) {
- std::map<std::string, void *>::iterator I =
- ExplicitSymbols->find(symbolName);
- std::map<std::string, void *>::iterator E = ExplicitSymbols->end();
- if (I != E)
- return I->second;
+ StringMap<void *>::iterator i = ExplicitSymbols->find(symbolName);
+
+ if (i != ExplicitSymbols->end())
+ return i->second;
}
// Now search the libraries.
- for (std::vector<HMODULE>::iterator I = OpenedHandles.begin(),
- E = OpenedHandles.end(); I != E; ++I) {
- FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
- if (ptr) {
- return (void *)(intptr_t)ptr;
+ if (OpenedHandles) {
+ for (DenseSet<HMODULE>::iterator I = OpenedHandles->begin(),
+ E = OpenedHandles->end(); I != E; ++I) {
+ FARPROC ptr = GetProcAddress((HMODULE)*I, symbolName);
+ if (ptr) {
+ return (void *)(intptr_t)ptr;
+ }
}
}
@@ -134,4 +150,14 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
return 0;
}
+
+void *DynamicLibrary::getAddressOfSymbol(const char *symbolName) {
+ if (!isValid())
+ return NULL;
+ if (Data == &OpenedHandles)
+ return SearchForAddressOfSymbol(symbolName);
+ return (void *)(intptr_t)GetProcAddress((HMODULE)Data, symbolName);
+}
+
+
}
diff --git a/lib/Support/Windows/Memory.inc b/lib/Support/Windows/Memory.inc
index 9f69e7367e6f..fcc72837c456 100644
--- a/lib/Support/Windows/Memory.inc
+++ b/lib/Support/Windows/Memory.inc
@@ -32,11 +32,16 @@ MemoryBlock Memory::AllocateRWX(size_t NumBytes,
static const size_t pageSize = Process::GetPageSize();
size_t NumPages = (NumBytes+pageSize-1)/pageSize;
- //FIXME: support NearBlock if ever needed on Win64.
+ PVOID start = NearBlock ? static_cast<unsigned char *>(NearBlock->base()) +
+ NearBlock->size() : NULL;
- void *pa = VirtualAlloc(NULL, NumPages*pageSize, MEM_COMMIT,
+ void *pa = VirtualAlloc(start, NumPages*pageSize, MEM_RESERVE | MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (pa == NULL) {
+ if (NearBlock) {
+ // Try again without the NearBlock hint
+ return AllocateRWX(NumBytes, NULL, ErrMsg);
+ }
MakeErrMsg(ErrMsg, "Can't allocate RWX Memory: ");
return MemoryBlock();
}
@@ -54,20 +59,62 @@ bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) {
return false;
}
+static DWORD getProtection(const void *addr) {
+ MEMORY_BASIC_INFORMATION info;
+ if (sizeof(info) == ::VirtualQuery(addr, &info, sizeof(info))) {
+ return info.Protect;
+ }
+ return 0;
+}
+
bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) {
+ if (!setRangeWritable(M.Address, M.Size)) {
+ return MakeErrMsg(ErrMsg, "Cannot set memory to writeable: ");
+ }
return true;
}
bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) {
- return false;
+ if (!setRangeExecutable(M.Address, M.Size)) {
+ return MakeErrMsg(ErrMsg, "Cannot set memory to executable: ");
+ }
+ return true;
}
bool Memory::setRangeWritable(const void *Addr, size_t Size) {
- return true;
+ DWORD prot = getProtection(Addr);
+ if (!prot)
+ return false;
+
+ if (prot == PAGE_EXECUTE || prot == PAGE_EXECUTE_READ) {
+ prot = PAGE_EXECUTE_READWRITE;
+ } else if (prot == PAGE_NOACCESS || prot == PAGE_READONLY) {
+ prot = PAGE_READWRITE;
+ }
+
+ DWORD oldProt;
+ sys::Memory::InvalidateInstructionCache(Addr, Size);
+ return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt)
+ == TRUE;
}
bool Memory::setRangeExecutable(const void *Addr, size_t Size) {
- return false;
+ DWORD prot = getProtection(Addr);
+ if (!prot)
+ return false;
+
+ if (prot == PAGE_NOACCESS) {
+ prot = PAGE_EXECUTE;
+ } else if (prot == PAGE_READONLY) {
+ prot = PAGE_EXECUTE_READ;
+ } else if (prot == PAGE_READWRITE) {
+ prot = PAGE_EXECUTE_READWRITE;
+ }
+
+ DWORD oldProt;
+ sys::Memory::InvalidateInstructionCache(Addr, Size);
+ return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt)
+ == TRUE;
}
}
diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc
index af71b73cd693..bc597b2dcc89 100644
--- a/lib/Support/Windows/PathV2.inc
+++ b/lib/Support/Windows/PathV2.inc
@@ -445,13 +445,35 @@ error_code file_size(const Twine &path, uint64_t &result) {
return success;
}
+static bool isReservedName(StringRef path) {
+ // This list of reserved names comes from MSDN, at:
+ // http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
+ static const char *sReservedNames[] = { "nul", "con", "prn", "aux",
+ "com1", "com2", "com3", "com4", "com5", "com6",
+ "com7", "com8", "com9", "lpt1", "lpt2", "lpt3",
+ "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9" };
+
+ // First, check to see if this is a device namespace, which always
+ // starts with \\.\, since device namespaces are not legal file paths.
+ if (path.startswith("\\\\.\\"))
+ return true;
+
+ // Then compare against the list of ancient reserved names
+ for (size_t i = 0; i < sizeof(sReservedNames) / sizeof(const char *); ++i) {
+ if (path.equals_lower(sReservedNames[i]))
+ return true;
+ }
+
+ // The path isn't what we consider reserved.
+ return false;
+}
+
error_code status(const Twine &path, file_status &result) {
SmallString<128> path_storage;
SmallVector<wchar_t, 128> path_utf16;
StringRef path8 = path.toStringRef(path_storage);
- // FIXME: We should detect as many "special file name" as possible.
- if (path8.compare_lower("nul") == 0) {
+ if (isReservedName(path8)) {
result = file_status(file_type::character_file);
return success;
}
@@ -501,7 +523,8 @@ handle_status_error:
}
error_code unique_file(const Twine &model, int &result_fd,
- SmallVectorImpl<char> &result_path) {
+ SmallVectorImpl<char> &result_path,
+ bool makeAbsolute) {
// Use result_path as temp storage.
result_path.set_size(0);
StringRef m = model.toStringRef(result_path);
@@ -509,17 +532,19 @@ error_code unique_file(const Twine &model, int &result_fd,
SmallVector<wchar_t, 128> model_utf16;
if (error_code ec = UTF8ToUTF16(m, model_utf16)) return ec;
- // Make model absolute by prepending a temp directory if it's not already.
- bool absolute = path::is_absolute(m);
-
- if (!absolute) {
- SmallVector<wchar_t, 64> temp_dir;
- if (error_code ec = TempDir(temp_dir)) return ec;
- // Handle c: by removing it.
- if (model_utf16.size() > 2 && model_utf16[1] == L':') {
- model_utf16.erase(model_utf16.begin(), model_utf16.begin() + 2);
+ if (makeAbsolute) {
+ // Make model absolute by prepending a temp directory if it's not already.
+ bool absolute = path::is_absolute(m);
+
+ if (!absolute) {
+ SmallVector<wchar_t, 64> temp_dir;
+ if (error_code ec = TempDir(temp_dir)) return ec;
+ // Handle c: by removing it.
+ if (model_utf16.size() > 2 && model_utf16[1] == L':') {
+ model_utf16.erase(model_utf16.begin(), model_utf16.begin() + 2);
+ }
+ model_utf16.insert(model_utf16.begin(), temp_dir.begin(), temp_dir.end());
}
- model_utf16.insert(model_utf16.begin(), temp_dir.begin(), temp_dir.end());
}
// Replace '%' with random chars. From here on, DO NOT modify model. It may be
diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc
index 06a7f0054d50..fe54eb1a7972 100644
--- a/lib/Support/Windows/Process.inc
+++ b/lib/Support/Windows/Process.inc
@@ -15,6 +15,7 @@
#include <psapi.h>
#include <malloc.h>
#include <io.h>
+#include <direct.h>
#ifdef __MINGW32__
#if (HAVE_LIBPSAPI != 1)
@@ -219,4 +220,8 @@ const char *Process::ResetColor() {
return 0;
}
+void Process::SetWorkingDirectory(std::string Path) {
+ ::_chdir(Path.c_str());
+}
+
}
diff --git a/lib/Support/Windows/RWMutex.inc b/lib/Support/Windows/RWMutex.inc
index 471f8fa294be..26b9bba9052c 100644
--- a/lib/Support/Windows/RWMutex.inc
+++ b/lib/Support/Windows/RWMutex.inc
@@ -18,39 +18,115 @@
#include "Windows.h"
-// FIXME: Windows does not have reader-writer locks pre-Vista. If you want
-// real reader-writer locks, you a threads implementation for Windows.
-
namespace llvm {
using namespace sys;
+// Windows has slim read-writer lock support on Vista and higher, so we
+// will attempt to load the APIs. If they exist, we will use them, and
+// if not, we will fall back on critical sections. When we drop support
+// for XP, we can stop lazy-loading these APIs and just use them directly.
+#if defined(__MINGW32__)
+ // Taken from WinNT.h
+ typedef struct _RTL_SRWLOCK {
+ PVOID Ptr;
+ } RTL_SRWLOCK, *PRTL_SRWLOCK;
+
+ // Taken from WinBase.h
+ typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
+#endif
+
+static VOID (WINAPI *fpInitializeSRWLock)(PSRWLOCK lock) = NULL;
+static VOID (WINAPI *fpAcquireSRWLockExclusive)(PSRWLOCK lock) = NULL;
+static VOID (WINAPI *fpAcquireSRWLockShared)(PSRWLOCK lock) = NULL;
+static VOID (WINAPI *fpReleaseSRWLockExclusive)(PSRWLOCK lock) = NULL;
+static VOID (WINAPI *fpReleaseSRWLockShared)(PSRWLOCK lock) = NULL;
+
+static bool sHasSRW = false;
+
+static bool loadSRW() {
+ static bool sChecked = false;
+ if (!sChecked) {
+ sChecked = true;
+
+ HMODULE hLib = ::LoadLibrary(TEXT("Kernel32"));
+ if (hLib) {
+ fpInitializeSRWLock =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "InitializeSRWLock");
+ fpAcquireSRWLockExclusive =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "AcquireSRWLockExclusive");
+ fpAcquireSRWLockShared =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "AcquireSRWLockShared");
+ fpReleaseSRWLockExclusive =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "ReleaseSRWLockExclusive");
+ fpReleaseSRWLockShared =
+ (VOID (WINAPI *)(PSRWLOCK))::GetProcAddress(hLib,
+ "ReleaseSRWLockShared");
+ ::FreeLibrary(hLib);
+
+ if (fpInitializeSRWLock != NULL) {
+ sHasSRW = true;
+ }
+ }
+ }
+ return sHasSRW;
+}
+
RWMutexImpl::RWMutexImpl() {
- data_ = calloc(1, sizeof(CRITICAL_SECTION));
- InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ if (loadSRW()) {
+ data_ = calloc(1, sizeof(SRWLOCK));
+ fpInitializeSRWLock(static_cast<PSRWLOCK>(data_));
+ } else {
+ data_ = calloc(1, sizeof(CRITICAL_SECTION));
+ InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
}
RWMutexImpl::~RWMutexImpl() {
- DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
- free(data_);
+ if (sHasSRW) {
+ // Nothing to do in the case of slim reader/writers
+ } else {
+ DeleteCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ free(data_);
+ }
}
bool RWMutexImpl::reader_acquire() {
- EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ if (sHasSRW) {
+ fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_));
+ } else {
+ EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
return true;
}
bool RWMutexImpl::reader_release() {
- LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ if (sHasSRW) {
+ fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_));
+ } else {
+ LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
return true;
}
bool RWMutexImpl::writer_acquire() {
- EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ if (sHasSRW) {
+ fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_));
+ } else {
+ EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
return true;
}
bool RWMutexImpl::writer_release() {
- LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ if (sHasSRW) {
+ fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_));
+ } else {
+ LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_));
+ }
return true;
}
diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc
index 14f3f21f02a1..0d4b8a26b023 100644
--- a/lib/Support/Windows/Signals.inc
+++ b/lib/Support/Windows/Signals.inc
@@ -23,14 +23,133 @@
#endif
#include <psapi.h>
-#ifdef __MINGW32__
+#ifdef _MSC_VER
+ #pragma comment(lib, "psapi.lib")
+ #pragma comment(lib, "dbghelp.lib")
+#elif __MINGW32__
#if ((HAVE_LIBIMAGEHLP != 1) || (HAVE_LIBPSAPI != 1))
#error "libimagehlp.a & libpsapi.a should be present"
#endif
-#else
- #pragma comment(lib, "psapi.lib")
- #pragma comment(lib, "dbghelp.lib")
-#endif
+ // The version of g++ that comes with MinGW does *not* properly understand
+ // the ll format specifier for printf. However, MinGW passes the format
+ // specifiers on to the MSVCRT entirely, and the CRT understands the ll
+ // specifier. So these warnings are spurious in this case. Since we compile
+ // with -Wall, this will generate these warnings which should be ignored. So
+ // we will turn off the warnings for this just file. However, MinGW also does
+ // not support push and pop for diagnostics, so we have to manually turn it
+ // back on at the end of the file.
+ #pragma GCC diagnostic ignored "-Wformat"
+ #pragma GCC diagnostic ignored "-Wformat-extra-args"
+
+ #if !defined(__MINGW64_VERSION_MAJOR)
+ // MinGW.org does not have updated support for the 64-bit versions of the
+ // DebugHlp APIs. So we will have to load them manually. The structures and
+ // method signatures were pulled from DbgHelp.h in the Windows Platform SDK,
+ // and adjusted for brevity.
+ typedef struct _IMAGEHLP_LINE64 {
+ DWORD SizeOfStruct;
+ PVOID Key;
+ DWORD LineNumber;
+ PCHAR FileName;
+ DWORD64 Address;
+ } IMAGEHLP_LINE64, *PIMAGEHLP_LINE64;
+
+ typedef struct _IMAGEHLP_SYMBOL64 {
+ DWORD SizeOfStruct;
+ DWORD64 Address;
+ DWORD Size;
+ DWORD Flags;
+ DWORD MaxNameLength;
+ CHAR Name[1];
+ } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64;
+
+ typedef struct _tagADDRESS64 {
+ DWORD64 Offset;
+ WORD Segment;
+ ADDRESS_MODE Mode;
+ } ADDRESS64, *LPADDRESS64;
+
+ typedef struct _KDHELP64 {
+ DWORD64 Thread;
+ DWORD ThCallbackStack;
+ DWORD ThCallbackBStore;
+ DWORD NextCallback;
+ DWORD FramePointer;
+ DWORD64 KiCallUserMode;
+ DWORD64 KeUserCallbackDispatcher;
+ DWORD64 SystemRangeStart;
+ DWORD64 KiUserExceptionDispatcher;
+ DWORD64 StackBase;
+ DWORD64 StackLimit;
+ DWORD64 Reserved[5];
+ } KDHELP64, *PKDHELP64;
+
+ typedef struct _tagSTACKFRAME64 {
+ ADDRESS64 AddrPC;
+ ADDRESS64 AddrReturn;
+ ADDRESS64 AddrFrame;
+ ADDRESS64 AddrStack;
+ ADDRESS64 AddrBStore;
+ PVOID FuncTableEntry;
+ DWORD64 Params[4];
+ BOOL Far;
+ BOOL Virtual;
+ DWORD64 Reserved[3];
+ KDHELP64 KdHelp;
+ } STACKFRAME64, *LPSTACKFRAME64;
+
+typedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess,
+ DWORD64 qwBaseAddress, PVOID lpBuffer, DWORD nSize,
+ LPDWORD lpNumberOfBytesRead);
+
+typedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( HANDLE ahProcess,
+ DWORD64 AddrBase);
+
+typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess,
+ DWORD64 Address);
+
+typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,
+ HANDLE hThread, LPADDRESS64 lpaddr);
+
+typedef BOOL (WINAPI *fpStackWalk64)(DWORD, HANDLE, HANDLE, LPSTACKFRAME64,
+ PVOID, PREAD_PROCESS_MEMORY_ROUTINE64,
+ PFUNCTION_TABLE_ACCESS_ROUTINE64,
+ PGET_MODULE_BASE_ROUTINE64,
+ PTRANSLATE_ADDRESS_ROUTINE64);
+static fpStackWalk64 StackWalk64;
+
+typedef DWORD64 (WINAPI *fpSymGetModuleBase64)(HANDLE, DWORD64);
+static fpSymGetModuleBase64 SymGetModuleBase64;
+
+typedef BOOL (WINAPI *fpSymGetSymFromAddr64)(HANDLE, DWORD64,
+ PDWORD64, PIMAGEHLP_SYMBOL64);
+static fpSymGetSymFromAddr64 SymGetSymFromAddr64;
+
+typedef BOOL (WINAPI *fpSymGetLineFromAddr64)(HANDLE, DWORD64,
+ PDWORD, PIMAGEHLP_LINE64);
+static fpSymGetLineFromAddr64 SymGetLineFromAddr64;
+
+typedef PVOID (WINAPI *fpSymFunctionTableAccess64)(HANDLE, DWORD64);
+static fpSymFunctionTableAccess64 SymFunctionTableAccess64;
+
+static bool load64BitDebugHelp(void) {
+ HMODULE hLib = ::LoadLibrary("Dbghelp.dll");
+ if (hLib) {
+ StackWalk64 = (fpStackWalk64)
+ ::GetProcAddress(hLib, "StackWalk64");
+ SymGetModuleBase64 = (fpSymGetModuleBase64)
+ ::GetProcAddress(hLib, "SymGetModuleBase64");
+ SymGetSymFromAddr64 = (fpSymGetSymFromAddr64)
+ ::GetProcAddress(hLib, "SymGetSymFromAddr64");
+ SymGetLineFromAddr64 = (fpSymGetLineFromAddr64)
+ ::GetProcAddress(hLib, "SymGetLineFromAddr64");
+ SymFunctionTableAccess64 = (fpSymFunctionTableAccess64)
+ ::GetProcAddress(hLib, "SymFunctionTableAccess64");
+ }
+ return StackWalk64 != NULL;
+}
+ #endif // !defined(__MINGW64_VERSION_MAJOR)
+#endif // __MINGW32__
// Forward declare.
static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
@@ -90,6 +209,18 @@ static int CRTReportHook(int ReportType, char *Message, int *Return) {
#endif
static void RegisterHandler() {
+#if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR)
+ // On MinGW.org, we need to load up the symbols explicitly, because the
+ // Win32 framework they include does not have support for the 64-bit
+ // versions of the APIs we need. If we cannot load up the APIs (which
+ // would be unexpected as they should exist on every version of Windows
+ // we support), we will bail out since there would be nothing to report.
+ if (!load64BitDebugHelp()) {
+ assert(false && "These APIs should always be available");
+ return;
+ }
+#endif
+
if (RegisteredUnhandledExceptionFilter) {
EnterCriticalSection(&CriticalSection);
return;
@@ -213,20 +344,28 @@ void llvm::sys::RunInterruptHandlers() {
static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
Cleanup();
-#ifdef _WIN64
- // TODO: provide a x64 friendly version of the following
-#else
-
// Initialize the STACKFRAME structure.
- STACKFRAME StackFrame;
+ STACKFRAME64 StackFrame;
memset(&StackFrame, 0, sizeof(StackFrame));
+ DWORD machineType;
+#if defined(_M_X64)
+ machineType = IMAGE_FILE_MACHINE_AMD64;
+ StackFrame.AddrPC.Offset = ep->ContextRecord->Rip;
+ StackFrame.AddrPC.Mode = AddrModeFlat;
+ StackFrame.AddrStack.Offset = ep->ContextRecord->Rsp;
+ StackFrame.AddrStack.Mode = AddrModeFlat;
+ StackFrame.AddrFrame.Offset = ep->ContextRecord->Rbp;
+ StackFrame.AddrFrame.Mode = AddrModeFlat;
+#elif defined(_M_IX86)
+ machineType = IMAGE_FILE_MACHINE_I386;
StackFrame.AddrPC.Offset = ep->ContextRecord->Eip;
StackFrame.AddrPC.Mode = AddrModeFlat;
StackFrame.AddrStack.Offset = ep->ContextRecord->Esp;
StackFrame.AddrStack.Mode = AddrModeFlat;
StackFrame.AddrFrame.Offset = ep->ContextRecord->Ebp;
StackFrame.AddrFrame.Mode = AddrModeFlat;
+#endif
HANDLE hProcess = GetCurrentProcess();
HANDLE hThread = GetCurrentThread();
@@ -236,9 +375,9 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
SymInitialize(hProcess, NULL, TRUE);
while (true) {
- if (!StackWalk(IMAGE_FILE_MACHINE_I386, hProcess, hThread, &StackFrame,
- ep->ContextRecord, NULL, SymFunctionTableAccess,
- SymGetModuleBase, NULL)) {
+ if (!StackWalk64(machineType, hProcess, hThread, &StackFrame,
+ ep->ContextRecord, NULL, SymFunctionTableAccess64,
+ SymGetModuleBase64, NULL)) {
break;
}
@@ -246,54 +385,66 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
break;
// Print the PC in hexadecimal.
- DWORD PC = StackFrame.AddrPC.Offset;
- fprintf(stderr, "%08lX", PC);
+ DWORD64 PC = StackFrame.AddrPC.Offset;
+#if defined(_M_X64)
+ fprintf(stderr, "0x%016llX", PC);
+#elif defined(_M_IX86)
+ fprintf(stderr, "0x%08lX", static_cast<DWORD>(PC));
+#endif
// Print the parameters. Assume there are four.
+#if defined(_M_X64)
+ fprintf(stderr, " (0x%016llX 0x%016llX 0x%016llX 0x%016llX)",
+ StackFrame.Params[0],
+ StackFrame.Params[1],
+ StackFrame.Params[2],
+ StackFrame.Params[3]);
+#elif defined(_M_IX86)
fprintf(stderr, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)",
- StackFrame.Params[0],
- StackFrame.Params[1], StackFrame.Params[2], StackFrame.Params[3]);
-
+ static_cast<DWORD>(StackFrame.Params[0]),
+ static_cast<DWORD>(StackFrame.Params[1]),
+ static_cast<DWORD>(StackFrame.Params[2]),
+ static_cast<DWORD>(StackFrame.Params[3]));
+#endif
// Verify the PC belongs to a module in this process.
- if (!SymGetModuleBase(hProcess, PC)) {
+ if (!SymGetModuleBase64(hProcess, PC)) {
fputs(" <unknown module>\n", stderr);
continue;
}
// Print the symbol name.
char buffer[512];
- IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL *>(buffer);
- memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL));
- symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL);
- symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL);
+ IMAGEHLP_SYMBOL64 *symbol = reinterpret_cast<IMAGEHLP_SYMBOL64 *>(buffer);
+ memset(symbol, 0, sizeof(IMAGEHLP_SYMBOL64));
+ symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
+ symbol->MaxNameLength = 512 - sizeof(IMAGEHLP_SYMBOL64);
- DWORD dwDisp;
- if (!SymGetSymFromAddr(hProcess, PC, &dwDisp, symbol)) {
+ DWORD64 dwDisp;
+ if (!SymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) {
fputc('\n', stderr);
continue;
}
buffer[511] = 0;
if (dwDisp > 0)
- fprintf(stderr, ", %s()+%04lu bytes(s)", symbol->Name, dwDisp);
+ fprintf(stderr, ", %s() + 0x%llX bytes(s)", symbol->Name, dwDisp);
else
fprintf(stderr, ", %s", symbol->Name);
// Print the source file and line number information.
- IMAGEHLP_LINE line;
+ IMAGEHLP_LINE64 line;
+ DWORD dwLineDisp;
memset(&line, 0, sizeof(line));
line.SizeOfStruct = sizeof(line);
- if (SymGetLineFromAddr(hProcess, PC, &dwDisp, &line)) {
+ if (SymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) {
fprintf(stderr, ", %s, line %lu", line.FileName, line.LineNumber);
- if (dwDisp > 0)
- fprintf(stderr, "+%04lu byte(s)", dwDisp);
+ if (dwLineDisp > 0)
+ fprintf(stderr, " + 0x%lX byte(s)", dwLineDisp);
}
fputc('\n', stderr);
}
-#endif
-
if (ExitOnUnhandledExceptions)
_exit(-3);
@@ -326,3 +477,12 @@ static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
LeaveCriticalSection(&CriticalSection);
return FALSE;
}
+
+#if __MINGW32__
+ // We turned these warnings off for this file so that MinGW-g++ doesn't
+ // complain about the ll format specifiers used. Now we are turning the
+ // warnings back on. If MinGW starts to support diagnostic stacks, we can
+ // replace this with a pop.
+ #pragma GCC diagnostic warning "-Wformat"
+ #pragma GCC diagnostic warning "-Wformat-extra-args"
+#endif
diff --git a/lib/Support/Windows/Windows.h b/lib/Support/Windows/Windows.h
index 4a1553b599d7..67b6f015114f 100644
--- a/lib/Support/Windows/Windows.h
+++ b/lib/Support/Windows/Windows.h
@@ -19,9 +19,9 @@
// mingw-w64 tends to define it as 0x0502 in its headers.
#undef _WIN32_WINNT
-// Require at least Windows 2000 API.
-#define _WIN32_WINNT 0x0500
-#define _WIN32_IE 0x0500 // MinGW at it again.
+// Require at least Windows XP(5.1) API.
+#define _WIN32_WINNT 0x0501
+#define _WIN32_IE 0x0600 // MinGW at it again.
#define WIN32_LEAN_AND_MEAN
#include "llvm/Config/config.h" // Get build system configuration settings
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 5a71fa3d8cea..4927e9a7b9d4 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -84,7 +84,7 @@ void raw_ostream::SetBuffered() {
}
void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size,
- BufferKind Mode) {
+ BufferKind Mode) {
assert(((Mode == Unbuffered && BufferStart == 0 && Size == 0) ||
(Mode != Unbuffered && BufferStart && Size)) &&
"stream must be unbuffered or have at least one byte");
@@ -121,7 +121,8 @@ raw_ostream &raw_ostream::operator<<(unsigned long N) {
raw_ostream &raw_ostream::operator<<(long N) {
if (N < 0) {
*this << '-';
- N = -N;
+ // Avoid undefined behavior on LONG_MIN with a cast.
+ N = -(unsigned long)N;
}
return this->operator<<(static_cast<unsigned long>(N));
@@ -284,7 +285,7 @@ raw_ostream &raw_ostream::write(unsigned char C) {
raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
// Group exceptional cases into a single branch.
- if (BUILTIN_EXPECT(OutBufCur+Size > OutBufEnd, false)) {
+ if (BUILTIN_EXPECT(size_t(OutBufEnd - OutBufCur) < Size, false)) {
if (BUILTIN_EXPECT(!OutBufStart, false)) {
if (BufferMode == Unbuffered) {
write_impl(Ptr, Size);