summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support')
-rw-r--r--contrib/llvm/lib/Support/CommandLine.cpp228
-rw-r--r--contrib/llvm/lib/Support/Compression.cpp97
-rw-r--r--contrib/llvm/lib/Support/DataExtractor.cpp2
-rw-r--r--contrib/llvm/lib/Support/FoldingSet.cpp4
-rw-r--r--contrib/llvm/lib/Support/Host.cpp39
-rw-r--r--contrib/llvm/lib/Support/LockFileManager.cpp37
-rw-r--r--contrib/llvm/lib/Support/PathV2.cpp7
-rw-r--r--contrib/llvm/lib/Support/Triple.cpp8
-rw-r--r--contrib/llvm/lib/Support/Unix/Memory.inc2
-rw-r--r--contrib/llvm/lib/Support/Unix/PathV2.inc4
-rw-r--r--contrib/llvm/lib/Support/Unix/Program.inc24
-rw-r--r--contrib/llvm/lib/Support/Unix/Signals.inc21
-rw-r--r--contrib/llvm/lib/Support/Windows/Program.inc71
-rw-r--r--contrib/llvm/lib/Support/Windows/Signals.inc22
-rw-r--r--contrib/llvm/lib/Support/YAMLParser.cpp2
15 files changed, 508 insertions, 60 deletions
diff --git a/contrib/llvm/lib/Support/CommandLine.cpp b/contrib/llvm/lib/Support/CommandLine.cpp
index 560d7eb..18d3db5 100644
--- a/contrib/llvm/lib/Support/CommandLine.cpp
+++ b/contrib/llvm/lib/Support/CommandLine.cpp
@@ -33,6 +33,7 @@
#include "llvm/Support/system_error.h"
#include <cerrno>
#include <cstdlib>
+#include <map>
using namespace llvm;
using namespace cl;
@@ -106,6 +107,17 @@ void Option::addArgument() {
MarkOptionsChanged();
}
+// This collects the different option categories that have been registered.
+typedef SmallPtrSet<OptionCategory*,16> OptionCatSet;
+static ManagedStatic<OptionCatSet> RegisteredOptionCategories;
+
+// Initialise the general option category.
+OptionCategory llvm::cl::GeneralCategory("General options");
+
+void OptionCategory::registerCategory()
+{
+ RegisteredOptionCategories->insert(this);
+}
//===----------------------------------------------------------------------===//
// Basic, shared command line option processing machinery.
@@ -1222,11 +1234,20 @@ sortOpts(StringMap<Option*> &OptMap,
namespace {
class HelpPrinter {
+protected:
const bool ShowHidden;
+ typedef SmallVector<std::pair<const char *, Option*>,128> StrOptionPairVector;
+ // Print the options. Opts is assumed to be alphabetically sorted.
+ virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
+ for (size_t i = 0, e = Opts.size(); i != e; ++i)
+ Opts[i].second->printOptionInfo(MaxArgLen);
+ }
public:
explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}
+ virtual ~HelpPrinter() {}
+ // Invoke the printer.
void operator=(bool Value) {
if (Value == false) return;
@@ -1236,7 +1257,7 @@ public:
StringMap<Option*> OptMap;
GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
- SmallVector<std::pair<const char *, Option*>, 128> Opts;
+ StrOptionPairVector Opts;
sortOpts(OptMap, Opts, ShowHidden);
if (ProgramOverview)
@@ -1267,12 +1288,12 @@ public:
MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());
outs() << "OPTIONS:\n";
- for (size_t i = 0, e = Opts.size(); i != e; ++i)
- Opts[i].second->printOptionInfo(MaxArgLen);
+ printOptions(Opts, MaxArgLen);
// Print any extra help the user has declared.
for (std::vector<const char *>::iterator I = MoreHelp->begin(),
- E = MoreHelp->end(); I != E; ++I)
+ E = MoreHelp->end();
+ I != E; ++I)
outs() << *I;
MoreHelp->clear();
@@ -1280,21 +1301,152 @@ public:
exit(1);
}
};
+
+class CategorizedHelpPrinter : public HelpPrinter {
+public:
+ explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {}
+
+ // Helper function for printOptions().
+ // It shall return true if A's name should be lexographically
+ // ordered before B's name. It returns false otherwise.
+ static bool OptionCategoryCompare(OptionCategory *A, OptionCategory *B) {
+ int Length = strcmp(A->getName(), B->getName());
+ assert(Length != 0 && "Duplicate option categories");
+ return Length < 0;
+ }
+
+ // Make sure we inherit our base class's operator=()
+ using HelpPrinter::operator= ;
+
+protected:
+ virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
+ std::vector<OptionCategory *> SortedCategories;
+ std::map<OptionCategory *, std::vector<Option *> > CategorizedOptions;
+
+ // Collect registered option categories into vector in preperation for
+ // sorting.
+ for (OptionCatSet::const_iterator I = RegisteredOptionCategories->begin(),
+ E = RegisteredOptionCategories->end();
+ I != E; ++I)
+ SortedCategories.push_back(*I);
+
+ // Sort the different option categories alphabetically.
+ assert(SortedCategories.size() > 0 && "No option categories registered!");
+ std::sort(SortedCategories.begin(), SortedCategories.end(),
+ OptionCategoryCompare);
+
+ // Create map to empty vectors.
+ for (std::vector<OptionCategory *>::const_iterator
+ I = SortedCategories.begin(),
+ E = SortedCategories.end();
+ I != E; ++I)
+ CategorizedOptions[*I] = std::vector<Option *>();
+
+ // Walk through pre-sorted options and assign into categories.
+ // Because the options are already alphabetically sorted the
+ // options within categories will also be alphabetically sorted.
+ for (size_t I = 0, E = Opts.size(); I != E; ++I) {
+ Option *Opt = Opts[I].second;
+ assert(CategorizedOptions.count(Opt->Category) > 0 &&
+ "Option has an unregistered category");
+ CategorizedOptions[Opt->Category].push_back(Opt);
+ }
+
+ // Now do printing.
+ for (std::vector<OptionCategory *>::const_iterator
+ Category = SortedCategories.begin(),
+ E = SortedCategories.end();
+ Category != E; ++Category) {
+ // Hide empty categories for -help, but show for -help-hidden.
+ bool IsEmptyCategory = CategorizedOptions[*Category].size() == 0;
+ if (!ShowHidden && IsEmptyCategory)
+ continue;
+
+ // Print category information.
+ outs() << "\n";
+ outs() << (*Category)->getName() << ":\n";
+
+ // Check if description is set.
+ if ((*Category)->getDescription() != 0)
+ outs() << (*Category)->getDescription() << "\n\n";
+ else
+ outs() << "\n";
+
+ // When using -help-hidden explicitly state if the category has no
+ // options associated with it.
+ if (IsEmptyCategory) {
+ outs() << " This option category has no options.\n";
+ continue;
+ }
+ // Loop over the options in the category and print.
+ for (std::vector<Option *>::const_iterator
+ Opt = CategorizedOptions[*Category].begin(),
+ E = CategorizedOptions[*Category].end();
+ Opt != E; ++Opt)
+ (*Opt)->printOptionInfo(MaxArgLen);
+ }
+ }
+};
+
+// This wraps the Uncategorizing and Categorizing printers and decides
+// at run time which should be invoked.
+class HelpPrinterWrapper {
+private:
+ HelpPrinter &UncategorizedPrinter;
+ CategorizedHelpPrinter &CategorizedPrinter;
+
+public:
+ explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter,
+ CategorizedHelpPrinter &CategorizedPrinter) :
+ UncategorizedPrinter(UncategorizedPrinter),
+ CategorizedPrinter(CategorizedPrinter) { }
+
+ // Invoke the printer.
+ void operator=(bool Value);
+};
+
} // End anonymous namespace
-// Define the two HelpPrinter instances that are used to print out help, or
-// help-hidden...
-//
-static HelpPrinter NormalPrinter(false);
-static HelpPrinter HiddenPrinter(true);
+// Declare the four HelpPrinter instances that are used to print out help, or
+// help-hidden as an uncategorized list or in categories.
+static HelpPrinter UncategorizedNormalPrinter(false);
+static HelpPrinter UncategorizedHiddenPrinter(true);
+static CategorizedHelpPrinter CategorizedNormalPrinter(false);
+static CategorizedHelpPrinter CategorizedHiddenPrinter(true);
+
+// Declare HelpPrinter wrappers that will decide whether or not to invoke
+// a categorizing help printer
+static HelpPrinterWrapper WrappedNormalPrinter(UncategorizedNormalPrinter,
+ CategorizedNormalPrinter);
+static HelpPrinterWrapper WrappedHiddenPrinter(UncategorizedHiddenPrinter,
+ CategorizedHiddenPrinter);
+
+// Define uncategorized help printers.
+// -help-list is hidden by default because if Option categories are being used
+// then -help behaves the same as -help-list.
static cl::opt<HelpPrinter, true, parser<bool> >
-HOp("help", cl::desc("Display available options (-help-hidden for more)"),
- cl::location(NormalPrinter), cl::ValueDisallowed);
+HLOp("help-list",
+ cl::desc("Display list of available options (-help-list-hidden for more)"),
+ cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed);
static cl::opt<HelpPrinter, true, parser<bool> >
+HLHOp("help-list-hidden",
+ cl::desc("Display list of all available options"),
+ cl::location(UncategorizedHiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+
+// Define uncategorized/categorized help printers. These printers change their
+// behaviour at runtime depending on whether one or more Option categories have
+// been declared.
+static cl::opt<HelpPrinterWrapper, true, parser<bool> >
+HOp("help", cl::desc("Display available options (-help-hidden for more)"),
+ cl::location(WrappedNormalPrinter), cl::ValueDisallowed);
+
+static cl::opt<HelpPrinterWrapper, true, parser<bool> >
HHOp("help-hidden", cl::desc("Display all available options"),
- cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+ cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+
+
static cl::opt<bool>
PrintOptions("print-options",
@@ -1306,6 +1458,24 @@ PrintAllOptions("print-all-options",
cl::desc("Print all option values after command line parsing"),
cl::Hidden, cl::init(false));
+void HelpPrinterWrapper::operator=(bool Value) {
+ if (Value == false)
+ return;
+
+ // Decide which printer to invoke. If more than one option category is
+ // registered then it is useful to show the categorized help instead of
+ // uncategorized help.
+ if (RegisteredOptionCategories->size() > 1) {
+ // unhide -help-list option so user can have uncategorized output if they
+ // want it.
+ HLOp.setHiddenFlag(NotHidden);
+
+ CategorizedPrinter = true; // Invoke categorized printer
+ }
+ else
+ UncategorizedPrinter = true; // Invoke uncategorized printer
+}
+
// Print the value of each option.
void cl::PrintOptionValues() {
if (!PrintOptions && !PrintAllOptions) return;
@@ -1393,14 +1563,22 @@ VersOp("version", cl::desc("Display the version of this program"),
cl::location(VersionPrinterInstance), cl::ValueDisallowed);
// Utility function for printing the help message.
-void cl::PrintHelpMessage() {
- // This looks weird, but it actually prints the help message. The
- // NormalPrinter variable is a HelpPrinter and the help gets printed when
- // its operator= is invoked. That's because the "normal" usages of the
- // help printer is to be assigned true/false depending on whether the
- // -help option was given or not. Since we're circumventing that we have
- // to make it look like -help was given, so we assign true.
- NormalPrinter = true;
+void cl::PrintHelpMessage(bool Hidden, bool Categorized) {
+ // This looks weird, but it actually prints the help message. The Printers are
+ // types of HelpPrinter and the help gets printed when its operator= is
+ // invoked. That's because the "normal" usages of the help printer is to be
+ // assigned true/false depending on whether -help or -help-hidden was given or
+ // not. Since we're circumventing that we have to make it look like -help or
+ // -help-hidden were given, so we assign true.
+
+ if (!Hidden && !Categorized)
+ UncategorizedNormalPrinter = true;
+ else if (!Hidden && Categorized)
+ CategorizedNormalPrinter = true;
+ else if (Hidden && !Categorized)
+ UncategorizedHiddenPrinter = true;
+ else
+ CategorizedHiddenPrinter = true;
}
/// Utility function for printing version number.
@@ -1418,3 +1596,13 @@ void cl::AddExtraVersionPrinter(void (*func)()) {
ExtraVersionPrinters->push_back(func);
}
+
+void cl::getRegisteredOptions(StringMap<Option*> &Map)
+{
+ // Get all the options.
+ SmallVector<Option*, 4> PositionalOpts; //NOT USED
+ SmallVector<Option*, 4> SinkOpts; //NOT USED
+ assert(Map.size() == 0 && "StringMap must be empty");
+ GetOptionInfo(PositionalOpts, SinkOpts, Map);
+ return;
+}
diff --git a/contrib/llvm/lib/Support/Compression.cpp b/contrib/llvm/lib/Support/Compression.cpp
new file mode 100644
index 0000000..fd8a874
--- /dev/null
+++ b/contrib/llvm/lib/Support/Compression.cpp
@@ -0,0 +1,97 @@
+//===--- Compression.cpp - Compression implementation ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements compression functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Compression.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+using namespace llvm;
+
+#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ
+static int encodeZlibCompressionLevel(zlib::CompressionLevel Level) {
+ switch (Level) {
+ case zlib::NoCompression: return 0;
+ case zlib::BestSpeedCompression: return 1;
+ case zlib::DefaultCompression: return Z_DEFAULT_COMPRESSION;
+ case zlib::BestSizeCompression: return 9;
+ }
+ llvm_unreachable("Invalid zlib::CompressionLevel!");
+}
+
+static zlib::Status encodeZlibReturnValue(int ReturnValue) {
+ switch (ReturnValue) {
+ case Z_OK: return zlib::StatusOK;
+ case Z_MEM_ERROR: return zlib::StatusOutOfMemory;
+ case Z_BUF_ERROR: return zlib::StatusBufferTooShort;
+ case Z_STREAM_ERROR: return zlib::StatusInvalidArg;
+ case Z_DATA_ERROR: return zlib::StatusInvalidData;
+ default: llvm_unreachable("unknown zlib return status!");
+ }
+}
+
+bool zlib::isAvailable() { return true; }
+zlib::Status zlib::compress(StringRef InputBuffer,
+ OwningPtr<MemoryBuffer> &CompressedBuffer,
+ CompressionLevel Level) {
+ unsigned long CompressedSize = ::compressBound(InputBuffer.size());
+ OwningArrayPtr<char> TmpBuffer(new char[CompressedSize]);
+ int CLevel = encodeZlibCompressionLevel(Level);
+ Status Res = encodeZlibReturnValue(::compress2(
+ (Bytef *)TmpBuffer.get(), &CompressedSize,
+ (const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel));
+ if (Res == StatusOK) {
+ CompressedBuffer.reset(MemoryBuffer::getMemBufferCopy(
+ StringRef(TmpBuffer.get(), CompressedSize)));
+ // Tell MSan that memory initialized by zlib is valid.
+ __msan_unpoison(CompressedBuffer->getBufferStart(), CompressedSize);
+ }
+ return Res;
+}
+
+zlib::Status zlib::uncompress(StringRef InputBuffer,
+ OwningPtr<MemoryBuffer> &UncompressedBuffer,
+ size_t UncompressedSize) {
+ OwningArrayPtr<char> TmpBuffer(new char[UncompressedSize]);
+ Status Res = encodeZlibReturnValue(
+ ::uncompress((Bytef *)TmpBuffer.get(), (uLongf *)&UncompressedSize,
+ (const Bytef *)InputBuffer.data(), InputBuffer.size()));
+ if (Res == StatusOK) {
+ UncompressedBuffer.reset(MemoryBuffer::getMemBufferCopy(
+ StringRef(TmpBuffer.get(), UncompressedSize)));
+ // Tell MSan that memory initialized by zlib is valid.
+ __msan_unpoison(UncompressedBuffer->getBufferStart(), UncompressedSize);
+ }
+ return Res;
+}
+
+#else
+bool zlib::isAvailable() { return false; }
+zlib::Status zlib::compress(StringRef InputBuffer,
+ OwningPtr<MemoryBuffer> &CompressedBuffer,
+ CompressionLevel Level) {
+ return zlib::StatusUnsupported;
+}
+zlib::Status zlib::uncompress(StringRef InputBuffer,
+ OwningPtr<MemoryBuffer> &UncompressedBuffer,
+ size_t UncompressedSize) {
+ return zlib::StatusUnsupported;
+}
+#endif
+
diff --git a/contrib/llvm/lib/Support/DataExtractor.cpp b/contrib/llvm/lib/Support/DataExtractor.cpp
index 3d5cce0..a564d21 100644
--- a/contrib/llvm/lib/Support/DataExtractor.cpp
+++ b/contrib/llvm/lib/Support/DataExtractor.cpp
@@ -20,7 +20,7 @@ static T getU(uint32_t *offset_ptr, const DataExtractor *de,
uint32_t offset = *offset_ptr;
if (de->isValidOffsetForDataOfSize(offset, sizeof(val))) {
std::memcpy(&val, &Data[offset], sizeof(val));
- if (sys::isLittleEndianHost() != isLittleEndian)
+ if (sys::IsLittleEndianHost != isLittleEndian)
val = sys::SwapByteOrder(val);
// Advance the offset
diff --git a/contrib/llvm/lib/Support/FoldingSet.cpp b/contrib/llvm/lib/Support/FoldingSet.cpp
index 36e33b5..145f12d 100644
--- a/contrib/llvm/lib/Support/FoldingSet.cpp
+++ b/contrib/llvm/lib/Support/FoldingSet.cpp
@@ -101,7 +101,7 @@ void FoldingSetNodeID::AddString(StringRef String) {
// Otherwise do it the hard way.
// To be compatible with above bulk transfer, we need to take endianness
// into account.
- if (sys::isBigEndianHost()) {
+ if (sys::IsBigEndianHost) {
for (Pos += 4; Pos <= Size; Pos += 4) {
unsigned V = ((unsigned char)String[Pos - 4] << 24) |
((unsigned char)String[Pos - 3] << 16) |
@@ -110,7 +110,7 @@ void FoldingSetNodeID::AddString(StringRef String) {
Bits.push_back(V);
}
} else {
- assert(sys::isLittleEndianHost() && "Unexpected host endianness");
+ assert(sys::IsLittleEndianHost && "Unexpected host endianness");
for (Pos += 4; Pos <= Size; Pos += 4) {
unsigned V = ((unsigned char)String[Pos - 1] << 24) |
((unsigned char)String[Pos - 2] << 16) |
diff --git a/contrib/llvm/lib/Support/Host.cpp b/contrib/llvm/lib/Support/Host.cpp
index 73d98d1..a7c7a95 100644
--- a/contrib/llvm/lib/Support/Host.cpp
+++ b/contrib/llvm/lib/Support/Host.cpp
@@ -112,19 +112,19 @@ static bool GetX86CpuIDAndInfo(unsigned value, unsigned *rEAX,
#endif
}
-static bool OSHasAVXSupport() {
-#if defined(__GNUC__)
- // Check xgetbv; this uses a .byte sequence instead of the instruction
- // directly because older assemblers do not include support for xgetbv and
- // there is no easy way to conditionally compile based on the assembler used.
- int rEAX, rEDX;
- __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (rEAX), "=d" (rEDX) : "c" (0));
-#elif defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 160040219
- unsigned long long rEAX = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
-#else
- int rEAX = 0; // Ensures we return false
-#endif
- return (rEAX & 6) == 6;
+static bool OSHasAVXSupport() {
+#if defined(__GNUC__)
+ // Check xgetbv; this uses a .byte sequence instead of the instruction
+ // directly because older assemblers do not include support for xgetbv and
+ // there is no easy way to conditionally compile based on the assembler used.
+ int rEAX, rEDX;
+ __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a" (rEAX), "=d" (rEDX) : "c" (0));
+#elif defined(_MSC_FULL_VER) && defined(_XCR_XFEATURE_ENABLED_MASK)
+ unsigned long long rEAX = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
+#else
+ int rEAX = 0; // Ensures we return false
+#endif
+ return (rEAX & 6) == 6;
}
static void DetectX86FamilyModel(unsigned EAX, unsigned &Family,
@@ -355,10 +355,15 @@ std::string sys::getHostCPUName() {
case 20:
return "btver1";
case 21:
- if (Model <= 15)
- return "bdver1";
- else if (Model <= 31)
+ if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
+ return "btver1";
+ if (Model > 15 && Model <= 31)
return "bdver2";
+ return "bdver1";
+ case 22:
+ if (!HasAVX) // If the OS doesn't support AVX provide a sane fallback.
+ return "btver1";
+ return "btver2";
default:
return "generic";
}
@@ -608,7 +613,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features){
#endif
std::string sys::getProcessTriple() {
- Triple PT(LLVM_HOSTTRIPLE);
+ Triple PT(LLVM_HOST_TRIPLE);
if (sizeof(void *) == 8 && PT.isArch32Bit())
PT = PT.get64BitArchVariant();
diff --git a/contrib/llvm/lib/Support/LockFileManager.cpp b/contrib/llvm/lib/Support/LockFileManager.cpp
index 92d8b83..2917e27 100644
--- a/contrib/llvm/lib/Support/LockFileManager.cpp
+++ b/contrib/llvm/lib/Support/LockFileManager.cpp
@@ -174,8 +174,8 @@ void LockFileManager::waitForUnlock() {
Interval.tv_sec = 0;
Interval.tv_nsec = 1000000;
#endif
- // Don't wait more than an hour for the file to appear.
- const unsigned MaxSeconds = 3600;
+ // Don't wait more than five minutes for the file to appear.
+ unsigned MaxSeconds = 300;
bool LockFileGone = false;
do {
// Sleep for the designated interval, to allow the owning process time to
@@ -187,21 +187,48 @@ void LockFileManager::waitForUnlock() {
#else
nanosleep(&Interval, NULL);
#endif
- // If the lock file no longer exists, wait for the actual file.
bool Exists = false;
+ bool LockFileJustDisappeared = false;
+
+ // If the lock file is still expected to be there, check whether it still
+ // is.
if (!LockFileGone) {
if (!sys::fs::exists(LockFileName.str(), Exists) && !Exists) {
LockFileGone = true;
+ LockFileJustDisappeared = true;
Exists = false;
}
}
+
+ // If the lock file is no longer there, check if the original file is
+ // available now.
if (LockFileGone) {
- if (!sys::fs::exists(FileName.str(), Exists) && Exists)
+ if (!sys::fs::exists(FileName.str(), Exists) && Exists) {
return;
+ }
+
+ // The lock file is gone, so now we're waiting for the original file to
+ // show up. If this just happened, reset our waiting intervals and keep
+ // waiting.
+ if (LockFileJustDisappeared) {
+ MaxSeconds = 5;
+
+#if LLVM_ON_WIN32
+ Interval = 1;
+#else
+ Interval.tv_sec = 0;
+ Interval.tv_nsec = 1000000;
+#endif
+ continue;
+ }
}
- if (!processStillExecuting((*Owner).first, (*Owner).second))
+ // If we're looking for the lock file to disappear, but the process
+ // owning the lock died without cleaning up, just bail out.
+ if (!LockFileGone &&
+ !processStillExecuting((*Owner).first, (*Owner).second)) {
return;
+ }
// Exponentially increase the time we wait for the lock to be removed.
#if LLVM_ON_WIN32
diff --git a/contrib/llvm/lib/Support/PathV2.cpp b/contrib/llvm/lib/Support/PathV2.cpp
index 58a6ea7..ac53a9e9 100644
--- a/contrib/llvm/lib/Support/PathV2.cpp
+++ b/contrib/llvm/lib/Support/PathV2.cpp
@@ -789,8 +789,11 @@ file_magic identify_magic(StringRef magic) {
case '\177':
if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') {
- if (magic.size() >= 18 && magic[17] == 0)
- switch (magic[16]) {
+ bool Data2MSB = magic[5] == 2;
+ unsigned high = Data2MSB ? 16 : 17;
+ unsigned low = Data2MSB ? 17 : 16;
+ if (magic.size() >= 18 && magic[high] == 0)
+ switch (magic[low]) {
default: break;
case 1: return file_magic::elf_relocatable;
case 2: return file_magic::elf_executable;
diff --git a/contrib/llvm/lib/Support/Triple.cpp b/contrib/llvm/lib/Support/Triple.cpp
index d2508ac..412e34c 100644
--- a/contrib/llvm/lib/Support/Triple.cpp
+++ b/contrib/llvm/lib/Support/Triple.cpp
@@ -32,6 +32,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case r600: return "r600";
case sparc: return "sparc";
case sparcv9: return "sparcv9";
+ case systemz: return "s390x";
case tce: return "tce";
case thumb: return "thumb";
case x86: return "i386";
@@ -76,6 +77,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case sparcv9:
case sparc: return "sparc";
+ case systemz: return "systemz";
+
case x86:
case x86_64: return "x86";
@@ -170,6 +173,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("hexagon", hexagon)
.Case("sparc", sparc)
.Case("sparcv9", sparcv9)
+ .Case("systemz", systemz)
.Case("tce", tce)
.Case("thumb", thumb)
.Case("x86", x86)
@@ -233,6 +237,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("mips64el", Triple::mips64el)
.Case("r600", Triple::r600)
.Case("hexagon", Triple::hexagon)
+ .Case("s390x", Triple::systemz)
.Case("sparc", Triple::sparc)
.Case("sparcv9", Triple::sparcv9)
.Case("tce", Triple::tce)
@@ -687,6 +692,7 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::nvptx64:
case llvm::Triple::ppc64:
case llvm::Triple::sparcv9:
+ case llvm::Triple::systemz:
case llvm::Triple::x86_64:
case llvm::Triple::spir64:
return 64;
@@ -712,6 +718,7 @@ Triple Triple::get32BitArchVariant() const {
case Triple::UnknownArch:
case Triple::aarch64:
case Triple::msp430:
+ case Triple::systemz:
T.setArch(UnknownArch);
break;
@@ -769,6 +776,7 @@ Triple Triple::get64BitArchVariant() const {
case Triple::nvptx64:
case Triple::ppc64:
case Triple::sparcv9:
+ case Triple::systemz:
case Triple::x86_64:
// Already 64-bit.
break;
diff --git a/contrib/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm/lib/Support/Unix/Memory.inc
index f397408..2bb9bf1 100644
--- a/contrib/llvm/lib/Support/Unix/Memory.inc
+++ b/contrib/llvm/lib/Support/Unix/Memory.inc
@@ -325,7 +325,7 @@ void Memory::InvalidateInstructionCache(const void *Addr,
for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
asm volatile("icbi 0, %0" : : "r"(Line));
asm volatile("isync");
-# elif defined(__arm__) && defined(__GNUC__) && !defined(__FreeBSD__)
+# elif (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__) && !defined(__FreeBSD__)
// FIXME: Can we safely always call this for __GNUC__ everywhere?
const char *Start = static_cast<const char *>(Addr);
const char *End = Start + Len;
diff --git a/contrib/llvm/lib/Support/Unix/PathV2.inc b/contrib/llvm/lib/Support/Unix/PathV2.inc
index a3dfd4b..7e0aead 100644
--- a/contrib/llvm/lib/Support/Unix/PathV2.inc
+++ b/contrib/llvm/lib/Support/Unix/PathV2.inc
@@ -430,9 +430,7 @@ rety_open_create:
if (SavedErrno == errc::file_exists)
goto retry_random_path;
// If path prefix doesn't exist, try to create it.
- if (SavedErrno == errc::no_such_file_or_directory &&
- !exists(path::parent_path(RandomPath)) &&
- !TriedToCreateParent) {
+ if (SavedErrno == errc::no_such_file_or_directory && !TriedToCreateParent) {
TriedToCreateParent = true;
StringRef p(RandomPath);
SmallString<64> dir_to_create;
diff --git a/contrib/llvm/lib/Support/Unix/Program.inc b/contrib/llvm/lib/Support/Unix/Program.inc
index 117151c..aa03d48 100644
--- a/contrib/llvm/lib/Support/Unix/Program.inc
+++ b/contrib/llvm/lib/Support/Unix/Program.inc
@@ -32,6 +32,9 @@
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#ifdef HAVE_POSIX_SPAWN
#include <spawn.h>
#if !defined(__APPLE__)
@@ -409,4 +412,25 @@ error_code Program::ChangeStderrToBinary(){
return make_error_code(errc::success);
}
+bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
+ static long ArgMax = sysconf(_SC_ARG_MAX);
+
+ // System says no practical limit.
+ if (ArgMax == -1)
+ return true;
+
+ // Conservatively account for space required by environment variables.
+ ArgMax /= 2;
+
+ size_t ArgLength = 0;
+ for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
+ I != E; ++I) {
+ ArgLength += strlen(*I) + 1;
+ if (ArgLength > size_t(ArgMax)) {
+ return false;
+ }
+ }
+ return true;
+}
+
}
diff --git a/contrib/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm/lib/Support/Unix/Signals.inc
index 66338f1..64d1fc1 100644
--- a/contrib/llvm/lib/Support/Unix/Signals.inc
+++ b/contrib/llvm/lib/Support/Unix/Signals.inc
@@ -27,10 +27,12 @@
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
-#if HAVE_DLFCN_H && __GNUG__
-#include <dlfcn.h>
+#if HAVE_CXXABI_H
#include <cxxabi.h>
#endif
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
#if HAVE_MACH_MACH_H
#include <mach/mach.h>
#endif
@@ -184,6 +186,15 @@ static RETSIGTYPE SignalHandler(int Sig) {
// Otherwise if it is a fault (like SEGV) run any handler.
for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i)
CallBacksToRun[i].first(CallBacksToRun[i].second);
+
+#ifdef __s390__
+ // On S/390, certain signals are delivered with PSW Address pointing to
+ // *after* the faulting instruction. Simply returning from the signal
+ // handler would continue execution after that point, instead of
+ // re-raising the signal. Raise the signal manually in those cases.
+ if (Sig == SIGILL || Sig == SIGFPE || Sig == SIGTRAP)
+ raise(Sig);
+#endif
}
void llvm::sys::RunInterruptHandlers() {
@@ -290,9 +301,13 @@ void llvm::sys::PrintStackTrace(FILE *FD) {
(int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]);
if (dlinfo.dli_sname != NULL) {
- int res;
fputc(' ', FD);
+# if HAVE_CXXABI_H
+ int res;
char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res);
+# else
+ char* d = NULL;
+# endif
if (d == NULL) fputs(dlinfo.dli_sname, FD);
else fputs(d, FD);
free(d);
diff --git a/contrib/llvm/lib/Support/Windows/Program.inc b/contrib/llvm/lib/Support/Windows/Program.inc
index 691d6d4..619ae5d 100644
--- a/contrib/llvm/lib/Support/Windows/Program.inc
+++ b/contrib/llvm/lib/Support/Windows/Program.inc
@@ -126,20 +126,58 @@ static bool ArgNeedsQuotes(const char *Str) {
return Str[0] == '\0' || strpbrk(Str, "\t \"&\'()*<>\\`^|") != 0;
}
+/// CountPrecedingBackslashes - Returns the number of backslashes preceding Cur
+/// in the C string Start.
+static unsigned int CountPrecedingBackslashes(const char *Start,
+ const char *Cur) {
+ unsigned int Count = 0;
+ --Cur;
+ while (Cur >= Start && *Cur == '\\') {
+ ++Count;
+ --Cur;
+ }
+ return Count;
+}
+
+/// EscapePrecedingEscapes - Append a backslash to Dst for every backslash
+/// preceding Cur in the Start string. Assumes Dst has enough space.
+static char *EscapePrecedingEscapes(char *Dst, const char *Start,
+ const char *Cur) {
+ unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Cur);
+ while (PrecedingEscapes > 0) {
+ *Dst++ = '\\';
+ --PrecedingEscapes;
+ }
+ return Dst;
+}
/// ArgLenWithQuotes - Check whether argument needs to be quoted when calling
/// CreateProcess and returns length of quoted arg with escaped quotes
static unsigned int ArgLenWithQuotes(const char *Str) {
- unsigned int len = ArgNeedsQuotes(Str) ? 2 : 0;
+ const char *Start = Str;
+ bool Quoted = ArgNeedsQuotes(Str);
+ unsigned int len = Quoted ? 2 : 0;
while (*Str != '\0') {
- if (*Str == '\"')
- ++len;
+ if (*Str == '\"') {
+ // We need to add a backslash, but ensure that it isn't escaped.
+ unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Str);
+ len += PrecedingEscapes + 1;
+ }
+ // Note that we *don't* need to escape runs of backslashes that don't
+ // precede a double quote! See MSDN:
+ // http://msdn.microsoft.com/en-us/library/17w5ykft%28v=vs.85%29.aspx
++len;
++Str;
}
+ if (Quoted) {
+ // Make sure the closing quote doesn't get escaped by a trailing backslash.
+ unsigned PrecedingEscapes = CountPrecedingBackslashes(Start, Str);
+ len += PrecedingEscapes + 1;
+ }
+
return len;
}
@@ -180,20 +218,27 @@ Program::Execute(const Path& path,
for (unsigned i = 0; args[i]; i++) {
const char *arg = args[i];
+ const char *start = arg;
bool needsQuoting = ArgNeedsQuotes(arg);
if (needsQuoting)
*p++ = '"';
while (*arg != '\0') {
- if (*arg == '\"')
+ if (*arg == '\"') {
+ // Escape all preceding escapes (if any), and then escape the quote.
+ p = EscapePrecedingEscapes(p, start, arg);
*p++ = '\\';
+ }
*p++ = *arg++;
}
- if (needsQuoting)
+ if (needsQuoting) {
+ // Make sure our quote doesn't get escaped by a trailing backslash.
+ p = EscapePrecedingEscapes(p, start, arg);
*p++ = '"';
+ }
*p++ = ' ';
}
@@ -396,4 +441,20 @@ error_code Program::ChangeStderrToBinary(){
return make_error_code(errc::success);
}
+bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef<const char*> Args) {
+ // The documented max length of the command line passed to CreateProcess.
+ static const size_t MaxCommandStringLength = 32768;
+ size_t ArgLength = 0;
+ for (ArrayRef<const char*>::iterator I = Args.begin(), E = Args.end();
+ I != E; ++I) {
+ // Account for the trailing space for every arg but the last one and the
+ // trailing NULL of the last argument.
+ ArgLength += ArgLenWithQuotes(*I) + 1;
+ if (ArgLength > MaxCommandStringLength) {
+ return false;
+ }
+ }
+ return true;
+}
+
}
diff --git a/contrib/llvm/lib/Support/Windows/Signals.inc b/contrib/llvm/lib/Support/Windows/Signals.inc
index 3dd6660..b18b4d1 100644
--- a/contrib/llvm/lib/Support/Windows/Signals.inc
+++ b/contrib/llvm/lib/Support/Windows/Signals.inc
@@ -178,6 +178,19 @@ namespace llvm {
//===----------------------------------------------------------------------===//
#ifdef _MSC_VER
+/// AvoidMessageBoxHook - Emulates hitting "retry" from an "abort, retry,
+/// ignore" CRT debug report dialog. "retry" raises an exception which
+/// ultimately triggers our stack dumper.
+static int AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
+ // Set *Return to the retry code for the return value of _CrtDbgReport:
+ // http://msdn.microsoft.com/en-us/library/8hyw4sy7(v=vs.71).aspx
+ // This may also trigger just-in-time debugging via DebugBreak().
+ if (Return)
+ *Return = 1;
+ // Don't call _CrtDbgReport.
+ return TRUE;
+}
+
/// CRTReportHook - Function called on a CRT debugging event.
static int CRTReportHook(int ReportType, char *Message, int *Return) {
// Don't cause a DebugBreak() on return.
@@ -238,6 +251,15 @@ static void RegisterHandler() {
OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
+#ifdef _MSC_VER
+ const char *EnableMsgbox = getenv("LLVM_ENABLE_CRT_REPORT");
+ if (!EnableMsgbox || strcmp("0", EnableMsgbox) == 0) {
+ // Setting a report hook overrides the default behavior of popping an "abort,
+ // retry, or ignore" dialog.
+ _CrtSetReportHook(AvoidMessageBoxHook);
+ }
+#endif
+
// Environment variable to disable any kind of crash dialog.
if (getenv("LLVM_DISABLE_CRASH_REPORT")) {
#ifdef _MSC_VER
diff --git a/contrib/llvm/lib/Support/YAMLParser.cpp b/contrib/llvm/lib/Support/YAMLParser.cpp
index 2cead20..213f5e1 100644
--- a/contrib/llvm/lib/Support/YAMLParser.cpp
+++ b/contrib/llvm/lib/Support/YAMLParser.cpp
@@ -260,7 +260,7 @@ public:
Token getNext();
void printError(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Message,
- ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) {
+ ArrayRef<SMRange> Ranges = None) {
SM.PrintMessage(Loc, Kind, Message, Ranges);
}
OpenPOWER on IntegriCloud