summaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-05-27 15:15:58 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-05-27 15:15:58 +0000
commit1e3dec662ea18131c495db50caccc57f77b7a5fe (patch)
tree9fad9a5d5dd8c4ff54af48edad9c8cc26dd5fda1 /lib/Support
parent377552607e51dc1d3e6ff33833f9620bcfe815ac (diff)
downloadFreeBSD-src-1e3dec662ea18131c495db50caccc57f77b7a5fe.zip
FreeBSD-src-1e3dec662ea18131c495db50caccc57f77b7a5fe.tar.gz
Update LLVM to r104832.
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APInt.cpp7
-rw-r--r--lib/Support/CommandLine.cpp2
-rw-r--r--lib/Support/ErrorHandling.cpp7
-rw-r--r--lib/Support/PrettyStackTrace.cpp4
-rw-r--r--lib/Support/StringRef.cpp28
-rw-r--r--lib/Support/Timer.cpp4
-rw-r--r--lib/Support/Twine.cpp8
-rw-r--r--lib/Support/raw_ostream.cpp64
8 files changed, 102 insertions, 22 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 50025d2..1341d21 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -1382,13 +1382,12 @@ APInt APInt::sqrt() const {
// libc sqrt function which will probably use a hardware sqrt computation.
// This should be faster than the algorithm below.
if (magnitude < 52) {
-#if defined( _MSC_VER ) || defined(_MINIX)
- // Amazingly, VC++ and Minix don't have round().
+#if HAVE_ROUND
return APInt(BitWidth,
- uint64_t(::sqrt(double(isSingleWord()?VAL:pVal[0]))) + 0.5);
+ uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0])))));
#else
return APInt(BitWidth,
- uint64_t(::round(::sqrt(double(isSingleWord()?VAL:pVal[0])))));
+ uint64_t(::sqrt(double(isSingleWord()?VAL:pVal[0]))) + 0.5);
#endif
}
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index d31f34e..ae66110 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -1170,7 +1170,9 @@ public:
std::string CPU = sys::getHostCPUName();
if (CPU == "generic") CPU = "(unknown)";
OS << ".\n"
+#if (ENABLE_TIMESTAMPS == 1)
<< " Built " << __DATE__ << " (" << __TIME__ << ").\n"
+#endif
<< " Host: " << sys::getHostTriple() << '\n'
<< " Host CPU: " << CPU << '\n'
<< '\n'
diff --git a/lib/Support/ErrorHandling.cpp b/lib/Support/ErrorHandling.cpp
index 56a171c..7e7ca9d 100644
--- a/lib/Support/ErrorHandling.cpp
+++ b/lib/Support/ErrorHandling.cpp
@@ -16,6 +16,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Signals.h"
#include "llvm/System/Threading.h"
#include <cassert>
#include <cstdlib>
@@ -52,6 +53,12 @@ void llvm::report_fatal_error(const Twine &reason) {
} else {
ErrorHandler(ErrorHandlerUserData, reason.str());
}
+
+ // If we reached here, we are failing ungracefully. Run the interrupt handlers
+ // to make sure any special cleanups get done, in particular that we remove
+ // files registered with RemoveFileOnSignal.
+ sys::RunInterruptHandlers();
+
exit(1);
}
diff --git a/lib/Support/PrettyStackTrace.cpp b/lib/Support/PrettyStackTrace.cpp
index 68b41a7..7a04a53 100644
--- a/lib/Support/PrettyStackTrace.cpp
+++ b/lib/Support/PrettyStackTrace.cpp
@@ -50,8 +50,8 @@ static void PrintCurStackTrace(raw_ostream &OS) {
// Integrate with crash reporter.
#ifdef __APPLE__
-extern "C" const char *__crashreporter_info__;
-const char *__crashreporter_info__ = 0;
+static const char *__crashreporter_info__ = 0;
+asm(".desc ___crashreporter_info__, 0x10");
#endif
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
index 2b262dc..ca0f518 100644
--- a/lib/Support/StringRef.cpp
+++ b/lib/Support/StringRef.cpp
@@ -23,6 +23,10 @@ static char ascii_tolower(char x) {
return x;
}
+static bool ascii_isdigit(char x) {
+ return x >= '0' && x <= '9';
+}
+
/// compare_lower - Compare strings, ignoring case.
int StringRef::compare_lower(StringRef RHS) const {
for (size_t I = 0, E = min(Length, RHS.Length); I != E; ++I) {
@@ -37,6 +41,30 @@ int StringRef::compare_lower(StringRef RHS) const {
return Length < RHS.Length ? -1 : 1;
}
+/// 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;
+ 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) {
+ bool ld = J < Length && ascii_isdigit(Data[J]);
+ bool rd = J < RHS.Length && ascii_isdigit(RHS.Data[J]);
+ if (ld != rd)
+ return rd ? -1 : 1;
+ if (!rd)
+ break;
+ }
+ }
+ return Data[I] < RHS.Data[I] ? -1 : 1;
+ }
+ if (Length == RHS.Length)
+ return 0;
+ return Length < RHS.Length ? -1 : 1;
+}
+
// Compute the edit distance between the two given strings.
unsigned StringRef::edit_distance(llvm::StringRef Other,
bool AllowReplacements) {
diff --git a/lib/Support/Timer.cpp b/lib/Support/Timer.cpp
index 481f6ba..784b77c 100644
--- a/lib/Support/Timer.cpp
+++ b/lib/Support/Timer.cpp
@@ -61,6 +61,10 @@ raw_ostream *llvm::CreateInfoOutputFile() {
if (OutputFilename == "-")
return new raw_fd_ostream(1, false); // stdout.
+ // Append mode is used because the info output file is opened and closed
+ // each time -stats or -time-passes wants to print output to it. To
+ // compensate for this, the test-suite Makefiles have code to delete the
+ // info output file before running commands which write to it.
std::string Error;
raw_ostream *Result = new raw_fd_ostream(OutputFilename.c_str(),
Error, raw_fd_ostream::F_Append);
diff --git a/lib/Support/Twine.cpp b/lib/Support/Twine.cpp
index 21504e9..b3ea013 100644
--- a/lib/Support/Twine.cpp
+++ b/lib/Support/Twine.cpp
@@ -48,10 +48,10 @@ void Twine::printOneChild(raw_ostream &OS, const void *Ptr,
OS << *static_cast<const StringRef*>(Ptr);
break;
case Twine::DecUIKind:
- OS << *static_cast<const unsigned int*>(Ptr);
+ OS << (unsigned)(uintptr_t)Ptr;
break;
case Twine::DecIKind:
- OS << *static_cast<const int*>(Ptr);
+ OS << (int)(intptr_t)Ptr;
break;
case Twine::DecULKind:
OS << *static_cast<const unsigned long*>(Ptr);
@@ -95,10 +95,10 @@ void Twine::printOneChildRepr(raw_ostream &OS, const void *Ptr,
<< static_cast<const StringRef*>(Ptr) << "\"";
break;
case Twine::DecUIKind:
- OS << "decUI:\"" << *static_cast<const unsigned int*>(Ptr) << "\"";
+ OS << "decUI:\"" << (unsigned)(uintptr_t)Ptr << "\"";
break;
case Twine::DecIKind:
- OS << "decI:\"" << *static_cast<const int*>(Ptr) << "\"";
+ OS << "decI:\"" << (int)(intptr_t)Ptr << "\"";
break;
case Twine::DecULKind:
OS << "decUL:\"" << *static_cast<const unsigned long*>(Ptr) << "\"";
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 0b05c54..11cf0ec 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -21,6 +21,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/ADT/STLExtras.h"
#include <cctype>
+#include <cerrno>
#include <sys/stat.h>
#include <sys/types.h>
@@ -399,37 +400,76 @@ raw_fd_ostream::raw_fd_ostream(const char *Filename, std::string &ErrorInfo,
if (Flags & F_Excl)
OpenFlags |= O_EXCL;
- FD = open(Filename, OpenFlags, 0664);
- if (FD < 0) {
- ErrorInfo = "Error opening output file '" + std::string(Filename) + "'";
- ShouldClose = false;
- } else {
- ShouldClose = true;
+ while ((FD = open(Filename, OpenFlags, 0664)) < 0) {
+ if (errno != EINTR) {
+ ErrorInfo = "Error opening output file '" + std::string(Filename) + "'";
+ ShouldClose = false;
+ return;
+ }
}
+
+ // Ok, we successfully opened the file, so it'll need to be closed.
+ ShouldClose = true;
}
raw_fd_ostream::~raw_fd_ostream() {
if (FD < 0) return;
flush();
if (ShouldClose)
- if (::close(FD) != 0)
- error_detected();
+ while (::close(FD) != 0)
+ if (errno != EINTR) {
+ error_detected();
+ break;
+ }
}
void raw_fd_ostream::write_impl(const char *Ptr, size_t Size) {
assert(FD >= 0 && "File already closed.");
pos += Size;
- if (::write(FD, Ptr, Size) != (ssize_t) Size)
- error_detected();
+ ssize_t ret;
+
+ do {
+ ret = ::write(FD, Ptr, Size);
+
+ if (ret < 0) {
+ // If it's a recoverable error, swallow it and retry the write.
+ //
+ // Ideally we wouldn't ever see EAGAIN or EWOULDBLOCK here, since
+ // raw_ostream isn't designed to do non-blocking I/O. However, some
+ // programs, such as old versions of bjam, have mistakenly used
+ // O_NONBLOCK. For compatibility, emulate blocking semantics by
+ // spinning until the write succeeds. If you don't want spinning,
+ // don't use O_NONBLOCK file descriptors with raw_ostream.
+ if (errno == EINTR || errno == EAGAIN
+#ifdef EWOULDBLOCK
+ || errno == EWOULDBLOCK
+#endif
+ )
+ continue;
+
+ // Otherwise it's a non-recoverable error. Note it and quit.
+ error_detected();
+ break;
+ }
+
+ // The write may have written some or all of the data. Update the
+ // size and buffer pointer to reflect the remainder that needs
+ // to be written. If there are no bytes left, we're done.
+ Ptr += ret;
+ Size -= ret;
+ } while (Size > 0);
}
void raw_fd_ostream::close() {
assert(ShouldClose);
ShouldClose = false;
flush();
- if (::close(FD) != 0)
- error_detected();
+ while (::close(FD) != 0)
+ if (errno != EINTR) {
+ error_detected();
+ break;
+ }
FD = -1;
}
OpenPOWER on IntegriCloud